From 32ee0232f0d3c2683956fd700faf344a365a76d8 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Wed, 20 Nov 2019 02:46:33 -0500 Subject: [PATCH 01/62] Hexagon architecture An example of Hexagon architecture in java. --- .../design-patterns-architectural/README.md | 1 + .../baeldung/hexagonal/ChatApplication.java | 45 +++++++++++++++++++ .../adapters/DisplayInConsoleAdapter.java | 36 +++++++++++++++ .../adapters/InMemoryMessageStore.java | 37 +++++++++++++++ .../hexagonal/application/ChatManager.java | 27 +++++++++++ .../hexagonal/domain/ChatMessage.java | 34 ++++++++++++++ .../baeldung/hexagonal/domain/ChatUser.java | 14 ++++++ .../hexagonal/domain/IDisplayMessages.java | 8 ++++ .../hexagonal/domain/ISendMessage.java | 8 ++++ .../hexagonal/domain/IStoreMessages.java | 14 ++++++ 10 files changed, 224 insertions(+) create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java create mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java diff --git a/patterns/design-patterns-architectural/README.md b/patterns/design-patterns-architectural/README.md index fbe4221752..7f3eea27af 100644 --- a/patterns/design-patterns-architectural/README.md +++ b/patterns/design-patterns-architectural/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Service Locator Pattern](https://www.baeldung.com/java-service-locator-pattern) - [The DAO Pattern in Java](https://www.baeldung.com/java-dao-pattern) +- [A Practical Example of Hexagonal Architecture in Java](https://www.baeldung.com/java-hexagonal-pattern) diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java new file mode 100644 index 0000000000..4e8cc457f7 --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java @@ -0,0 +1,45 @@ +package com.baeldung.hexagonal; + +import com.baeldung.hexagonal.adapters.DisplayInConsoleAdapter; +import com.baeldung.hexagonal.adapters.InMemoryMessageStore; +import com.baeldung.hexagonal.application.ChatManager; +import com.baeldung.hexagonal.domain.ChatUser; +import com.baeldung.hexagonal.domain.IDisplayMessages; + +import java.util.ArrayDeque; +import java.util.Scanner; + +public class ChatApplication { + + public static void main(String[] args) { + Scanner console = new Scanner(System.in); + + System.out.print("Enter username of user 1: "); + ChatUser user1 = new ChatUser(console.nextLine()); + + System.out.printf("Enter username of user 2: "); + ChatUser user2 = new ChatUser(console.nextLine()); + + System.out.println("Chat will end when any user uses the word bye in a message."); + + InMemoryMessageStore messageStore = new InMemoryMessageStore(new ArrayDeque<>(10)); + IDisplayMessages messageDisplayer = new DisplayInConsoleAdapter(messageStore); + ChatManager chatManager = new ChatManager(messageStore, messageDisplayer); + + + while (true) { + System.out.printf("From %s to %s : ", user1, user2); + String message = console.nextLine(); + if (message.toLowerCase().contains("bye")) { + chatManager.sendMessage(user1, user2, message); + System.out.println("Chat recap:"); + messageDisplayer.displayMessages(); + System.exit(0); + } + chatManager.sendMessage(user1, user2, message); + ChatUser temp = user1; + user1 = user2; + user2 = temp; + } + } +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java new file mode 100644 index 0000000000..ea4982182b --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java @@ -0,0 +1,36 @@ +package com.baeldung.hexagonal.adapters; + +import com.baeldung.hexagonal.domain.ChatMessage; +import com.baeldung.hexagonal.domain.IDisplayMessages; +import com.baeldung.hexagonal.domain.IStoreMessages; + +/** + * A Utility adapter to display the chat messages in the console + */ +public class DisplayInConsoleAdapter implements IDisplayMessages { + + IStoreMessages messageStore; + + public DisplayInConsoleAdapter(IStoreMessages messageStore) { + this.messageStore = messageStore; + } + + public static void clearScreen() { + System.out.print("\033[H\033[2J"); + System.out.flush(); + } + + @Override + public void displayMessages() { + clearScreen(); + for (ChatMessage message: messageStore.getMessages(10)) { + System.out.printf( + "%tF %tT [%s to %s]: %s %n", + message.getTimeSent(), + message.getTimeSent(), + message.getFrom(), + message.getTo(), + message.getContents()); + } + } +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java new file mode 100644 index 0000000000..6c4c12eb6f --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java @@ -0,0 +1,37 @@ +package com.baeldung.hexagonal.adapters; + +import com.baeldung.hexagonal.domain.ChatMessage; +import com.baeldung.hexagonal.domain.IStoreMessages; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Queue; +import java.util.stream.Collectors; + +/** + * We're storing the messages in memory. We could later opt to switch to an implementation that stores messages in a + * database. + */ +public class InMemoryMessageStore implements IStoreMessages { + + private Queue messages; + + public InMemoryMessageStore(Queue messages) { + this.messages = messages; + } + + @Override + public void storeMessage(ChatMessage message) { + this.messages.add(message); + } + + @Override + public Collection getMessages(long maxNbMessages) {// @formatter:off + return messages.stream() + .sorted((m1, m2) -> m2.getTimeSent().compareTo(m1.getTimeSent())) + .limit(maxNbMessages) + .sorted(Comparator.comparing(ChatMessage::getTimeSent)) + .collect(Collectors.toList()); + // @formatter:on + } +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java new file mode 100644 index 0000000000..3ec54f1354 --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java @@ -0,0 +1,27 @@ +package com.baeldung.hexagonal.application; + +import com.baeldung.hexagonal.domain.*; + +import java.time.LocalDateTime; + +public class ChatManager implements ISendMessage { + + // The domain doesn't need to know where messages will be stored + private IStoreMessages messageStore; + + // The domain doesn't need to know how messages will be displayed + private IDisplayMessages messageDisplayer; + + public ChatManager(IStoreMessages messageStore, IDisplayMessages displayMessages) { + this.messageStore = messageStore; + this.messageDisplayer = displayMessages; + } + + @Override + public void sendMessage(ChatUser from, ChatUser to, String message) { + ChatMessage chatMessage = new ChatMessage(LocalDateTime.now(), from, to, message); + this.messageStore.storeMessage(chatMessage); + this.messageDisplayer.displayMessages(); + } + +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java new file mode 100644 index 0000000000..27db77a887 --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java @@ -0,0 +1,34 @@ +package com.baeldung.hexagonal.domain; + +import java.time.LocalDateTime; + +public class ChatMessage { + private LocalDateTime timeSent; + private ChatUser from; + private ChatUser to; + private String contents; + + public LocalDateTime getTimeSent() { + return timeSent; + } + + public ChatUser getFrom() { + return from; + } + + public ChatUser getTo() { + return to; + } + + public String getContents() { + return contents; + } + + public ChatMessage(LocalDateTime timeSent, ChatUser from, ChatUser to, String contents) { + this.timeSent = timeSent; + this.from = from; + this.to = to; + this.contents = contents; + } + +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java new file mode 100644 index 0000000000..e66e0c79e3 --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java @@ -0,0 +1,14 @@ +package com.baeldung.hexagonal.domain; + +public class ChatUser { + private String name; + + public ChatUser(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java new file mode 100644 index 0000000000..beb7e71cff --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.domain; + +/** + * An external system displays the messages sent by users. + */ +public interface IDisplayMessages { + void displayMessages(); +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java new file mode 100644 index 0000000000..dcec7e033a --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java @@ -0,0 +1,8 @@ +package com.baeldung.hexagonal.domain; + +/** + * A user sends a message (application's use case) + */ +public interface ISendMessage { + void sendMessage(ChatUser from, ChatUser to, String message); +} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java new file mode 100644 index 0000000000..fe6195bb67 --- /dev/null +++ b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java @@ -0,0 +1,14 @@ +package com.baeldung.hexagonal.domain; + +import java.util.Collection; + +/** + * An external system (infrastructure) stores a message + */ +public interface IStoreMessages { + + void storeMessage(ChatMessage message); + + Collection getMessages(long maxNbMessages); + +} From 7434ce777532d074cd3cdba7123b244a1a296bbb Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Wed, 18 Dec 2019 22:11:41 +0100 Subject: [PATCH 02/62] BAEL-19928: Refactor spring-reactor module --- ...tion.java => NotificationApplication.java} | 18 ++++---------- .../consumer/NotificationConsumer.java | 2 +- .../controller/NotificationController.java | 2 +- .../{doman => domain}/NotificationData.java | 2 +- .../baeldung/service/NotificationService.java | 2 +- .../service/impl/NotificationServiceimpl.java | 2 +- .../java/com/baeldung/DataLoaderLiveTest.java | 14 ----------- ...otificationApplicationIntegrationTest.java | 24 +++++++++++++++++++ .../java/org/baeldung/SpringContextTest.java | 4 ++-- 9 files changed, 36 insertions(+), 34 deletions(-) rename spring-reactor/src/main/java/com/baeldung/{Application.java => NotificationApplication.java} (59%) rename spring-reactor/src/main/java/com/baeldung/{doman => domain}/NotificationData.java (95%) delete mode 100644 spring-reactor/src/test/java/com/baeldung/DataLoaderLiveTest.java create mode 100644 spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java diff --git a/spring-reactor/src/main/java/com/baeldung/Application.java b/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java similarity index 59% rename from spring-reactor/src/main/java/com/baeldung/Application.java rename to spring-reactor/src/main/java/com/baeldung/NotificationApplication.java index 9030d41d26..a15b2e1818 100644 --- a/spring-reactor/src/main/java/com/baeldung/Application.java +++ b/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java @@ -1,24 +1,16 @@ package com.baeldung; +import com.baeldung.consumer.NotificationConsumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import com.baeldung.consumer.NotificationConsumer; - +import org.springframework.boot.autoconfigure.SpringBootApplication; import reactor.bus.EventBus; import static reactor.bus.selector.Selectors.$; -@Configuration -@EnableAutoConfiguration -@ComponentScan -@Import(Config.class) -public class Application implements CommandLineRunner { +@SpringBootApplication +public class NotificationApplication implements CommandLineRunner { @Autowired private EventBus eventBus; @@ -32,7 +24,7 @@ public class Application implements CommandLineRunner { } public static void main(String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run(NotificationApplication.class, args); } } diff --git a/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java b/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java index ca6a5b4303..56d038384a 100644 --- a/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java +++ b/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java @@ -3,7 +3,7 @@ package com.baeldung.consumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.doman.NotificationData; +import com.baeldung.domain.NotificationData; import com.baeldung.service.NotificationService; import reactor.bus.Event; diff --git a/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java b/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java index 8665f247b0..9d24b560cd 100644 --- a/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java +++ b/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.doman.NotificationData; +import com.baeldung.domain.NotificationData; import reactor.bus.Event; import reactor.bus.EventBus; diff --git a/spring-reactor/src/main/java/com/baeldung/doman/NotificationData.java b/spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java similarity index 95% rename from spring-reactor/src/main/java/com/baeldung/doman/NotificationData.java rename to spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java index d6d7b02949..2fdb4299a4 100644 --- a/spring-reactor/src/main/java/com/baeldung/doman/NotificationData.java +++ b/spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java @@ -1,4 +1,4 @@ -package com.baeldung.doman; +package com.baeldung.domain; public class NotificationData { diff --git a/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java b/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java index f653b2162f..bb0e15b7eb 100644 --- a/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java +++ b/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java @@ -1,6 +1,6 @@ package com.baeldung.service; -import com.baeldung.doman.NotificationData; +import com.baeldung.domain.NotificationData; public interface NotificationService { diff --git a/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java b/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java index bf37741f6a..20a24a68fd 100644 --- a/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java +++ b/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java @@ -2,7 +2,7 @@ package com.baeldung.service.impl; import org.springframework.stereotype.Service; -import com.baeldung.doman.NotificationData; +import com.baeldung.domain.NotificationData; import com.baeldung.service.NotificationService; @Service diff --git a/spring-reactor/src/test/java/com/baeldung/DataLoaderLiveTest.java b/spring-reactor/src/test/java/com/baeldung/DataLoaderLiveTest.java deleted file mode 100644 index 5833bc277c..0000000000 --- a/spring-reactor/src/test/java/com/baeldung/DataLoaderLiveTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.springframework.web.client.RestTemplate; - -public class DataLoaderLiveTest { - - @Test - public void exampleTest() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.getForObject("http://localhost:8080/startNotification/10", String.class); - } - -} diff --git a/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java b/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java new file mode 100644 index 0000000000..5ad9427397 --- /dev/null +++ b/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java @@ -0,0 +1,24 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class NotificationApplicationIntegrationTest { + + @LocalServerPort + private int port; + + @Test + public void givenAppStarted_whenNotificationTasksSubmitted_thenProcessed() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getForObject("http://localhost:" + port + "/startNotification/10", String.class); + } + + +} diff --git a/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java b/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java index 5e68a8e64f..bc8542c5ac 100644 --- a/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java @@ -5,10 +5,10 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.Application; +import com.baeldung.NotificationApplication; @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest(classes = NotificationApplication.class) public class SpringContextTest { @Test From dee493a6ebbc178e93d7ded7c6e6379f8f37c62e Mon Sep 17 00:00:00 2001 From: Krzysztof Woyke Date: Thu, 19 Dec 2019 08:28:26 +0100 Subject: [PATCH 03/62] BAEL-19928: Further minor improvements --- spring-reactor/src/main/java/com/baeldung/Config.java | 6 ++---- .../src/main/java/com/baeldung/NotificationApplication.java | 1 - .../baeldung/NotificationApplicationIntegrationTest.java | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/spring-reactor/src/main/java/com/baeldung/Config.java b/spring-reactor/src/main/java/com/baeldung/Config.java index 28f40dda02..ac1bfb3945 100644 --- a/spring-reactor/src/main/java/com/baeldung/Config.java +++ b/spring-reactor/src/main/java/com/baeldung/Config.java @@ -2,7 +2,6 @@ package com.baeldung; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; - import reactor.Environment; import reactor.bus.EventBus; @@ -10,13 +9,12 @@ import reactor.bus.EventBus; public class Config { @Bean - Environment env() { + public Environment env() { return Environment.initializeIfEmpty().assignErrorJournal(); } @Bean - EventBus createEventBus(Environment env) { + public EventBus createEventBus(Environment env) { return EventBus.create(env, Environment.THREAD_POOL); } - } diff --git a/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java b/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java index a15b2e1818..6f0c8cdf96 100644 --- a/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java +++ b/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java @@ -26,5 +26,4 @@ public class NotificationApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(NotificationApplication.class, args); } - } diff --git a/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java b/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java index 5ad9427397..6f6b39b2d5 100644 --- a/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java +++ b/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java @@ -19,6 +19,4 @@ public class NotificationApplicationIntegrationTest { RestTemplate restTemplate = new RestTemplate(); restTemplate.getForObject("http://localhost:" + port + "/startNotification/10", String.class); } - - } From af27178965c50f7a3cb8c4443b98b7fb61e58a87 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Fri, 3 Jan 2020 00:43:57 -0500 Subject: [PATCH 04/62] File locking example --- core-java-modules/core-java-io-2/README.md | 2 +- core-java-modules/core-java-nio-2/pom.xml | 17 +++ .../java/com/baeldung/lock/FileLocks.java | 105 ++++++++++++++++++ .../lock/com_baeldung_lock_FileLocks.h | 21 ++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java create mode 100644 core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h diff --git a/core-java-modules/core-java-io-2/README.md b/core-java-modules/core-java-io-2/README.md index 3251d2153e..62461be0ff 100644 --- a/core-java-modules/core-java-io-2/README.md +++ b/core-java-modules/core-java-io-2/README.md @@ -11,5 +11,5 @@ This module contains articles about core Java input and output (IO) - [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files) - [Java – Append Data to a File](https://www.baeldung.com/java-append-to-file) - [How to Copy a File with Java](https://www.baeldung.com/java-copy-file) -- [Create a Directory in Java](https://www.baeldung.com/java-create-directory) +- [Create a Directory in Java](https://www.baeldung.com/java-create-directory) - [[<-- Prev]](/core-java-modules/core-java-io) diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml index cd5c87d44e..ba50391048 100644 --- a/core-java-modules/core-java-nio-2/pom.xml +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -14,5 +14,22 @@ 0.0.1-SNAPSHOT ../../parent-java + + + + + com.github.jnr + jnr-ffi + 2.1.11 + + + + + com.github.jnr + jnr-constants + 0.9.14 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java new file mode 100644 index 0000000000..5363ba56e1 --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java @@ -0,0 +1,105 @@ +package com.baeldung.lock; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import jnr.ffi.LibraryLoader; +import jnr.ffi.Memory; +import jnr.ffi.Pointer; +import jnr.ffi.types.pid_t; + +public class FileLocks { + + public static interface LibC { + + public static final int O_NONBLOCK = jnr.constants.platform.OpenFlags.O_NONBLOCK.intValue(); + public static final int O_RDWR = jnr.constants.platform.OpenFlags.O_RDWR.intValue(); + public static final int O_EXLOCK = jnr.constants.platform.OpenFlags.O_EXLOCK.intValue(); + + public long write(int fd, Pointer data, long len); + + @pid_t + long getpid(); + + int open(String filename, int flags); + + int close(int fd); + } + + public static void main(String[] args) throws IOException, InterruptedException { + + Path path = Paths.get("/tmp/foo"); + + // Delete the file if it exists + Files.deleteIfExists(path); + + // Start with a fresh empty file + Files.createFile(path); + + // Prepare some external libc calls. Will only work on systems that have libc. + LibC libc = LibraryLoader.create(LibC.class).load("c"); + byte[] bytes = "Hello from C\n".getBytes("UTF-8"); + jnr.ffi.Runtime runtime = jnr.ffi.Runtime.getRuntime(libc); + Pointer buffer = Memory.allocateDirect(runtime, bytes.length); + buffer.put(0, bytes, 0, bytes.length); + + // Open the file through a libc call. This returns a file descriptor. + int fd = libc.open(path.toString(), libc.O_RDWR + libc.O_EXLOCK + libc.O_NONBLOCK); + System.out.println("Opened the file through a libc call that locks it."); + + // Our java method will see the lock. Itd will be well behaved and won't write to the file. + // Note that external processes on POSIX systems would still be able to write to this file ignoring any locks. + writeToRandomAccessFile(path, "I won't write this", 0L); + + // Libc opened the file, it can write to its corresponding file handle. + libc.write(fd, buffer, bytes.length); + + // Now let's close the file through a libc call, to release its lock. + libc.close(fd); + System.out.println("Invoked libc's close() method"); + + // This time our method won't see the lock and will write to the file. + writeToRandomAccessFile(path, "Hello from java", bytes.length); + + System.out.println("Now that all the locks are gone, here are the file contents:"); + System.out.println("------------------------------------------------------------"); + Files.lines(path).forEach(System.out::println); + + } + + public static RandomAccessFile writeToRandomAccessFile(Path path, String data, long position) { + RandomAccessFile file = null; + try { + file = new RandomAccessFile(path.toFile(), "rws"); + FileChannel channel = file.getChannel(); + // Try to acquire a lock + try (FileLock lock = channel.tryLock()) { + if (lock == null) { + System.out.println("Tried to lock through the FileChannel's lock() method. This file is already locked! It's my responsibility to not write to it, even if the OS would let me!"); + } else { + System.out.println("I don't see a lock on this file anymore. Now I can write to it."); + int i = 0; + channel.write( + ByteBuffer.wrap((data).getBytes(StandardCharsets.UTF_8)), position); + } + } catch (Exception e) { + System.out.println("Error while locking"); + e.printStackTrace(); + } + } catch (Exception e) { + System.out.println("Other Error."); + e.printStackTrace(); + } + return file; + } + + + +} diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h new file mode 100644 index 0000000000..b227cb0c79 --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_baeldung_lock_FileLocks */ + +#ifndef _Included_com_baeldung_lock_FileLocks +#define _Included_com_baeldung_lock_FileLocks +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_baeldung_lock_FileLocks + * Method: getpid + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_baeldung_lock_FileLocks_getpid + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif From 5ecd92fd83d4e5afa7d7336c8baa5411ff3f8f7b Mon Sep 17 00:00:00 2001 From: Krzysiek Date: Wed, 8 Jan 2020 20:41:16 +0100 Subject: [PATCH 05/62] BAEL-19928: Move code to com.baeldung.reactorbus package --- .../src/main/java/com/baeldung/{ => reactorbus}/Config.java | 2 +- .../baeldung/{ => reactorbus}/NotificationApplication.java | 4 ++-- .../{ => reactorbus}/consumer/NotificationConsumer.java | 6 +++--- .../{ => reactorbus}/controller/NotificationController.java | 4 ++-- .../baeldung/{ => reactorbus}/domain/NotificationData.java | 2 +- .../{ => reactorbus}/service/NotificationService.java | 4 ++-- .../service/impl/NotificationServiceimpl.java | 6 +++--- .../test/java/{org => com}/baeldung/SpringContextTest.java | 4 ++-- .../NotificationApplicationIntegrationTest.java | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/Config.java (93%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/NotificationApplication.java (89%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/consumer/NotificationConsumer.java (80%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/controller/NotificationController.java (89%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/domain/NotificationData.java (94%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/service/NotificationService.java (58%) rename spring-reactor/src/main/java/com/baeldung/{ => reactorbus}/service/impl/NotificationServiceimpl.java (75%) rename spring-reactor/src/test/java/{org => com}/baeldung/SpringContextTest.java (83%) rename spring-reactor/src/test/java/com/baeldung/{ => reactorbus}/NotificationApplicationIntegrationTest.java (95%) diff --git a/spring-reactor/src/main/java/com/baeldung/Config.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/Config.java similarity index 93% rename from spring-reactor/src/main/java/com/baeldung/Config.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/Config.java index ac1bfb3945..f849215dc4 100644 --- a/spring-reactor/src/main/java/com/baeldung/Config.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/Config.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.reactorbus; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/NotificationApplication.java similarity index 89% rename from spring-reactor/src/main/java/com/baeldung/NotificationApplication.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/NotificationApplication.java index 6f0c8cdf96..b315e6ce25 100644 --- a/spring-reactor/src/main/java/com/baeldung/NotificationApplication.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/NotificationApplication.java @@ -1,6 +1,6 @@ -package com.baeldung; +package com.baeldung.reactorbus; -import com.baeldung.consumer.NotificationConsumer; +import com.baeldung.reactorbus.consumer.NotificationConsumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; diff --git a/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/consumer/NotificationConsumer.java similarity index 80% rename from spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/consumer/NotificationConsumer.java index 56d038384a..d9d2586187 100644 --- a/spring-reactor/src/main/java/com/baeldung/consumer/NotificationConsumer.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/consumer/NotificationConsumer.java @@ -1,10 +1,10 @@ -package com.baeldung.consumer; +package com.baeldung.reactorbus.consumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.domain.NotificationData; -import com.baeldung.service.NotificationService; +import com.baeldung.reactorbus.domain.NotificationData; +import com.baeldung.reactorbus.service.NotificationService; import reactor.bus.Event; import reactor.fn.Consumer; diff --git a/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/controller/NotificationController.java similarity index 89% rename from spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/controller/NotificationController.java index 9d24b560cd..62a7b38662 100644 --- a/spring-reactor/src/main/java/com/baeldung/controller/NotificationController.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/controller/NotificationController.java @@ -1,11 +1,11 @@ -package com.baeldung.controller; +package com.baeldung.reactorbus.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.domain.NotificationData; +import com.baeldung.reactorbus.domain.NotificationData; import reactor.bus.Event; import reactor.bus.EventBus; diff --git a/spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/domain/NotificationData.java similarity index 94% rename from spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/domain/NotificationData.java index 2fdb4299a4..65d3559541 100644 --- a/spring-reactor/src/main/java/com/baeldung/domain/NotificationData.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/domain/NotificationData.java @@ -1,4 +1,4 @@ -package com.baeldung.domain; +package com.baeldung.reactorbus.domain; public class NotificationData { diff --git a/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/service/NotificationService.java similarity index 58% rename from spring-reactor/src/main/java/com/baeldung/service/NotificationService.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/service/NotificationService.java index bb0e15b7eb..dfcd03ed68 100644 --- a/spring-reactor/src/main/java/com/baeldung/service/NotificationService.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/service/NotificationService.java @@ -1,6 +1,6 @@ -package com.baeldung.service; +package com.baeldung.reactorbus.service; -import com.baeldung.domain.NotificationData; +import com.baeldung.reactorbus.domain.NotificationData; public interface NotificationService { diff --git a/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java b/spring-reactor/src/main/java/com/baeldung/reactorbus/service/impl/NotificationServiceimpl.java similarity index 75% rename from spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java rename to spring-reactor/src/main/java/com/baeldung/reactorbus/service/impl/NotificationServiceimpl.java index 20a24a68fd..aa305caaad 100644 --- a/spring-reactor/src/main/java/com/baeldung/service/impl/NotificationServiceimpl.java +++ b/spring-reactor/src/main/java/com/baeldung/reactorbus/service/impl/NotificationServiceimpl.java @@ -1,9 +1,9 @@ -package com.baeldung.service.impl; +package com.baeldung.reactorbus.service.impl; import org.springframework.stereotype.Service; -import com.baeldung.domain.NotificationData; -import com.baeldung.service.NotificationService; +import com.baeldung.reactorbus.domain.NotificationData; +import com.baeldung.reactorbus.service.NotificationService; @Service public class NotificationServiceimpl implements NotificationService { diff --git a/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java b/spring-reactor/src/test/java/com/baeldung/SpringContextTest.java similarity index 83% rename from spring-reactor/src/test/java/org/baeldung/SpringContextTest.java rename to spring-reactor/src/test/java/com/baeldung/SpringContextTest.java index bc8542c5ac..68b6018433 100644 --- a/spring-reactor/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-reactor/src/test/java/com/baeldung/SpringContextTest.java @@ -1,11 +1,11 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.NotificationApplication; +import com.baeldung.reactorbus.NotificationApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = NotificationApplication.class) diff --git a/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java b/spring-reactor/src/test/java/com/baeldung/reactorbus/NotificationApplicationIntegrationTest.java similarity index 95% rename from spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java rename to spring-reactor/src/test/java/com/baeldung/reactorbus/NotificationApplicationIntegrationTest.java index 6f6b39b2d5..0adea21fd4 100644 --- a/spring-reactor/src/test/java/com/baeldung/NotificationApplicationIntegrationTest.java +++ b/spring-reactor/src/test/java/com/baeldung/reactorbus/NotificationApplicationIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.reactorbus; import org.junit.Test; import org.junit.runner.RunWith; From 9e93614755898e7b9e5e1dee105273d2086f21d1 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Sun, 12 Jan 2020 17:26:59 -0500 Subject: [PATCH 06/62] New version of the article --- core-java-modules/core-java-nio-2/README.md | 1 + .../core-java-nio-2/hard_link.txt | 10000 ---------------- core-java-modules/core-java-nio-2/pom.xml | 17 - .../java/com/baeldung/lock/FileLocks.java | 292 +- .../lock/com_baeldung_lock_FileLocks.h | 21 - .../java/com/baeldung/lock/FileLocksTest.java | 78 + 6 files changed, 289 insertions(+), 10120 deletions(-) delete mode 100644 core-java-modules/core-java-nio-2/hard_link.txt delete mode 100644 core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h create mode 100644 core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index 8b29c97385..1d879b3c5b 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -8,4 +8,5 @@ This module contains articles about core Java non-blocking input and output (IO) - [Create a Symbolic Link with Java](https://www.baeldung.com/java-symlink) - [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector) - [Using Java MappedByteBuffer](https://www.baeldung.com/java-mapped-byte-buffer) +- [How to Lock a File in Java](https://www.baeldung.com/how-to-lock-a-file-in-java) - [[<-- Prev]](/core-java-modules/core-java-nio) \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/hard_link.txt b/core-java-modules/core-java-nio-2/hard_link.txt deleted file mode 100644 index 931a810b8d..0000000000 --- a/core-java-modules/core-java-nio-2/hard_link.txt +++ /dev/null @@ -1,10000 +0,0 @@ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -1258 -1259 -1260 -1261 -1262 -1263 -1264 -1265 -1266 -1267 -1268 -1269 -1270 -1271 -1272 -1273 -1274 -1275 -1276 -1277 -1278 -1279 -1280 -1281 -1282 -1283 -1284 -1285 -1286 -1287 -1288 -1289 -1290 -1291 -1292 -1293 -1294 -1295 -1296 -1297 -1298 -1299 -1300 -1301 -1302 -1303 -1304 -1305 -1306 -1307 -1308 -1309 -1310 -1311 -1312 -1313 -1314 -1315 -1316 -1317 -1318 -1319 -1320 -1321 -1322 -1323 -1324 -1325 -1326 -1327 -1328 -1329 -1330 -1331 -1332 -1333 -1334 -1335 -1336 -1337 -1338 -1339 -1340 -1341 -1342 -1343 -1344 -1345 -1346 -1347 -1348 -1349 -1350 -1351 -1352 -1353 -1354 -1355 -1356 -1357 -1358 -1359 -1360 -1361 -1362 -1363 -1364 -1365 -1366 -1367 -1368 -1369 -1370 -1371 -1372 -1373 -1374 -1375 -1376 -1377 -1378 -1379 -1380 -1381 -1382 -1383 -1384 -1385 -1386 -1387 -1388 -1389 -1390 -1391 -1392 -1393 -1394 -1395 -1396 -1397 -1398 -1399 -1400 -1401 -1402 -1403 -1404 -1405 -1406 -1407 -1408 -1409 -1410 -1411 -1412 -1413 -1414 -1415 -1416 -1417 -1418 -1419 -1420 -1421 -1422 -1423 -1424 -1425 -1426 -1427 -1428 -1429 -1430 -1431 -1432 -1433 -1434 -1435 -1436 -1437 -1438 -1439 -1440 -1441 -1442 -1443 -1444 -1445 -1446 -1447 -1448 -1449 -1450 -1451 -1452 -1453 -1454 -1455 -1456 -1457 -1458 -1459 -1460 -1461 -1462 -1463 -1464 -1465 -1466 -1467 -1468 -1469 -1470 -1471 -1472 -1473 -1474 -1475 -1476 -1477 -1478 -1479 -1480 -1481 -1482 -1483 -1484 -1485 -1486 -1487 -1488 -1489 -1490 -1491 -1492 -1493 -1494 -1495 -1496 -1497 -1498 -1499 -1500 -1501 -1502 -1503 -1504 -1505 -1506 -1507 -1508 -1509 -1510 -1511 -1512 -1513 -1514 -1515 -1516 -1517 -1518 -1519 -1520 -1521 -1522 -1523 -1524 -1525 -1526 -1527 -1528 -1529 -1530 -1531 -1532 -1533 -1534 -1535 -1536 -1537 -1538 -1539 -1540 -1541 -1542 -1543 -1544 -1545 -1546 -1547 -1548 -1549 -1550 -1551 -1552 -1553 -1554 -1555 -1556 -1557 -1558 -1559 -1560 -1561 -1562 -1563 -1564 -1565 -1566 -1567 -1568 -1569 -1570 -1571 -1572 -1573 -1574 -1575 -1576 -1577 -1578 -1579 -1580 -1581 -1582 -1583 -1584 -1585 -1586 -1587 -1588 -1589 -1590 -1591 -1592 -1593 -1594 -1595 -1596 -1597 -1598 -1599 -1600 -1601 -1602 -1603 -1604 -1605 -1606 -1607 -1608 -1609 -1610 -1611 -1612 -1613 -1614 -1615 -1616 -1617 -1618 -1619 -1620 -1621 -1622 -1623 -1624 -1625 -1626 -1627 -1628 -1629 -1630 -1631 -1632 -1633 -1634 -1635 -1636 -1637 -1638 -1639 -1640 -1641 -1642 -1643 -1644 -1645 -1646 -1647 -1648 -1649 -1650 -1651 -1652 -1653 -1654 -1655 -1656 -1657 -1658 -1659 -1660 -1661 -1662 -1663 -1664 -1665 -1666 -1667 -1668 -1669 -1670 -1671 -1672 -1673 -1674 -1675 -1676 -1677 -1678 -1679 -1680 -1681 -1682 -1683 -1684 -1685 -1686 -1687 -1688 -1689 -1690 -1691 -1692 -1693 -1694 -1695 -1696 -1697 -1698 -1699 -1700 -1701 -1702 -1703 -1704 -1705 -1706 -1707 -1708 -1709 -1710 -1711 -1712 -1713 -1714 -1715 -1716 -1717 -1718 -1719 -1720 -1721 -1722 -1723 -1724 -1725 -1726 -1727 -1728 -1729 -1730 -1731 -1732 -1733 -1734 -1735 -1736 -1737 -1738 -1739 -1740 -1741 -1742 -1743 -1744 -1745 -1746 -1747 -1748 -1749 -1750 -1751 -1752 -1753 -1754 -1755 -1756 -1757 -1758 -1759 -1760 -1761 -1762 -1763 -1764 -1765 -1766 -1767 -1768 -1769 -1770 -1771 -1772 -1773 -1774 -1775 -1776 -1777 -1778 -1779 -1780 -1781 -1782 -1783 -1784 -1785 -1786 -1787 -1788 -1789 -1790 -1791 -1792 -1793 -1794 -1795 -1796 -1797 -1798 -1799 -1800 -1801 -1802 -1803 -1804 -1805 -1806 -1807 -1808 -1809 -1810 -1811 -1812 -1813 -1814 -1815 -1816 -1817 -1818 -1819 -1820 -1821 -1822 -1823 -1824 -1825 -1826 -1827 -1828 -1829 -1830 -1831 -1832 -1833 -1834 -1835 -1836 -1837 -1838 -1839 -1840 -1841 -1842 -1843 -1844 -1845 -1846 -1847 -1848 -1849 -1850 -1851 -1852 -1853 -1854 -1855 -1856 -1857 -1858 -1859 -1860 -1861 -1862 -1863 -1864 -1865 -1866 -1867 -1868 -1869 -1870 -1871 -1872 -1873 -1874 -1875 -1876 -1877 -1878 -1879 -1880 -1881 -1882 -1883 -1884 -1885 -1886 -1887 -1888 -1889 -1890 -1891 -1892 -1893 -1894 -1895 -1896 -1897 -1898 -1899 -1900 -1901 -1902 -1903 -1904 -1905 -1906 -1907 -1908 -1909 -1910 -1911 -1912 -1913 -1914 -1915 -1916 -1917 -1918 -1919 -1920 -1921 -1922 -1923 -1924 -1925 -1926 -1927 -1928 -1929 -1930 -1931 -1932 -1933 -1934 -1935 -1936 -1937 -1938 -1939 -1940 -1941 -1942 -1943 -1944 -1945 -1946 -1947 -1948 -1949 -1950 -1951 -1952 -1953 -1954 -1955 -1956 -1957 -1958 -1959 -1960 -1961 -1962 -1963 -1964 -1965 -1966 -1967 -1968 -1969 -1970 -1971 -1972 -1973 -1974 -1975 -1976 -1977 -1978 -1979 -1980 -1981 -1982 -1983 -1984 -1985 -1986 -1987 -1988 -1989 -1990 -1991 -1992 -1993 -1994 -1995 -1996 -1997 -1998 -1999 -2000 -2001 -2002 -2003 -2004 -2005 -2006 -2007 -2008 -2009 -2010 -2011 -2012 -2013 -2014 -2015 -2016 -2017 -2018 -2019 -2020 -2021 -2022 -2023 -2024 -2025 -2026 -2027 -2028 -2029 -2030 -2031 -2032 -2033 -2034 -2035 -2036 -2037 -2038 -2039 -2040 -2041 -2042 -2043 -2044 -2045 -2046 -2047 -2048 -2049 -2050 -2051 -2052 -2053 -2054 -2055 -2056 -2057 -2058 -2059 -2060 -2061 -2062 -2063 -2064 -2065 -2066 -2067 -2068 -2069 -2070 -2071 -2072 -2073 -2074 -2075 -2076 -2077 -2078 -2079 -2080 -2081 -2082 -2083 -2084 -2085 -2086 -2087 -2088 -2089 -2090 -2091 -2092 -2093 -2094 -2095 -2096 -2097 -2098 -2099 -2100 -2101 -2102 -2103 -2104 -2105 -2106 -2107 -2108 -2109 -2110 -2111 -2112 -2113 -2114 -2115 -2116 -2117 -2118 -2119 -2120 -2121 -2122 -2123 -2124 -2125 -2126 -2127 -2128 -2129 -2130 -2131 -2132 -2133 -2134 -2135 -2136 -2137 -2138 -2139 -2140 -2141 -2142 -2143 -2144 -2145 -2146 -2147 -2148 -2149 -2150 -2151 -2152 -2153 -2154 -2155 -2156 -2157 -2158 -2159 -2160 -2161 -2162 -2163 -2164 -2165 -2166 -2167 -2168 -2169 -2170 -2171 -2172 -2173 -2174 -2175 -2176 -2177 -2178 -2179 -2180 -2181 -2182 -2183 -2184 -2185 -2186 -2187 -2188 -2189 -2190 -2191 -2192 -2193 -2194 -2195 -2196 -2197 -2198 -2199 -2200 -2201 -2202 -2203 -2204 -2205 -2206 -2207 -2208 -2209 -2210 -2211 -2212 -2213 -2214 -2215 -2216 -2217 -2218 -2219 -2220 -2221 -2222 -2223 -2224 -2225 -2226 -2227 -2228 -2229 -2230 -2231 -2232 -2233 -2234 -2235 -2236 -2237 -2238 -2239 -2240 -2241 -2242 -2243 -2244 -2245 -2246 -2247 -2248 -2249 -2250 -2251 -2252 -2253 -2254 -2255 -2256 -2257 -2258 -2259 -2260 -2261 -2262 -2263 -2264 -2265 -2266 -2267 -2268 -2269 -2270 -2271 -2272 -2273 -2274 -2275 -2276 -2277 -2278 -2279 -2280 -2281 -2282 -2283 -2284 -2285 -2286 -2287 -2288 -2289 -2290 -2291 -2292 -2293 -2294 -2295 -2296 -2297 -2298 -2299 -2300 -2301 -2302 -2303 -2304 -2305 -2306 -2307 -2308 -2309 -2310 -2311 -2312 -2313 -2314 -2315 -2316 -2317 -2318 -2319 -2320 -2321 -2322 -2323 -2324 -2325 -2326 -2327 -2328 -2329 -2330 -2331 -2332 -2333 -2334 -2335 -2336 -2337 -2338 -2339 -2340 -2341 -2342 -2343 -2344 -2345 -2346 -2347 -2348 -2349 -2350 -2351 -2352 -2353 -2354 -2355 -2356 -2357 -2358 -2359 -2360 -2361 -2362 -2363 -2364 -2365 -2366 -2367 -2368 -2369 -2370 -2371 -2372 -2373 -2374 -2375 -2376 -2377 -2378 -2379 -2380 -2381 -2382 -2383 -2384 -2385 -2386 -2387 -2388 -2389 -2390 -2391 -2392 -2393 -2394 -2395 -2396 -2397 -2398 -2399 -2400 -2401 -2402 -2403 -2404 -2405 -2406 -2407 -2408 -2409 -2410 -2411 -2412 -2413 -2414 -2415 -2416 -2417 -2418 -2419 -2420 -2421 -2422 -2423 -2424 -2425 -2426 -2427 -2428 -2429 -2430 -2431 -2432 -2433 -2434 -2435 -2436 -2437 -2438 -2439 -2440 -2441 -2442 -2443 -2444 -2445 -2446 -2447 -2448 -2449 -2450 -2451 -2452 -2453 -2454 -2455 -2456 -2457 -2458 -2459 -2460 -2461 -2462 -2463 -2464 -2465 -2466 -2467 -2468 -2469 -2470 -2471 -2472 -2473 -2474 -2475 -2476 -2477 -2478 -2479 -2480 -2481 -2482 -2483 -2484 -2485 -2486 -2487 -2488 -2489 -2490 -2491 -2492 -2493 -2494 -2495 -2496 -2497 -2498 -2499 -2500 -2501 -2502 -2503 -2504 -2505 -2506 -2507 -2508 -2509 -2510 -2511 -2512 -2513 -2514 -2515 -2516 -2517 -2518 -2519 -2520 -2521 -2522 -2523 -2524 -2525 -2526 -2527 -2528 -2529 -2530 -2531 -2532 -2533 -2534 -2535 -2536 -2537 -2538 -2539 -2540 -2541 -2542 -2543 -2544 -2545 -2546 -2547 -2548 -2549 -2550 -2551 -2552 -2553 -2554 -2555 -2556 -2557 -2558 -2559 -2560 -2561 -2562 -2563 -2564 -2565 -2566 -2567 -2568 -2569 -2570 -2571 -2572 -2573 -2574 -2575 -2576 -2577 -2578 -2579 -2580 -2581 -2582 -2583 -2584 -2585 -2586 -2587 -2588 -2589 -2590 -2591 -2592 -2593 -2594 -2595 -2596 -2597 -2598 -2599 -2600 -2601 -2602 -2603 -2604 -2605 -2606 -2607 -2608 -2609 -2610 -2611 -2612 -2613 -2614 -2615 -2616 -2617 -2618 -2619 -2620 -2621 -2622 -2623 -2624 -2625 -2626 -2627 -2628 -2629 -2630 -2631 -2632 -2633 -2634 -2635 -2636 -2637 -2638 -2639 -2640 -2641 -2642 -2643 -2644 -2645 -2646 -2647 -2648 -2649 -2650 -2651 -2652 -2653 -2654 -2655 -2656 -2657 -2658 -2659 -2660 -2661 -2662 -2663 -2664 -2665 -2666 -2667 -2668 -2669 -2670 -2671 -2672 -2673 -2674 -2675 -2676 -2677 -2678 -2679 -2680 -2681 -2682 -2683 -2684 -2685 -2686 -2687 -2688 -2689 -2690 -2691 -2692 -2693 -2694 -2695 -2696 -2697 -2698 -2699 -2700 -2701 -2702 -2703 -2704 -2705 -2706 -2707 -2708 -2709 -2710 -2711 -2712 -2713 -2714 -2715 -2716 -2717 -2718 -2719 -2720 -2721 -2722 -2723 -2724 -2725 -2726 -2727 -2728 -2729 -2730 -2731 -2732 -2733 -2734 -2735 -2736 -2737 -2738 -2739 -2740 -2741 -2742 -2743 -2744 -2745 -2746 -2747 -2748 -2749 -2750 -2751 -2752 -2753 -2754 -2755 -2756 -2757 -2758 -2759 -2760 -2761 -2762 -2763 -2764 -2765 -2766 -2767 -2768 -2769 -2770 -2771 -2772 -2773 -2774 -2775 -2776 -2777 -2778 -2779 -2780 -2781 -2782 -2783 -2784 -2785 -2786 -2787 -2788 -2789 -2790 -2791 -2792 -2793 -2794 -2795 -2796 -2797 -2798 -2799 -2800 -2801 -2802 -2803 -2804 -2805 -2806 -2807 -2808 -2809 -2810 -2811 -2812 -2813 -2814 -2815 -2816 -2817 -2818 -2819 -2820 -2821 -2822 -2823 -2824 -2825 -2826 -2827 -2828 -2829 -2830 -2831 -2832 -2833 -2834 -2835 -2836 -2837 -2838 -2839 -2840 -2841 -2842 -2843 -2844 -2845 -2846 -2847 -2848 -2849 -2850 -2851 -2852 -2853 -2854 -2855 -2856 -2857 -2858 -2859 -2860 -2861 -2862 -2863 -2864 -2865 -2866 -2867 -2868 -2869 -2870 -2871 -2872 -2873 -2874 -2875 -2876 -2877 -2878 -2879 -2880 -2881 -2882 -2883 -2884 -2885 -2886 -2887 -2888 -2889 -2890 -2891 -2892 -2893 -2894 -2895 -2896 -2897 -2898 -2899 -2900 -2901 -2902 -2903 -2904 -2905 -2906 -2907 -2908 -2909 -2910 -2911 -2912 -2913 -2914 -2915 -2916 -2917 -2918 -2919 -2920 -2921 -2922 -2923 -2924 -2925 -2926 -2927 -2928 -2929 -2930 -2931 -2932 -2933 -2934 -2935 -2936 -2937 -2938 -2939 -2940 -2941 -2942 -2943 -2944 -2945 -2946 -2947 -2948 -2949 -2950 -2951 -2952 -2953 -2954 -2955 -2956 -2957 -2958 -2959 -2960 -2961 -2962 -2963 -2964 -2965 -2966 -2967 -2968 -2969 -2970 -2971 -2972 -2973 -2974 -2975 -2976 -2977 -2978 -2979 -2980 -2981 -2982 -2983 -2984 -2985 -2986 -2987 -2988 -2989 -2990 -2991 -2992 -2993 -2994 -2995 -2996 -2997 -2998 -2999 -3000 -3001 -3002 -3003 -3004 -3005 -3006 -3007 -3008 -3009 -3010 -3011 -3012 -3013 -3014 -3015 -3016 -3017 -3018 -3019 -3020 -3021 -3022 -3023 -3024 -3025 -3026 -3027 -3028 -3029 -3030 -3031 -3032 -3033 -3034 -3035 -3036 -3037 -3038 -3039 -3040 -3041 -3042 -3043 -3044 -3045 -3046 -3047 -3048 -3049 -3050 -3051 -3052 -3053 -3054 -3055 -3056 -3057 -3058 -3059 -3060 -3061 -3062 -3063 -3064 -3065 -3066 -3067 -3068 -3069 -3070 -3071 -3072 -3073 -3074 -3075 -3076 -3077 -3078 -3079 -3080 -3081 -3082 -3083 -3084 -3085 -3086 -3087 -3088 -3089 -3090 -3091 -3092 -3093 -3094 -3095 -3096 -3097 -3098 -3099 -3100 -3101 -3102 -3103 -3104 -3105 -3106 -3107 -3108 -3109 -3110 -3111 -3112 -3113 -3114 -3115 -3116 -3117 -3118 -3119 -3120 -3121 -3122 -3123 -3124 -3125 -3126 -3127 -3128 -3129 -3130 -3131 -3132 -3133 -3134 -3135 -3136 -3137 -3138 -3139 -3140 -3141 -3142 -3143 -3144 -3145 -3146 -3147 -3148 -3149 -3150 -3151 -3152 -3153 -3154 -3155 -3156 -3157 -3158 -3159 -3160 -3161 -3162 -3163 -3164 -3165 -3166 -3167 -3168 -3169 -3170 -3171 -3172 -3173 -3174 -3175 -3176 -3177 -3178 -3179 -3180 -3181 -3182 -3183 -3184 -3185 -3186 -3187 -3188 -3189 -3190 -3191 -3192 -3193 -3194 -3195 -3196 -3197 -3198 -3199 -3200 -3201 -3202 -3203 -3204 -3205 -3206 -3207 -3208 -3209 -3210 -3211 -3212 -3213 -3214 -3215 -3216 -3217 -3218 -3219 -3220 -3221 -3222 -3223 -3224 -3225 -3226 -3227 -3228 -3229 -3230 -3231 -3232 -3233 -3234 -3235 -3236 -3237 -3238 -3239 -3240 -3241 -3242 -3243 -3244 -3245 -3246 -3247 -3248 -3249 -3250 -3251 -3252 -3253 -3254 -3255 -3256 -3257 -3258 -3259 -3260 -3261 -3262 -3263 -3264 -3265 -3266 -3267 -3268 -3269 -3270 -3271 -3272 -3273 -3274 -3275 -3276 -3277 -3278 -3279 -3280 -3281 -3282 -3283 -3284 -3285 -3286 -3287 -3288 -3289 -3290 -3291 -3292 -3293 -3294 -3295 -3296 -3297 -3298 -3299 -3300 -3301 -3302 -3303 -3304 -3305 -3306 -3307 -3308 -3309 -3310 -3311 -3312 -3313 -3314 -3315 -3316 -3317 -3318 -3319 -3320 -3321 -3322 -3323 -3324 -3325 -3326 -3327 -3328 -3329 -3330 -3331 -3332 -3333 -3334 -3335 -3336 -3337 -3338 -3339 -3340 -3341 -3342 -3343 -3344 -3345 -3346 -3347 -3348 -3349 -3350 -3351 -3352 -3353 -3354 -3355 -3356 -3357 -3358 -3359 -3360 -3361 -3362 -3363 -3364 -3365 -3366 -3367 -3368 -3369 -3370 -3371 -3372 -3373 -3374 -3375 -3376 -3377 -3378 -3379 -3380 -3381 -3382 -3383 -3384 -3385 -3386 -3387 -3388 -3389 -3390 -3391 -3392 -3393 -3394 -3395 -3396 -3397 -3398 -3399 -3400 -3401 -3402 -3403 -3404 -3405 -3406 -3407 -3408 -3409 -3410 -3411 -3412 -3413 -3414 -3415 -3416 -3417 -3418 -3419 -3420 -3421 -3422 -3423 -3424 -3425 -3426 -3427 -3428 -3429 -3430 -3431 -3432 -3433 -3434 -3435 -3436 -3437 -3438 -3439 -3440 -3441 -3442 -3443 -3444 -3445 -3446 -3447 -3448 -3449 -3450 -3451 -3452 -3453 -3454 -3455 -3456 -3457 -3458 -3459 -3460 -3461 -3462 -3463 -3464 -3465 -3466 -3467 -3468 -3469 -3470 -3471 -3472 -3473 -3474 -3475 -3476 -3477 -3478 -3479 -3480 -3481 -3482 -3483 -3484 -3485 -3486 -3487 -3488 -3489 -3490 -3491 -3492 -3493 -3494 -3495 -3496 -3497 -3498 -3499 -3500 -3501 -3502 -3503 -3504 -3505 -3506 -3507 -3508 -3509 -3510 -3511 -3512 -3513 -3514 -3515 -3516 -3517 -3518 -3519 -3520 -3521 -3522 -3523 -3524 -3525 -3526 -3527 -3528 -3529 -3530 -3531 -3532 -3533 -3534 -3535 -3536 -3537 -3538 -3539 -3540 -3541 -3542 -3543 -3544 -3545 -3546 -3547 -3548 -3549 -3550 -3551 -3552 -3553 -3554 -3555 -3556 -3557 -3558 -3559 -3560 -3561 -3562 -3563 -3564 -3565 -3566 -3567 -3568 -3569 -3570 -3571 -3572 -3573 -3574 -3575 -3576 -3577 -3578 -3579 -3580 -3581 -3582 -3583 -3584 -3585 -3586 -3587 -3588 -3589 -3590 -3591 -3592 -3593 -3594 -3595 -3596 -3597 -3598 -3599 -3600 -3601 -3602 -3603 -3604 -3605 -3606 -3607 -3608 -3609 -3610 -3611 -3612 -3613 -3614 -3615 -3616 -3617 -3618 -3619 -3620 -3621 -3622 -3623 -3624 -3625 -3626 -3627 -3628 -3629 -3630 -3631 -3632 -3633 -3634 -3635 -3636 -3637 -3638 -3639 -3640 -3641 -3642 -3643 -3644 -3645 -3646 -3647 -3648 -3649 -3650 -3651 -3652 -3653 -3654 -3655 -3656 -3657 -3658 -3659 -3660 -3661 -3662 -3663 -3664 -3665 -3666 -3667 -3668 -3669 -3670 -3671 -3672 -3673 -3674 -3675 -3676 -3677 -3678 -3679 -3680 -3681 -3682 -3683 -3684 -3685 -3686 -3687 -3688 -3689 -3690 -3691 -3692 -3693 -3694 -3695 -3696 -3697 -3698 -3699 -3700 -3701 -3702 -3703 -3704 -3705 -3706 -3707 -3708 -3709 -3710 -3711 -3712 -3713 -3714 -3715 -3716 -3717 -3718 -3719 -3720 -3721 -3722 -3723 -3724 -3725 -3726 -3727 -3728 -3729 -3730 -3731 -3732 -3733 -3734 -3735 -3736 -3737 -3738 -3739 -3740 -3741 -3742 -3743 -3744 -3745 -3746 -3747 -3748 -3749 -3750 -3751 -3752 -3753 -3754 -3755 -3756 -3757 -3758 -3759 -3760 -3761 -3762 -3763 -3764 -3765 -3766 -3767 -3768 -3769 -3770 -3771 -3772 -3773 -3774 -3775 -3776 -3777 -3778 -3779 -3780 -3781 -3782 -3783 -3784 -3785 -3786 -3787 -3788 -3789 -3790 -3791 -3792 -3793 -3794 -3795 -3796 -3797 -3798 -3799 -3800 -3801 -3802 -3803 -3804 -3805 -3806 -3807 -3808 -3809 -3810 -3811 -3812 -3813 -3814 -3815 -3816 -3817 -3818 -3819 -3820 -3821 -3822 -3823 -3824 -3825 -3826 -3827 -3828 -3829 -3830 -3831 -3832 -3833 -3834 -3835 -3836 -3837 -3838 -3839 -3840 -3841 -3842 -3843 -3844 -3845 -3846 -3847 -3848 -3849 -3850 -3851 -3852 -3853 -3854 -3855 -3856 -3857 -3858 -3859 -3860 -3861 -3862 -3863 -3864 -3865 -3866 -3867 -3868 -3869 -3870 -3871 -3872 -3873 -3874 -3875 -3876 -3877 -3878 -3879 -3880 -3881 -3882 -3883 -3884 -3885 -3886 -3887 -3888 -3889 -3890 -3891 -3892 -3893 -3894 -3895 -3896 -3897 -3898 -3899 -3900 -3901 -3902 -3903 -3904 -3905 -3906 -3907 -3908 -3909 -3910 -3911 -3912 -3913 -3914 -3915 -3916 -3917 -3918 -3919 -3920 -3921 -3922 -3923 -3924 -3925 -3926 -3927 -3928 -3929 -3930 -3931 -3932 -3933 -3934 -3935 -3936 -3937 -3938 -3939 -3940 -3941 -3942 -3943 -3944 -3945 -3946 -3947 -3948 -3949 -3950 -3951 -3952 -3953 -3954 -3955 -3956 -3957 -3958 -3959 -3960 -3961 -3962 -3963 -3964 -3965 -3966 -3967 -3968 -3969 -3970 -3971 -3972 -3973 -3974 -3975 -3976 -3977 -3978 -3979 -3980 -3981 -3982 -3983 -3984 -3985 -3986 -3987 -3988 -3989 -3990 -3991 -3992 -3993 -3994 -3995 -3996 -3997 -3998 -3999 -4000 -4001 -4002 -4003 -4004 -4005 -4006 -4007 -4008 -4009 -4010 -4011 -4012 -4013 -4014 -4015 -4016 -4017 -4018 -4019 -4020 -4021 -4022 -4023 -4024 -4025 -4026 -4027 -4028 -4029 -4030 -4031 -4032 -4033 -4034 -4035 -4036 -4037 -4038 -4039 -4040 -4041 -4042 -4043 -4044 -4045 -4046 -4047 -4048 -4049 -4050 -4051 -4052 -4053 -4054 -4055 -4056 -4057 -4058 -4059 -4060 -4061 -4062 -4063 -4064 -4065 -4066 -4067 -4068 -4069 -4070 -4071 -4072 -4073 -4074 -4075 -4076 -4077 -4078 -4079 -4080 -4081 -4082 -4083 -4084 -4085 -4086 -4087 -4088 -4089 -4090 -4091 -4092 -4093 -4094 -4095 -4096 -4097 -4098 -4099 -4100 -4101 -4102 -4103 -4104 -4105 -4106 -4107 -4108 -4109 -4110 -4111 -4112 -4113 -4114 -4115 -4116 -4117 -4118 -4119 -4120 -4121 -4122 -4123 -4124 -4125 -4126 -4127 -4128 -4129 -4130 -4131 -4132 -4133 -4134 -4135 -4136 -4137 -4138 -4139 -4140 -4141 -4142 -4143 -4144 -4145 -4146 -4147 -4148 -4149 -4150 -4151 -4152 -4153 -4154 -4155 -4156 -4157 -4158 -4159 -4160 -4161 -4162 -4163 -4164 -4165 -4166 -4167 -4168 -4169 -4170 -4171 -4172 -4173 -4174 -4175 -4176 -4177 -4178 -4179 -4180 -4181 -4182 -4183 -4184 -4185 -4186 -4187 -4188 -4189 -4190 -4191 -4192 -4193 -4194 -4195 -4196 -4197 -4198 -4199 -4200 -4201 -4202 -4203 -4204 -4205 -4206 -4207 -4208 -4209 -4210 -4211 -4212 -4213 -4214 -4215 -4216 -4217 -4218 -4219 -4220 -4221 -4222 -4223 -4224 -4225 -4226 -4227 -4228 -4229 -4230 -4231 -4232 -4233 -4234 -4235 -4236 -4237 -4238 -4239 -4240 -4241 -4242 -4243 -4244 -4245 -4246 -4247 -4248 -4249 -4250 -4251 -4252 -4253 -4254 -4255 -4256 -4257 -4258 -4259 -4260 -4261 -4262 -4263 -4264 -4265 -4266 -4267 -4268 -4269 -4270 -4271 -4272 -4273 -4274 -4275 -4276 -4277 -4278 -4279 -4280 -4281 -4282 -4283 -4284 -4285 -4286 -4287 -4288 -4289 -4290 -4291 -4292 -4293 -4294 -4295 -4296 -4297 -4298 -4299 -4300 -4301 -4302 -4303 -4304 -4305 -4306 -4307 -4308 -4309 -4310 -4311 -4312 -4313 -4314 -4315 -4316 -4317 -4318 -4319 -4320 -4321 -4322 -4323 -4324 -4325 -4326 -4327 -4328 -4329 -4330 -4331 -4332 -4333 -4334 -4335 -4336 -4337 -4338 -4339 -4340 -4341 -4342 -4343 -4344 -4345 -4346 -4347 -4348 -4349 -4350 -4351 -4352 -4353 -4354 -4355 -4356 -4357 -4358 -4359 -4360 -4361 -4362 -4363 -4364 -4365 -4366 -4367 -4368 -4369 -4370 -4371 -4372 -4373 -4374 -4375 -4376 -4377 -4378 -4379 -4380 -4381 -4382 -4383 -4384 -4385 -4386 -4387 -4388 -4389 -4390 -4391 -4392 -4393 -4394 -4395 -4396 -4397 -4398 -4399 -4400 -4401 -4402 -4403 -4404 -4405 -4406 -4407 -4408 -4409 -4410 -4411 -4412 -4413 -4414 -4415 -4416 -4417 -4418 -4419 -4420 -4421 -4422 -4423 -4424 -4425 -4426 -4427 -4428 -4429 -4430 -4431 -4432 -4433 -4434 -4435 -4436 -4437 -4438 -4439 -4440 -4441 -4442 -4443 -4444 -4445 -4446 -4447 -4448 -4449 -4450 -4451 -4452 -4453 -4454 -4455 -4456 -4457 -4458 -4459 -4460 -4461 -4462 -4463 -4464 -4465 -4466 -4467 -4468 -4469 -4470 -4471 -4472 -4473 -4474 -4475 -4476 -4477 -4478 -4479 -4480 -4481 -4482 -4483 -4484 -4485 -4486 -4487 -4488 -4489 -4490 -4491 -4492 -4493 -4494 -4495 -4496 -4497 -4498 -4499 -4500 -4501 -4502 -4503 -4504 -4505 -4506 -4507 -4508 -4509 -4510 -4511 -4512 -4513 -4514 -4515 -4516 -4517 -4518 -4519 -4520 -4521 -4522 -4523 -4524 -4525 -4526 -4527 -4528 -4529 -4530 -4531 -4532 -4533 -4534 -4535 -4536 -4537 -4538 -4539 -4540 -4541 -4542 -4543 -4544 -4545 -4546 -4547 -4548 -4549 -4550 -4551 -4552 -4553 -4554 -4555 -4556 -4557 -4558 -4559 -4560 -4561 -4562 -4563 -4564 -4565 -4566 -4567 -4568 -4569 -4570 -4571 -4572 -4573 -4574 -4575 -4576 -4577 -4578 -4579 -4580 -4581 -4582 -4583 -4584 -4585 -4586 -4587 -4588 -4589 -4590 -4591 -4592 -4593 -4594 -4595 -4596 -4597 -4598 -4599 -4600 -4601 -4602 -4603 -4604 -4605 -4606 -4607 -4608 -4609 -4610 -4611 -4612 -4613 -4614 -4615 -4616 -4617 -4618 -4619 -4620 -4621 -4622 -4623 -4624 -4625 -4626 -4627 -4628 -4629 -4630 -4631 -4632 -4633 -4634 -4635 -4636 -4637 -4638 -4639 -4640 -4641 -4642 -4643 -4644 -4645 -4646 -4647 -4648 -4649 -4650 -4651 -4652 -4653 -4654 -4655 -4656 -4657 -4658 -4659 -4660 -4661 -4662 -4663 -4664 -4665 -4666 -4667 -4668 -4669 -4670 -4671 -4672 -4673 -4674 -4675 -4676 -4677 -4678 -4679 -4680 -4681 -4682 -4683 -4684 -4685 -4686 -4687 -4688 -4689 -4690 -4691 -4692 -4693 -4694 -4695 -4696 -4697 -4698 -4699 -4700 -4701 -4702 -4703 -4704 -4705 -4706 -4707 -4708 -4709 -4710 -4711 -4712 -4713 -4714 -4715 -4716 -4717 -4718 -4719 -4720 -4721 -4722 -4723 -4724 -4725 -4726 -4727 -4728 -4729 -4730 -4731 -4732 -4733 -4734 -4735 -4736 -4737 -4738 -4739 -4740 -4741 -4742 -4743 -4744 -4745 -4746 -4747 -4748 -4749 -4750 -4751 -4752 -4753 -4754 -4755 -4756 -4757 -4758 -4759 -4760 -4761 -4762 -4763 -4764 -4765 -4766 -4767 -4768 -4769 -4770 -4771 -4772 -4773 -4774 -4775 -4776 -4777 -4778 -4779 -4780 -4781 -4782 -4783 -4784 -4785 -4786 -4787 -4788 -4789 -4790 -4791 -4792 -4793 -4794 -4795 -4796 -4797 -4798 -4799 -4800 -4801 -4802 -4803 -4804 -4805 -4806 -4807 -4808 -4809 -4810 -4811 -4812 -4813 -4814 -4815 -4816 -4817 -4818 -4819 -4820 -4821 -4822 -4823 -4824 -4825 -4826 -4827 -4828 -4829 -4830 -4831 -4832 -4833 -4834 -4835 -4836 -4837 -4838 -4839 -4840 -4841 -4842 -4843 -4844 -4845 -4846 -4847 -4848 -4849 -4850 -4851 -4852 -4853 -4854 -4855 -4856 -4857 -4858 -4859 -4860 -4861 -4862 -4863 -4864 -4865 -4866 -4867 -4868 -4869 -4870 -4871 -4872 -4873 -4874 -4875 -4876 -4877 -4878 -4879 -4880 -4881 -4882 -4883 -4884 -4885 -4886 -4887 -4888 -4889 -4890 -4891 -4892 -4893 -4894 -4895 -4896 -4897 -4898 -4899 -4900 -4901 -4902 -4903 -4904 -4905 -4906 -4907 -4908 -4909 -4910 -4911 -4912 -4913 -4914 -4915 -4916 -4917 -4918 -4919 -4920 -4921 -4922 -4923 -4924 -4925 -4926 -4927 -4928 -4929 -4930 -4931 -4932 -4933 -4934 -4935 -4936 -4937 -4938 -4939 -4940 -4941 -4942 -4943 -4944 -4945 -4946 -4947 -4948 -4949 -4950 -4951 -4952 -4953 -4954 -4955 -4956 -4957 -4958 -4959 -4960 -4961 -4962 -4963 -4964 -4965 -4966 -4967 -4968 -4969 -4970 -4971 -4972 -4973 -4974 -4975 -4976 -4977 -4978 -4979 -4980 -4981 -4982 -4983 -4984 -4985 -4986 -4987 -4988 -4989 -4990 -4991 -4992 -4993 -4994 -4995 -4996 -4997 -4998 -4999 -5000 -5001 -5002 -5003 -5004 -5005 -5006 -5007 -5008 -5009 -5010 -5011 -5012 -5013 -5014 -5015 -5016 -5017 -5018 -5019 -5020 -5021 -5022 -5023 -5024 -5025 -5026 -5027 -5028 -5029 -5030 -5031 -5032 -5033 -5034 -5035 -5036 -5037 -5038 -5039 -5040 -5041 -5042 -5043 -5044 -5045 -5046 -5047 -5048 -5049 -5050 -5051 -5052 -5053 -5054 -5055 -5056 -5057 -5058 -5059 -5060 -5061 -5062 -5063 -5064 -5065 -5066 -5067 -5068 -5069 -5070 -5071 -5072 -5073 -5074 -5075 -5076 -5077 -5078 -5079 -5080 -5081 -5082 -5083 -5084 -5085 -5086 -5087 -5088 -5089 -5090 -5091 -5092 -5093 -5094 -5095 -5096 -5097 -5098 -5099 -5100 -5101 -5102 -5103 -5104 -5105 -5106 -5107 -5108 -5109 -5110 -5111 -5112 -5113 -5114 -5115 -5116 -5117 -5118 -5119 -5120 -5121 -5122 -5123 -5124 -5125 -5126 -5127 -5128 -5129 -5130 -5131 -5132 -5133 -5134 -5135 -5136 -5137 -5138 -5139 -5140 -5141 -5142 -5143 -5144 -5145 -5146 -5147 -5148 -5149 -5150 -5151 -5152 -5153 -5154 -5155 -5156 -5157 -5158 -5159 -5160 -5161 -5162 -5163 -5164 -5165 -5166 -5167 -5168 -5169 -5170 -5171 -5172 -5173 -5174 -5175 -5176 -5177 -5178 -5179 -5180 -5181 -5182 -5183 -5184 -5185 -5186 -5187 -5188 -5189 -5190 -5191 -5192 -5193 -5194 -5195 -5196 -5197 -5198 -5199 -5200 -5201 -5202 -5203 -5204 -5205 -5206 -5207 -5208 -5209 -5210 -5211 -5212 -5213 -5214 -5215 -5216 -5217 -5218 -5219 -5220 -5221 -5222 -5223 -5224 -5225 -5226 -5227 -5228 -5229 -5230 -5231 -5232 -5233 -5234 -5235 -5236 -5237 -5238 -5239 -5240 -5241 -5242 -5243 -5244 -5245 -5246 -5247 -5248 -5249 -5250 -5251 -5252 -5253 -5254 -5255 -5256 -5257 -5258 -5259 -5260 -5261 -5262 -5263 -5264 -5265 -5266 -5267 -5268 -5269 -5270 -5271 -5272 -5273 -5274 -5275 -5276 -5277 -5278 -5279 -5280 -5281 -5282 -5283 -5284 -5285 -5286 -5287 -5288 -5289 -5290 -5291 -5292 -5293 -5294 -5295 -5296 -5297 -5298 -5299 -5300 -5301 -5302 -5303 -5304 -5305 -5306 -5307 -5308 -5309 -5310 -5311 -5312 -5313 -5314 -5315 -5316 -5317 -5318 -5319 -5320 -5321 -5322 -5323 -5324 -5325 -5326 -5327 -5328 -5329 -5330 -5331 -5332 -5333 -5334 -5335 -5336 -5337 -5338 -5339 -5340 -5341 -5342 -5343 -5344 -5345 -5346 -5347 -5348 -5349 -5350 -5351 -5352 -5353 -5354 -5355 -5356 -5357 -5358 -5359 -5360 -5361 -5362 -5363 -5364 -5365 -5366 -5367 -5368 -5369 -5370 -5371 -5372 -5373 -5374 -5375 -5376 -5377 -5378 -5379 -5380 -5381 -5382 -5383 -5384 -5385 -5386 -5387 -5388 -5389 -5390 -5391 -5392 -5393 -5394 -5395 -5396 -5397 -5398 -5399 -5400 -5401 -5402 -5403 -5404 -5405 -5406 -5407 -5408 -5409 -5410 -5411 -5412 -5413 -5414 -5415 -5416 -5417 -5418 -5419 -5420 -5421 -5422 -5423 -5424 -5425 -5426 -5427 -5428 -5429 -5430 -5431 -5432 -5433 -5434 -5435 -5436 -5437 -5438 -5439 -5440 -5441 -5442 -5443 -5444 -5445 -5446 -5447 -5448 -5449 -5450 -5451 -5452 -5453 -5454 -5455 -5456 -5457 -5458 -5459 -5460 -5461 -5462 -5463 -5464 -5465 -5466 -5467 -5468 -5469 -5470 -5471 -5472 -5473 -5474 -5475 -5476 -5477 -5478 -5479 -5480 -5481 -5482 -5483 -5484 -5485 -5486 -5487 -5488 -5489 -5490 -5491 -5492 -5493 -5494 -5495 -5496 -5497 -5498 -5499 -5500 -5501 -5502 -5503 -5504 -5505 -5506 -5507 -5508 -5509 -5510 -5511 -5512 -5513 -5514 -5515 -5516 -5517 -5518 -5519 -5520 -5521 -5522 -5523 -5524 -5525 -5526 -5527 -5528 -5529 -5530 -5531 -5532 -5533 -5534 -5535 -5536 -5537 -5538 -5539 -5540 -5541 -5542 -5543 -5544 -5545 -5546 -5547 -5548 -5549 -5550 -5551 -5552 -5553 -5554 -5555 -5556 -5557 -5558 -5559 -5560 -5561 -5562 -5563 -5564 -5565 -5566 -5567 -5568 -5569 -5570 -5571 -5572 -5573 -5574 -5575 -5576 -5577 -5578 -5579 -5580 -5581 -5582 -5583 -5584 -5585 -5586 -5587 -5588 -5589 -5590 -5591 -5592 -5593 -5594 -5595 -5596 -5597 -5598 -5599 -5600 -5601 -5602 -5603 -5604 -5605 -5606 -5607 -5608 -5609 -5610 -5611 -5612 -5613 -5614 -5615 -5616 -5617 -5618 -5619 -5620 -5621 -5622 -5623 -5624 -5625 -5626 -5627 -5628 -5629 -5630 -5631 -5632 -5633 -5634 -5635 -5636 -5637 -5638 -5639 -5640 -5641 -5642 -5643 -5644 -5645 -5646 -5647 -5648 -5649 -5650 -5651 -5652 -5653 -5654 -5655 -5656 -5657 -5658 -5659 -5660 -5661 -5662 -5663 -5664 -5665 -5666 -5667 -5668 -5669 -5670 -5671 -5672 -5673 -5674 -5675 -5676 -5677 -5678 -5679 -5680 -5681 -5682 -5683 -5684 -5685 -5686 -5687 -5688 -5689 -5690 -5691 -5692 -5693 -5694 -5695 -5696 -5697 -5698 -5699 -5700 -5701 -5702 -5703 -5704 -5705 -5706 -5707 -5708 -5709 -5710 -5711 -5712 -5713 -5714 -5715 -5716 -5717 -5718 -5719 -5720 -5721 -5722 -5723 -5724 -5725 -5726 -5727 -5728 -5729 -5730 -5731 -5732 -5733 -5734 -5735 -5736 -5737 -5738 -5739 -5740 -5741 -5742 -5743 -5744 -5745 -5746 -5747 -5748 -5749 -5750 -5751 -5752 -5753 -5754 -5755 -5756 -5757 -5758 -5759 -5760 -5761 -5762 -5763 -5764 -5765 -5766 -5767 -5768 -5769 -5770 -5771 -5772 -5773 -5774 -5775 -5776 -5777 -5778 -5779 -5780 -5781 -5782 -5783 -5784 -5785 -5786 -5787 -5788 -5789 -5790 -5791 -5792 -5793 -5794 -5795 -5796 -5797 -5798 -5799 -5800 -5801 -5802 -5803 -5804 -5805 -5806 -5807 -5808 -5809 -5810 -5811 -5812 -5813 -5814 -5815 -5816 -5817 -5818 -5819 -5820 -5821 -5822 -5823 -5824 -5825 -5826 -5827 -5828 -5829 -5830 -5831 -5832 -5833 -5834 -5835 -5836 -5837 -5838 -5839 -5840 -5841 -5842 -5843 -5844 -5845 -5846 -5847 -5848 -5849 -5850 -5851 -5852 -5853 -5854 -5855 -5856 -5857 -5858 -5859 -5860 -5861 -5862 -5863 -5864 -5865 -5866 -5867 -5868 -5869 -5870 -5871 -5872 -5873 -5874 -5875 -5876 -5877 -5878 -5879 -5880 -5881 -5882 -5883 -5884 -5885 -5886 -5887 -5888 -5889 -5890 -5891 -5892 -5893 -5894 -5895 -5896 -5897 -5898 -5899 -5900 -5901 -5902 -5903 -5904 -5905 -5906 -5907 -5908 -5909 -5910 -5911 -5912 -5913 -5914 -5915 -5916 -5917 -5918 -5919 -5920 -5921 -5922 -5923 -5924 -5925 -5926 -5927 -5928 -5929 -5930 -5931 -5932 -5933 -5934 -5935 -5936 -5937 -5938 -5939 -5940 -5941 -5942 -5943 -5944 -5945 -5946 -5947 -5948 -5949 -5950 -5951 -5952 -5953 -5954 -5955 -5956 -5957 -5958 -5959 -5960 -5961 -5962 -5963 -5964 -5965 -5966 -5967 -5968 -5969 -5970 -5971 -5972 -5973 -5974 -5975 -5976 -5977 -5978 -5979 -5980 -5981 -5982 -5983 -5984 -5985 -5986 -5987 -5988 -5989 -5990 -5991 -5992 -5993 -5994 -5995 -5996 -5997 -5998 -5999 -6000 -6001 -6002 -6003 -6004 -6005 -6006 -6007 -6008 -6009 -6010 -6011 -6012 -6013 -6014 -6015 -6016 -6017 -6018 -6019 -6020 -6021 -6022 -6023 -6024 -6025 -6026 -6027 -6028 -6029 -6030 -6031 -6032 -6033 -6034 -6035 -6036 -6037 -6038 -6039 -6040 -6041 -6042 -6043 -6044 -6045 -6046 -6047 -6048 -6049 -6050 -6051 -6052 -6053 -6054 -6055 -6056 -6057 -6058 -6059 -6060 -6061 -6062 -6063 -6064 -6065 -6066 -6067 -6068 -6069 -6070 -6071 -6072 -6073 -6074 -6075 -6076 -6077 -6078 -6079 -6080 -6081 -6082 -6083 -6084 -6085 -6086 -6087 -6088 -6089 -6090 -6091 -6092 -6093 -6094 -6095 -6096 -6097 -6098 -6099 -6100 -6101 -6102 -6103 -6104 -6105 -6106 -6107 -6108 -6109 -6110 -6111 -6112 -6113 -6114 -6115 -6116 -6117 -6118 -6119 -6120 -6121 -6122 -6123 -6124 -6125 -6126 -6127 -6128 -6129 -6130 -6131 -6132 -6133 -6134 -6135 -6136 -6137 -6138 -6139 -6140 -6141 -6142 -6143 -6144 -6145 -6146 -6147 -6148 -6149 -6150 -6151 -6152 -6153 -6154 -6155 -6156 -6157 -6158 -6159 -6160 -6161 -6162 -6163 -6164 -6165 -6166 -6167 -6168 -6169 -6170 -6171 -6172 -6173 -6174 -6175 -6176 -6177 -6178 -6179 -6180 -6181 -6182 -6183 -6184 -6185 -6186 -6187 -6188 -6189 -6190 -6191 -6192 -6193 -6194 -6195 -6196 -6197 -6198 -6199 -6200 -6201 -6202 -6203 -6204 -6205 -6206 -6207 -6208 -6209 -6210 -6211 -6212 -6213 -6214 -6215 -6216 -6217 -6218 -6219 -6220 -6221 -6222 -6223 -6224 -6225 -6226 -6227 -6228 -6229 -6230 -6231 -6232 -6233 -6234 -6235 -6236 -6237 -6238 -6239 -6240 -6241 -6242 -6243 -6244 -6245 -6246 -6247 -6248 -6249 -6250 -6251 -6252 -6253 -6254 -6255 -6256 -6257 -6258 -6259 -6260 -6261 -6262 -6263 -6264 -6265 -6266 -6267 -6268 -6269 -6270 -6271 -6272 -6273 -6274 -6275 -6276 -6277 -6278 -6279 -6280 -6281 -6282 -6283 -6284 -6285 -6286 -6287 -6288 -6289 -6290 -6291 -6292 -6293 -6294 -6295 -6296 -6297 -6298 -6299 -6300 -6301 -6302 -6303 -6304 -6305 -6306 -6307 -6308 -6309 -6310 -6311 -6312 -6313 -6314 -6315 -6316 -6317 -6318 -6319 -6320 -6321 -6322 -6323 -6324 -6325 -6326 -6327 -6328 -6329 -6330 -6331 -6332 -6333 -6334 -6335 -6336 -6337 -6338 -6339 -6340 -6341 -6342 -6343 -6344 -6345 -6346 -6347 -6348 -6349 -6350 -6351 -6352 -6353 -6354 -6355 -6356 -6357 -6358 -6359 -6360 -6361 -6362 -6363 -6364 -6365 -6366 -6367 -6368 -6369 -6370 -6371 -6372 -6373 -6374 -6375 -6376 -6377 -6378 -6379 -6380 -6381 -6382 -6383 -6384 -6385 -6386 -6387 -6388 -6389 -6390 -6391 -6392 -6393 -6394 -6395 -6396 -6397 -6398 -6399 -6400 -6401 -6402 -6403 -6404 -6405 -6406 -6407 -6408 -6409 -6410 -6411 -6412 -6413 -6414 -6415 -6416 -6417 -6418 -6419 -6420 -6421 -6422 -6423 -6424 -6425 -6426 -6427 -6428 -6429 -6430 -6431 -6432 -6433 -6434 -6435 -6436 -6437 -6438 -6439 -6440 -6441 -6442 -6443 -6444 -6445 -6446 -6447 -6448 -6449 -6450 -6451 -6452 -6453 -6454 -6455 -6456 -6457 -6458 -6459 -6460 -6461 -6462 -6463 -6464 -6465 -6466 -6467 -6468 -6469 -6470 -6471 -6472 -6473 -6474 -6475 -6476 -6477 -6478 -6479 -6480 -6481 -6482 -6483 -6484 -6485 -6486 -6487 -6488 -6489 -6490 -6491 -6492 -6493 -6494 -6495 -6496 -6497 -6498 -6499 -6500 -6501 -6502 -6503 -6504 -6505 -6506 -6507 -6508 -6509 -6510 -6511 -6512 -6513 -6514 -6515 -6516 -6517 -6518 -6519 -6520 -6521 -6522 -6523 -6524 -6525 -6526 -6527 -6528 -6529 -6530 -6531 -6532 -6533 -6534 -6535 -6536 -6537 -6538 -6539 -6540 -6541 -6542 -6543 -6544 -6545 -6546 -6547 -6548 -6549 -6550 -6551 -6552 -6553 -6554 -6555 -6556 -6557 -6558 -6559 -6560 -6561 -6562 -6563 -6564 -6565 -6566 -6567 -6568 -6569 -6570 -6571 -6572 -6573 -6574 -6575 -6576 -6577 -6578 -6579 -6580 -6581 -6582 -6583 -6584 -6585 -6586 -6587 -6588 -6589 -6590 -6591 -6592 -6593 -6594 -6595 -6596 -6597 -6598 -6599 -6600 -6601 -6602 -6603 -6604 -6605 -6606 -6607 -6608 -6609 -6610 -6611 -6612 -6613 -6614 -6615 -6616 -6617 -6618 -6619 -6620 -6621 -6622 -6623 -6624 -6625 -6626 -6627 -6628 -6629 -6630 -6631 -6632 -6633 -6634 -6635 -6636 -6637 -6638 -6639 -6640 -6641 -6642 -6643 -6644 -6645 -6646 -6647 -6648 -6649 -6650 -6651 -6652 -6653 -6654 -6655 -6656 -6657 -6658 -6659 -6660 -6661 -6662 -6663 -6664 -6665 -6666 -6667 -6668 -6669 -6670 -6671 -6672 -6673 -6674 -6675 -6676 -6677 -6678 -6679 -6680 -6681 -6682 -6683 -6684 -6685 -6686 -6687 -6688 -6689 -6690 -6691 -6692 -6693 -6694 -6695 -6696 -6697 -6698 -6699 -6700 -6701 -6702 -6703 -6704 -6705 -6706 -6707 -6708 -6709 -6710 -6711 -6712 -6713 -6714 -6715 -6716 -6717 -6718 -6719 -6720 -6721 -6722 -6723 -6724 -6725 -6726 -6727 -6728 -6729 -6730 -6731 -6732 -6733 -6734 -6735 -6736 -6737 -6738 -6739 -6740 -6741 -6742 -6743 -6744 -6745 -6746 -6747 -6748 -6749 -6750 -6751 -6752 -6753 -6754 -6755 -6756 -6757 -6758 -6759 -6760 -6761 -6762 -6763 -6764 -6765 -6766 -6767 -6768 -6769 -6770 -6771 -6772 -6773 -6774 -6775 -6776 -6777 -6778 -6779 -6780 -6781 -6782 -6783 -6784 -6785 -6786 -6787 -6788 -6789 -6790 -6791 -6792 -6793 -6794 -6795 -6796 -6797 -6798 -6799 -6800 -6801 -6802 -6803 -6804 -6805 -6806 -6807 -6808 -6809 -6810 -6811 -6812 -6813 -6814 -6815 -6816 -6817 -6818 -6819 -6820 -6821 -6822 -6823 -6824 -6825 -6826 -6827 -6828 -6829 -6830 -6831 -6832 -6833 -6834 -6835 -6836 -6837 -6838 -6839 -6840 -6841 -6842 -6843 -6844 -6845 -6846 -6847 -6848 -6849 -6850 -6851 -6852 -6853 -6854 -6855 -6856 -6857 -6858 -6859 -6860 -6861 -6862 -6863 -6864 -6865 -6866 -6867 -6868 -6869 -6870 -6871 -6872 -6873 -6874 -6875 -6876 -6877 -6878 -6879 -6880 -6881 -6882 -6883 -6884 -6885 -6886 -6887 -6888 -6889 -6890 -6891 -6892 -6893 -6894 -6895 -6896 -6897 -6898 -6899 -6900 -6901 -6902 -6903 -6904 -6905 -6906 -6907 -6908 -6909 -6910 -6911 -6912 -6913 -6914 -6915 -6916 -6917 -6918 -6919 -6920 -6921 -6922 -6923 -6924 -6925 -6926 -6927 -6928 -6929 -6930 -6931 -6932 -6933 -6934 -6935 -6936 -6937 -6938 -6939 -6940 -6941 -6942 -6943 -6944 -6945 -6946 -6947 -6948 -6949 -6950 -6951 -6952 -6953 -6954 -6955 -6956 -6957 -6958 -6959 -6960 -6961 -6962 -6963 -6964 -6965 -6966 -6967 -6968 -6969 -6970 -6971 -6972 -6973 -6974 -6975 -6976 -6977 -6978 -6979 -6980 -6981 -6982 -6983 -6984 -6985 -6986 -6987 -6988 -6989 -6990 -6991 -6992 -6993 -6994 -6995 -6996 -6997 -6998 -6999 -7000 -7001 -7002 -7003 -7004 -7005 -7006 -7007 -7008 -7009 -7010 -7011 -7012 -7013 -7014 -7015 -7016 -7017 -7018 -7019 -7020 -7021 -7022 -7023 -7024 -7025 -7026 -7027 -7028 -7029 -7030 -7031 -7032 -7033 -7034 -7035 -7036 -7037 -7038 -7039 -7040 -7041 -7042 -7043 -7044 -7045 -7046 -7047 -7048 -7049 -7050 -7051 -7052 -7053 -7054 -7055 -7056 -7057 -7058 -7059 -7060 -7061 -7062 -7063 -7064 -7065 -7066 -7067 -7068 -7069 -7070 -7071 -7072 -7073 -7074 -7075 -7076 -7077 -7078 -7079 -7080 -7081 -7082 -7083 -7084 -7085 -7086 -7087 -7088 -7089 -7090 -7091 -7092 -7093 -7094 -7095 -7096 -7097 -7098 -7099 -7100 -7101 -7102 -7103 -7104 -7105 -7106 -7107 -7108 -7109 -7110 -7111 -7112 -7113 -7114 -7115 -7116 -7117 -7118 -7119 -7120 -7121 -7122 -7123 -7124 -7125 -7126 -7127 -7128 -7129 -7130 -7131 -7132 -7133 -7134 -7135 -7136 -7137 -7138 -7139 -7140 -7141 -7142 -7143 -7144 -7145 -7146 -7147 -7148 -7149 -7150 -7151 -7152 -7153 -7154 -7155 -7156 -7157 -7158 -7159 -7160 -7161 -7162 -7163 -7164 -7165 -7166 -7167 -7168 -7169 -7170 -7171 -7172 -7173 -7174 -7175 -7176 -7177 -7178 -7179 -7180 -7181 -7182 -7183 -7184 -7185 -7186 -7187 -7188 -7189 -7190 -7191 -7192 -7193 -7194 -7195 -7196 -7197 -7198 -7199 -7200 -7201 -7202 -7203 -7204 -7205 -7206 -7207 -7208 -7209 -7210 -7211 -7212 -7213 -7214 -7215 -7216 -7217 -7218 -7219 -7220 -7221 -7222 -7223 -7224 -7225 -7226 -7227 -7228 -7229 -7230 -7231 -7232 -7233 -7234 -7235 -7236 -7237 -7238 -7239 -7240 -7241 -7242 -7243 -7244 -7245 -7246 -7247 -7248 -7249 -7250 -7251 -7252 -7253 -7254 -7255 -7256 -7257 -7258 -7259 -7260 -7261 -7262 -7263 -7264 -7265 -7266 -7267 -7268 -7269 -7270 -7271 -7272 -7273 -7274 -7275 -7276 -7277 -7278 -7279 -7280 -7281 -7282 -7283 -7284 -7285 -7286 -7287 -7288 -7289 -7290 -7291 -7292 -7293 -7294 -7295 -7296 -7297 -7298 -7299 -7300 -7301 -7302 -7303 -7304 -7305 -7306 -7307 -7308 -7309 -7310 -7311 -7312 -7313 -7314 -7315 -7316 -7317 -7318 -7319 -7320 -7321 -7322 -7323 -7324 -7325 -7326 -7327 -7328 -7329 -7330 -7331 -7332 -7333 -7334 -7335 -7336 -7337 -7338 -7339 -7340 -7341 -7342 -7343 -7344 -7345 -7346 -7347 -7348 -7349 -7350 -7351 -7352 -7353 -7354 -7355 -7356 -7357 -7358 -7359 -7360 -7361 -7362 -7363 -7364 -7365 -7366 -7367 -7368 -7369 -7370 -7371 -7372 -7373 -7374 -7375 -7376 -7377 -7378 -7379 -7380 -7381 -7382 -7383 -7384 -7385 -7386 -7387 -7388 -7389 -7390 -7391 -7392 -7393 -7394 -7395 -7396 -7397 -7398 -7399 -7400 -7401 -7402 -7403 -7404 -7405 -7406 -7407 -7408 -7409 -7410 -7411 -7412 -7413 -7414 -7415 -7416 -7417 -7418 -7419 -7420 -7421 -7422 -7423 -7424 -7425 -7426 -7427 -7428 -7429 -7430 -7431 -7432 -7433 -7434 -7435 -7436 -7437 -7438 -7439 -7440 -7441 -7442 -7443 -7444 -7445 -7446 -7447 -7448 -7449 -7450 -7451 -7452 -7453 -7454 -7455 -7456 -7457 -7458 -7459 -7460 -7461 -7462 -7463 -7464 -7465 -7466 -7467 -7468 -7469 -7470 -7471 -7472 -7473 -7474 -7475 -7476 -7477 -7478 -7479 -7480 -7481 -7482 -7483 -7484 -7485 -7486 -7487 -7488 -7489 -7490 -7491 -7492 -7493 -7494 -7495 -7496 -7497 -7498 -7499 -7500 -7501 -7502 -7503 -7504 -7505 -7506 -7507 -7508 -7509 -7510 -7511 -7512 -7513 -7514 -7515 -7516 -7517 -7518 -7519 -7520 -7521 -7522 -7523 -7524 -7525 -7526 -7527 -7528 -7529 -7530 -7531 -7532 -7533 -7534 -7535 -7536 -7537 -7538 -7539 -7540 -7541 -7542 -7543 -7544 -7545 -7546 -7547 -7548 -7549 -7550 -7551 -7552 -7553 -7554 -7555 -7556 -7557 -7558 -7559 -7560 -7561 -7562 -7563 -7564 -7565 -7566 -7567 -7568 -7569 -7570 -7571 -7572 -7573 -7574 -7575 -7576 -7577 -7578 -7579 -7580 -7581 -7582 -7583 -7584 -7585 -7586 -7587 -7588 -7589 -7590 -7591 -7592 -7593 -7594 -7595 -7596 -7597 -7598 -7599 -7600 -7601 -7602 -7603 -7604 -7605 -7606 -7607 -7608 -7609 -7610 -7611 -7612 -7613 -7614 -7615 -7616 -7617 -7618 -7619 -7620 -7621 -7622 -7623 -7624 -7625 -7626 -7627 -7628 -7629 -7630 -7631 -7632 -7633 -7634 -7635 -7636 -7637 -7638 -7639 -7640 -7641 -7642 -7643 -7644 -7645 -7646 -7647 -7648 -7649 -7650 -7651 -7652 -7653 -7654 -7655 -7656 -7657 -7658 -7659 -7660 -7661 -7662 -7663 -7664 -7665 -7666 -7667 -7668 -7669 -7670 -7671 -7672 -7673 -7674 -7675 -7676 -7677 -7678 -7679 -7680 -7681 -7682 -7683 -7684 -7685 -7686 -7687 -7688 -7689 -7690 -7691 -7692 -7693 -7694 -7695 -7696 -7697 -7698 -7699 -7700 -7701 -7702 -7703 -7704 -7705 -7706 -7707 -7708 -7709 -7710 -7711 -7712 -7713 -7714 -7715 -7716 -7717 -7718 -7719 -7720 -7721 -7722 -7723 -7724 -7725 -7726 -7727 -7728 -7729 -7730 -7731 -7732 -7733 -7734 -7735 -7736 -7737 -7738 -7739 -7740 -7741 -7742 -7743 -7744 -7745 -7746 -7747 -7748 -7749 -7750 -7751 -7752 -7753 -7754 -7755 -7756 -7757 -7758 -7759 -7760 -7761 -7762 -7763 -7764 -7765 -7766 -7767 -7768 -7769 -7770 -7771 -7772 -7773 -7774 -7775 -7776 -7777 -7778 -7779 -7780 -7781 -7782 -7783 -7784 -7785 -7786 -7787 -7788 -7789 -7790 -7791 -7792 -7793 -7794 -7795 -7796 -7797 -7798 -7799 -7800 -7801 -7802 -7803 -7804 -7805 -7806 -7807 -7808 -7809 -7810 -7811 -7812 -7813 -7814 -7815 -7816 -7817 -7818 -7819 -7820 -7821 -7822 -7823 -7824 -7825 -7826 -7827 -7828 -7829 -7830 -7831 -7832 -7833 -7834 -7835 -7836 -7837 -7838 -7839 -7840 -7841 -7842 -7843 -7844 -7845 -7846 -7847 -7848 -7849 -7850 -7851 -7852 -7853 -7854 -7855 -7856 -7857 -7858 -7859 -7860 -7861 -7862 -7863 -7864 -7865 -7866 -7867 -7868 -7869 -7870 -7871 -7872 -7873 -7874 -7875 -7876 -7877 -7878 -7879 -7880 -7881 -7882 -7883 -7884 -7885 -7886 -7887 -7888 -7889 -7890 -7891 -7892 -7893 -7894 -7895 -7896 -7897 -7898 -7899 -7900 -7901 -7902 -7903 -7904 -7905 -7906 -7907 -7908 -7909 -7910 -7911 -7912 -7913 -7914 -7915 -7916 -7917 -7918 -7919 -7920 -7921 -7922 -7923 -7924 -7925 -7926 -7927 -7928 -7929 -7930 -7931 -7932 -7933 -7934 -7935 -7936 -7937 -7938 -7939 -7940 -7941 -7942 -7943 -7944 -7945 -7946 -7947 -7948 -7949 -7950 -7951 -7952 -7953 -7954 -7955 -7956 -7957 -7958 -7959 -7960 -7961 -7962 -7963 -7964 -7965 -7966 -7967 -7968 -7969 -7970 -7971 -7972 -7973 -7974 -7975 -7976 -7977 -7978 -7979 -7980 -7981 -7982 -7983 -7984 -7985 -7986 -7987 -7988 -7989 -7990 -7991 -7992 -7993 -7994 -7995 -7996 -7997 -7998 -7999 -8000 -8001 -8002 -8003 -8004 -8005 -8006 -8007 -8008 -8009 -8010 -8011 -8012 -8013 -8014 -8015 -8016 -8017 -8018 -8019 -8020 -8021 -8022 -8023 -8024 -8025 -8026 -8027 -8028 -8029 -8030 -8031 -8032 -8033 -8034 -8035 -8036 -8037 -8038 -8039 -8040 -8041 -8042 -8043 -8044 -8045 -8046 -8047 -8048 -8049 -8050 -8051 -8052 -8053 -8054 -8055 -8056 -8057 -8058 -8059 -8060 -8061 -8062 -8063 -8064 -8065 -8066 -8067 -8068 -8069 -8070 -8071 -8072 -8073 -8074 -8075 -8076 -8077 -8078 -8079 -8080 -8081 -8082 -8083 -8084 -8085 -8086 -8087 -8088 -8089 -8090 -8091 -8092 -8093 -8094 -8095 -8096 -8097 -8098 -8099 -8100 -8101 -8102 -8103 -8104 -8105 -8106 -8107 -8108 -8109 -8110 -8111 -8112 -8113 -8114 -8115 -8116 -8117 -8118 -8119 -8120 -8121 -8122 -8123 -8124 -8125 -8126 -8127 -8128 -8129 -8130 -8131 -8132 -8133 -8134 -8135 -8136 -8137 -8138 -8139 -8140 -8141 -8142 -8143 -8144 -8145 -8146 -8147 -8148 -8149 -8150 -8151 -8152 -8153 -8154 -8155 -8156 -8157 -8158 -8159 -8160 -8161 -8162 -8163 -8164 -8165 -8166 -8167 -8168 -8169 -8170 -8171 -8172 -8173 -8174 -8175 -8176 -8177 -8178 -8179 -8180 -8181 -8182 -8183 -8184 -8185 -8186 -8187 -8188 -8189 -8190 -8191 -8192 -8193 -8194 -8195 -8196 -8197 -8198 -8199 -8200 -8201 -8202 -8203 -8204 -8205 -8206 -8207 -8208 -8209 -8210 -8211 -8212 -8213 -8214 -8215 -8216 -8217 -8218 -8219 -8220 -8221 -8222 -8223 -8224 -8225 -8226 -8227 -8228 -8229 -8230 -8231 -8232 -8233 -8234 -8235 -8236 -8237 -8238 -8239 -8240 -8241 -8242 -8243 -8244 -8245 -8246 -8247 -8248 -8249 -8250 -8251 -8252 -8253 -8254 -8255 -8256 -8257 -8258 -8259 -8260 -8261 -8262 -8263 -8264 -8265 -8266 -8267 -8268 -8269 -8270 -8271 -8272 -8273 -8274 -8275 -8276 -8277 -8278 -8279 -8280 -8281 -8282 -8283 -8284 -8285 -8286 -8287 -8288 -8289 -8290 -8291 -8292 -8293 -8294 -8295 -8296 -8297 -8298 -8299 -8300 -8301 -8302 -8303 -8304 -8305 -8306 -8307 -8308 -8309 -8310 -8311 -8312 -8313 -8314 -8315 -8316 -8317 -8318 -8319 -8320 -8321 -8322 -8323 -8324 -8325 -8326 -8327 -8328 -8329 -8330 -8331 -8332 -8333 -8334 -8335 -8336 -8337 -8338 -8339 -8340 -8341 -8342 -8343 -8344 -8345 -8346 -8347 -8348 -8349 -8350 -8351 -8352 -8353 -8354 -8355 -8356 -8357 -8358 -8359 -8360 -8361 -8362 -8363 -8364 -8365 -8366 -8367 -8368 -8369 -8370 -8371 -8372 -8373 -8374 -8375 -8376 -8377 -8378 -8379 -8380 -8381 -8382 -8383 -8384 -8385 -8386 -8387 -8388 -8389 -8390 -8391 -8392 -8393 -8394 -8395 -8396 -8397 -8398 -8399 -8400 -8401 -8402 -8403 -8404 -8405 -8406 -8407 -8408 -8409 -8410 -8411 -8412 -8413 -8414 -8415 -8416 -8417 -8418 -8419 -8420 -8421 -8422 -8423 -8424 -8425 -8426 -8427 -8428 -8429 -8430 -8431 -8432 -8433 -8434 -8435 -8436 -8437 -8438 -8439 -8440 -8441 -8442 -8443 -8444 -8445 -8446 -8447 -8448 -8449 -8450 -8451 -8452 -8453 -8454 -8455 -8456 -8457 -8458 -8459 -8460 -8461 -8462 -8463 -8464 -8465 -8466 -8467 -8468 -8469 -8470 -8471 -8472 -8473 -8474 -8475 -8476 -8477 -8478 -8479 -8480 -8481 -8482 -8483 -8484 -8485 -8486 -8487 -8488 -8489 -8490 -8491 -8492 -8493 -8494 -8495 -8496 -8497 -8498 -8499 -8500 -8501 -8502 -8503 -8504 -8505 -8506 -8507 -8508 -8509 -8510 -8511 -8512 -8513 -8514 -8515 -8516 -8517 -8518 -8519 -8520 -8521 -8522 -8523 -8524 -8525 -8526 -8527 -8528 -8529 -8530 -8531 -8532 -8533 -8534 -8535 -8536 -8537 -8538 -8539 -8540 -8541 -8542 -8543 -8544 -8545 -8546 -8547 -8548 -8549 -8550 -8551 -8552 -8553 -8554 -8555 -8556 -8557 -8558 -8559 -8560 -8561 -8562 -8563 -8564 -8565 -8566 -8567 -8568 -8569 -8570 -8571 -8572 -8573 -8574 -8575 -8576 -8577 -8578 -8579 -8580 -8581 -8582 -8583 -8584 -8585 -8586 -8587 -8588 -8589 -8590 -8591 -8592 -8593 -8594 -8595 -8596 -8597 -8598 -8599 -8600 -8601 -8602 -8603 -8604 -8605 -8606 -8607 -8608 -8609 -8610 -8611 -8612 -8613 -8614 -8615 -8616 -8617 -8618 -8619 -8620 -8621 -8622 -8623 -8624 -8625 -8626 -8627 -8628 -8629 -8630 -8631 -8632 -8633 -8634 -8635 -8636 -8637 -8638 -8639 -8640 -8641 -8642 -8643 -8644 -8645 -8646 -8647 -8648 -8649 -8650 -8651 -8652 -8653 -8654 -8655 -8656 -8657 -8658 -8659 -8660 -8661 -8662 -8663 -8664 -8665 -8666 -8667 -8668 -8669 -8670 -8671 -8672 -8673 -8674 -8675 -8676 -8677 -8678 -8679 -8680 -8681 -8682 -8683 -8684 -8685 -8686 -8687 -8688 -8689 -8690 -8691 -8692 -8693 -8694 -8695 -8696 -8697 -8698 -8699 -8700 -8701 -8702 -8703 -8704 -8705 -8706 -8707 -8708 -8709 -8710 -8711 -8712 -8713 -8714 -8715 -8716 -8717 -8718 -8719 -8720 -8721 -8722 -8723 -8724 -8725 -8726 -8727 -8728 -8729 -8730 -8731 -8732 -8733 -8734 -8735 -8736 -8737 -8738 -8739 -8740 -8741 -8742 -8743 -8744 -8745 -8746 -8747 -8748 -8749 -8750 -8751 -8752 -8753 -8754 -8755 -8756 -8757 -8758 -8759 -8760 -8761 -8762 -8763 -8764 -8765 -8766 -8767 -8768 -8769 -8770 -8771 -8772 -8773 -8774 -8775 -8776 -8777 -8778 -8779 -8780 -8781 -8782 -8783 -8784 -8785 -8786 -8787 -8788 -8789 -8790 -8791 -8792 -8793 -8794 -8795 -8796 -8797 -8798 -8799 -8800 -8801 -8802 -8803 -8804 -8805 -8806 -8807 -8808 -8809 -8810 -8811 -8812 -8813 -8814 -8815 -8816 -8817 -8818 -8819 -8820 -8821 -8822 -8823 -8824 -8825 -8826 -8827 -8828 -8829 -8830 -8831 -8832 -8833 -8834 -8835 -8836 -8837 -8838 -8839 -8840 -8841 -8842 -8843 -8844 -8845 -8846 -8847 -8848 -8849 -8850 -8851 -8852 -8853 -8854 -8855 -8856 -8857 -8858 -8859 -8860 -8861 -8862 -8863 -8864 -8865 -8866 -8867 -8868 -8869 -8870 -8871 -8872 -8873 -8874 -8875 -8876 -8877 -8878 -8879 -8880 -8881 -8882 -8883 -8884 -8885 -8886 -8887 -8888 -8889 -8890 -8891 -8892 -8893 -8894 -8895 -8896 -8897 -8898 -8899 -8900 -8901 -8902 -8903 -8904 -8905 -8906 -8907 -8908 -8909 -8910 -8911 -8912 -8913 -8914 -8915 -8916 -8917 -8918 -8919 -8920 -8921 -8922 -8923 -8924 -8925 -8926 -8927 -8928 -8929 -8930 -8931 -8932 -8933 -8934 -8935 -8936 -8937 -8938 -8939 -8940 -8941 -8942 -8943 -8944 -8945 -8946 -8947 -8948 -8949 -8950 -8951 -8952 -8953 -8954 -8955 -8956 -8957 -8958 -8959 -8960 -8961 -8962 -8963 -8964 -8965 -8966 -8967 -8968 -8969 -8970 -8971 -8972 -8973 -8974 -8975 -8976 -8977 -8978 -8979 -8980 -8981 -8982 -8983 -8984 -8985 -8986 -8987 -8988 -8989 -8990 -8991 -8992 -8993 -8994 -8995 -8996 -8997 -8998 -8999 -9000 -9001 -9002 -9003 -9004 -9005 -9006 -9007 -9008 -9009 -9010 -9011 -9012 -9013 -9014 -9015 -9016 -9017 -9018 -9019 -9020 -9021 -9022 -9023 -9024 -9025 -9026 -9027 -9028 -9029 -9030 -9031 -9032 -9033 -9034 -9035 -9036 -9037 -9038 -9039 -9040 -9041 -9042 -9043 -9044 -9045 -9046 -9047 -9048 -9049 -9050 -9051 -9052 -9053 -9054 -9055 -9056 -9057 -9058 -9059 -9060 -9061 -9062 -9063 -9064 -9065 -9066 -9067 -9068 -9069 -9070 -9071 -9072 -9073 -9074 -9075 -9076 -9077 -9078 -9079 -9080 -9081 -9082 -9083 -9084 -9085 -9086 -9087 -9088 -9089 -9090 -9091 -9092 -9093 -9094 -9095 -9096 -9097 -9098 -9099 -9100 -9101 -9102 -9103 -9104 -9105 -9106 -9107 -9108 -9109 -9110 -9111 -9112 -9113 -9114 -9115 -9116 -9117 -9118 -9119 -9120 -9121 -9122 -9123 -9124 -9125 -9126 -9127 -9128 -9129 -9130 -9131 -9132 -9133 -9134 -9135 -9136 -9137 -9138 -9139 -9140 -9141 -9142 -9143 -9144 -9145 -9146 -9147 -9148 -9149 -9150 -9151 -9152 -9153 -9154 -9155 -9156 -9157 -9158 -9159 -9160 -9161 -9162 -9163 -9164 -9165 -9166 -9167 -9168 -9169 -9170 -9171 -9172 -9173 -9174 -9175 -9176 -9177 -9178 -9179 -9180 -9181 -9182 -9183 -9184 -9185 -9186 -9187 -9188 -9189 -9190 -9191 -9192 -9193 -9194 -9195 -9196 -9197 -9198 -9199 -9200 -9201 -9202 -9203 -9204 -9205 -9206 -9207 -9208 -9209 -9210 -9211 -9212 -9213 -9214 -9215 -9216 -9217 -9218 -9219 -9220 -9221 -9222 -9223 -9224 -9225 -9226 -9227 -9228 -9229 -9230 -9231 -9232 -9233 -9234 -9235 -9236 -9237 -9238 -9239 -9240 -9241 -9242 -9243 -9244 -9245 -9246 -9247 -9248 -9249 -9250 -9251 -9252 -9253 -9254 -9255 -9256 -9257 -9258 -9259 -9260 -9261 -9262 -9263 -9264 -9265 -9266 -9267 -9268 -9269 -9270 -9271 -9272 -9273 -9274 -9275 -9276 -9277 -9278 -9279 -9280 -9281 -9282 -9283 -9284 -9285 -9286 -9287 -9288 -9289 -9290 -9291 -9292 -9293 -9294 -9295 -9296 -9297 -9298 -9299 -9300 -9301 -9302 -9303 -9304 -9305 -9306 -9307 -9308 -9309 -9310 -9311 -9312 -9313 -9314 -9315 -9316 -9317 -9318 -9319 -9320 -9321 -9322 -9323 -9324 -9325 -9326 -9327 -9328 -9329 -9330 -9331 -9332 -9333 -9334 -9335 -9336 -9337 -9338 -9339 -9340 -9341 -9342 -9343 -9344 -9345 -9346 -9347 -9348 -9349 -9350 -9351 -9352 -9353 -9354 -9355 -9356 -9357 -9358 -9359 -9360 -9361 -9362 -9363 -9364 -9365 -9366 -9367 -9368 -9369 -9370 -9371 -9372 -9373 -9374 -9375 -9376 -9377 -9378 -9379 -9380 -9381 -9382 -9383 -9384 -9385 -9386 -9387 -9388 -9389 -9390 -9391 -9392 -9393 -9394 -9395 -9396 -9397 -9398 -9399 -9400 -9401 -9402 -9403 -9404 -9405 -9406 -9407 -9408 -9409 -9410 -9411 -9412 -9413 -9414 -9415 -9416 -9417 -9418 -9419 -9420 -9421 -9422 -9423 -9424 -9425 -9426 -9427 -9428 -9429 -9430 -9431 -9432 -9433 -9434 -9435 -9436 -9437 -9438 -9439 -9440 -9441 -9442 -9443 -9444 -9445 -9446 -9447 -9448 -9449 -9450 -9451 -9452 -9453 -9454 -9455 -9456 -9457 -9458 -9459 -9460 -9461 -9462 -9463 -9464 -9465 -9466 -9467 -9468 -9469 -9470 -9471 -9472 -9473 -9474 -9475 -9476 -9477 -9478 -9479 -9480 -9481 -9482 -9483 -9484 -9485 -9486 -9487 -9488 -9489 -9490 -9491 -9492 -9493 -9494 -9495 -9496 -9497 -9498 -9499 -9500 -9501 -9502 -9503 -9504 -9505 -9506 -9507 -9508 -9509 -9510 -9511 -9512 -9513 -9514 -9515 -9516 -9517 -9518 -9519 -9520 -9521 -9522 -9523 -9524 -9525 -9526 -9527 -9528 -9529 -9530 -9531 -9532 -9533 -9534 -9535 -9536 -9537 -9538 -9539 -9540 -9541 -9542 -9543 -9544 -9545 -9546 -9547 -9548 -9549 -9550 -9551 -9552 -9553 -9554 -9555 -9556 -9557 -9558 -9559 -9560 -9561 -9562 -9563 -9564 -9565 -9566 -9567 -9568 -9569 -9570 -9571 -9572 -9573 -9574 -9575 -9576 -9577 -9578 -9579 -9580 -9581 -9582 -9583 -9584 -9585 -9586 -9587 -9588 -9589 -9590 -9591 -9592 -9593 -9594 -9595 -9596 -9597 -9598 -9599 -9600 -9601 -9602 -9603 -9604 -9605 -9606 -9607 -9608 -9609 -9610 -9611 -9612 -9613 -9614 -9615 -9616 -9617 -9618 -9619 -9620 -9621 -9622 -9623 -9624 -9625 -9626 -9627 -9628 -9629 -9630 -9631 -9632 -9633 -9634 -9635 -9636 -9637 -9638 -9639 -9640 -9641 -9642 -9643 -9644 -9645 -9646 -9647 -9648 -9649 -9650 -9651 -9652 -9653 -9654 -9655 -9656 -9657 -9658 -9659 -9660 -9661 -9662 -9663 -9664 -9665 -9666 -9667 -9668 -9669 -9670 -9671 -9672 -9673 -9674 -9675 -9676 -9677 -9678 -9679 -9680 -9681 -9682 -9683 -9684 -9685 -9686 -9687 -9688 -9689 -9690 -9691 -9692 -9693 -9694 -9695 -9696 -9697 -9698 -9699 -9700 -9701 -9702 -9703 -9704 -9705 -9706 -9707 -9708 -9709 -9710 -9711 -9712 -9713 -9714 -9715 -9716 -9717 -9718 -9719 -9720 -9721 -9722 -9723 -9724 -9725 -9726 -9727 -9728 -9729 -9730 -9731 -9732 -9733 -9734 -9735 -9736 -9737 -9738 -9739 -9740 -9741 -9742 -9743 -9744 -9745 -9746 -9747 -9748 -9749 -9750 -9751 -9752 -9753 -9754 -9755 -9756 -9757 -9758 -9759 -9760 -9761 -9762 -9763 -9764 -9765 -9766 -9767 -9768 -9769 -9770 -9771 -9772 -9773 -9774 -9775 -9776 -9777 -9778 -9779 -9780 -9781 -9782 -9783 -9784 -9785 -9786 -9787 -9788 -9789 -9790 -9791 -9792 -9793 -9794 -9795 -9796 -9797 -9798 -9799 -9800 -9801 -9802 -9803 -9804 -9805 -9806 -9807 -9808 -9809 -9810 -9811 -9812 -9813 -9814 -9815 -9816 -9817 -9818 -9819 -9820 -9821 -9822 -9823 -9824 -9825 -9826 -9827 -9828 -9829 -9830 -9831 -9832 -9833 -9834 -9835 -9836 -9837 -9838 -9839 -9840 -9841 -9842 -9843 -9844 -9845 -9846 -9847 -9848 -9849 -9850 -9851 -9852 -9853 -9854 -9855 -9856 -9857 -9858 -9859 -9860 -9861 -9862 -9863 -9864 -9865 -9866 -9867 -9868 -9869 -9870 -9871 -9872 -9873 -9874 -9875 -9876 -9877 -9878 -9879 -9880 -9881 -9882 -9883 -9884 -9885 -9886 -9887 -9888 -9889 -9890 -9891 -9892 -9893 -9894 -9895 -9896 -9897 -9898 -9899 -9900 -9901 -9902 -9903 -9904 -9905 -9906 -9907 -9908 -9909 -9910 -9911 -9912 -9913 -9914 -9915 -9916 -9917 -9918 -9919 -9920 -9921 -9922 -9923 -9924 -9925 -9926 -9927 -9928 -9929 -9930 -9931 -9932 -9933 -9934 -9935 -9936 -9937 -9938 -9939 -9940 -9941 -9942 -9943 -9944 -9945 -9946 -9947 -9948 -9949 -9950 -9951 -9952 -9953 -9954 -9955 -9956 -9957 -9958 -9959 -9960 -9961 -9962 -9963 -9964 -9965 -9966 -9967 -9968 -9969 -9970 -9971 -9972 -9973 -9974 -9975 -9976 -9977 -9978 -9979 -9980 -9981 -9982 -9983 -9984 -9985 -9986 -9987 -9988 -9989 -9990 -9991 -9992 -9993 -9994 -9995 -9996 -9997 -9998 -9999 diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml index ba50391048..cd5c87d44e 100644 --- a/core-java-modules/core-java-nio-2/pom.xml +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -14,22 +14,5 @@ 0.0.1-SNAPSHOT ../../parent-java - - - - - com.github.jnr - jnr-ffi - 2.1.11 - - - - - com.github.jnr - jnr-constants - 0.9.14 - - - \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java index 5363ba56e1..9d7c84b529 100644 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java @@ -1,105 +1,233 @@ package com.baeldung.lock; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; -import java.nio.charset.StandardCharsets; +import java.nio.channels.NonReadableChannelException; +import java.nio.channels.NonWritableChannelException; +import java.nio.channels.OverlappingFileLockException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; -import jnr.ffi.LibraryLoader; -import jnr.ffi.Memory; -import jnr.ffi.Pointer; -import jnr.ffi.types.pid_t; +import com.google.common.base.Charsets; public class FileLocks { - public static interface LibC { - - public static final int O_NONBLOCK = jnr.constants.platform.OpenFlags.O_NONBLOCK.intValue(); - public static final int O_RDWR = jnr.constants.platform.OpenFlags.O_RDWR.intValue(); - public static final int O_EXLOCK = jnr.constants.platform.OpenFlags.O_EXLOCK.intValue(); - - public long write(int fd, Pointer data, long len); - - @pid_t - long getpid(); - - int open(String filename, int flags); - - int close(int fd); + // Write locks + /** + * Trying to get an exclusive lock on a read-only FileChannel won't work. + */ + static void getExclusiveLockFromInputStream() throws IOException, NonWritableChannelException { + Path path = Files.createTempFile("foo", "txt"); + try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) { + System.out.println("This won't happen"); + } catch (NonWritableChannelException e) { + System.err.println( + "The channel obtained through a FileInputStream isn't writable. " + + "You can't obtain an exclusive lock on it!"); + throw e; + } } - public static void main(String[] args) throws IOException, InterruptedException { - - Path path = Paths.get("/tmp/foo"); - - // Delete the file if it exists - Files.deleteIfExists(path); - - // Start with a fresh empty file - Files.createFile(path); - - // Prepare some external libc calls. Will only work on systems that have libc. - LibC libc = LibraryLoader.create(LibC.class).load("c"); - byte[] bytes = "Hello from C\n".getBytes("UTF-8"); - jnr.ffi.Runtime runtime = jnr.ffi.Runtime.getRuntime(libc); - Pointer buffer = Memory.allocateDirect(runtime, bytes.length); - buffer.put(0, bytes, 0, bytes.length); - - // Open the file through a libc call. This returns a file descriptor. - int fd = libc.open(path.toString(), libc.O_RDWR + libc.O_EXLOCK + libc.O_NONBLOCK); - System.out.println("Opened the file through a libc call that locks it."); - - // Our java method will see the lock. Itd will be well behaved and won't write to the file. - // Note that external processes on POSIX systems would still be able to write to this file ignoring any locks. - writeToRandomAccessFile(path, "I won't write this", 0L); - - // Libc opened the file, it can write to its corresponding file handle. - libc.write(fd, buffer, bytes.length); - - // Now let's close the file through a libc call, to release its lock. - libc.close(fd); - System.out.println("Invoked libc's close() method"); - - // This time our method won't see the lock and will write to the file. - writeToRandomAccessFile(path, "Hello from java", bytes.length); - - System.out.println("Now that all the locks are gone, here are the file contents:"); - System.out.println("------------------------------------------------------------"); - Files.lines(path).forEach(System.out::println); - + + /** + * Getting an exclusive lock from a RandomAccessFile works if the file is in write mode. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return + * @throws IOException + */ + static FileLock getExclusiveLockFromRandomAccessFile(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); + FileLock lock = file.getChannel().lock(from, size, false)) { + if (lock.isValid()) { + System.out.println("This is a valid exclusive lock"); + return lock; + } + return null; + } catch (Exception e) { + System.out.println(e.getMessage()); + } + return null; } - public static RandomAccessFile writeToRandomAccessFile(Path path, String data, long position) { - RandomAccessFile file = null; - try { - file = new RandomAccessFile(path.toFile(), "rws"); - FileChannel channel = file.getChannel(); - // Try to acquire a lock - try (FileLock lock = channel.tryLock()) { - if (lock == null) { - System.out.println("Tried to lock through the FileChannel's lock() method. This file is already locked! It's my responsibility to not write to it, even if the OS would let me!"); - } else { - System.out.println("I don't see a lock on this file anymore. Now I can write to it."); - int i = 0; - channel.write( - ByteBuffer.wrap((data).getBytes(StandardCharsets.UTF_8)), position); - } - } catch (Exception e) { - System.out.println("Error while locking"); + /** + * Getting a write lock on a file region + */ + static FileLock getExclusiveLockFromFileChannelOpen(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND); + FileLock lock = channel.lock(from, size, false)) { + String text = "Hello, world."; + ByteBuffer buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); + buffer.put((text + System.lineSeparator()).getBytes(Charsets.UTF_8)); + buffer.flip(); + while (buffer.hasRemaining()) { + channel.write(buffer, channel.size()); + } + System.out.println("This was written to the file"); + Files.lines(path).forEach(System.out::println); + return lock; + } + } + + // Read locks + /** + * Trying to get a shared lock on a write-only FileChannel won't work. + */ + static void getReadLockFromOutputStream(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileOutputStream fis = new FileOutputStream(path.toFile()); + FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) { + System.out.println("This won't happen"); + } catch (NonReadableChannelException e) { + System.err.println( + "The channel obtained through a FileOutputStream isn't readable. " + + "You can't obtain an shared lock on it!"); + throw e; + } + } + + /** + * Locking a file for reading doesn't require a writable FileChannel. + * + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return + * @throws IOException + */ + static FileLock getReadLockFromInputStream(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileInputStream fis = new FileInputStream(path.toFile()); + FileLock lock = fis.getChannel().lock(from, size, true)) { + if (lock.isValid()) { + System.out.println("This is a valid shared lock"); + return lock; + } + return null; + } + } + + + /** + * Getting an exclusive lock from a RandomAccessFile works if the file is in read mode. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return + * @throws IOException + */ + static FileLock getReadLockFromRandomAccessFile(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "r"); // could also be "rw", but "r" is sufficient for reading + FileLock lock = file.getChannel().lock(from, size, true)) { + if (lock.isValid()) { + System.out.println("This is a valid shared lock"); + return lock; + } + return null; + } catch (Exception e) { + System.out.println(e.getMessage()); + } + return null; + } + + + + static class Writer implements Runnable { + + private Path path; + + private volatile RandomAccessFile file; + + private String text; + + private volatile CountDownLatch countDownLatch; + + /** + * + * @param path The path to the file we will write into + * @param text The text to write + * @param countDownLatch A counter for thread synchronization + * + */ + public Writer(Path path, String text, CountDownLatch countDownLatch) { + this.path = path; + this.text = text; + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + lockAndWrite(); + } catch (InterruptedException | FileNotFoundException e) { + // TODO Auto-generated catch block e.printStackTrace(); } - } catch (Exception e) { - System.out.println("Other Error."); - e.printStackTrace(); + countDownLatch.countDown(); } - return file; - } - - + private void lockAndWrite() throws InterruptedException, FileNotFoundException { + ByteBuffer buffer = null; + if (file == null) { + file = new RandomAccessFile(path.toFile(), "rw"); + } + try (FileChannel channel = file.getChannel()) { + + try (FileLock lock = channel.tryLock(channel.size(), + channel.size() + text.length() + System.lineSeparator().length(), true)) { + if (lock != null) { + String text = "Hello, world."; + buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); + buffer.put((text + System.lineSeparator()).getBytes(Charsets.UTF_8)); + buffer.flip(); + while (buffer.hasRemaining()) { + channel.write(buffer, channel.size()); + } + } + } catch (OverlappingFileLockException e) { + // Failed to lock. Try again later. + Thread.sleep(50); + lockAndWrite(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + + public static void main(String[] args) throws InterruptedException, IOException { + Path path = Paths.get("/tmp/foo"); + Files.deleteIfExists(path); + Files.createFile(path); + int concurrentWriters = 5; + CountDownLatch countDownLatch = new CountDownLatch(concurrentWriters); + // Launch 10 writers in parallel + final AtomicInteger count = new AtomicInteger(0); + Stream.generate(() -> new Thread(new Writer(path, "foo " + count.incrementAndGet(), countDownLatch))) + .limit(concurrentWriters).forEach(Thread::start); + + countDownLatch.await(); + AtomicInteger lineCount = new AtomicInteger(0); + Files.lines(path).forEach((line) -> { + lineCount.incrementAndGet(); + System.out.println(line); + }); + System.out.println("Total lines written = " + lineCount.get()); + + } } diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h deleted file mode 100644 index b227cb0c79..0000000000 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/com_baeldung_lock_FileLocks.h +++ /dev/null @@ -1,21 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class com_baeldung_lock_FileLocks */ - -#ifndef _Included_com_baeldung_lock_FileLocks -#define _Included_com_baeldung_lock_FileLocks -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: com_baeldung_lock_FileLocks - * Method: getpid - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_com_baeldung_lock_FileLocks_getpid - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java new file mode 100644 index 0000000000..4d9fbadaca --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java @@ -0,0 +1,78 @@ +package com.baeldung.lock; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.channels.FileLock; +import java.nio.channels.NonReadableChannelException; +import java.nio.channels.NonWritableChannelException; + +import org.junit.jupiter.api.Test; + +class FileLocksTest { + + // Exclusive locks + /** + * Getting an exclusive (write) lock on the entire file. + * Fails when getting the lock from a FileChannel obtained through a FileInputStream. + */ + @Test + void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { + assertThrows(NonWritableChannelException.class, + () -> FileLocks.getExclusiveLockFromInputStream()); + } + + /** + * Getting and exclusive lock from a RandomAccessFile + * @throws IOException + */ + @Test + void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { + FileLock lock = FileLocks.getExclusiveLockFromRandomAccessFile(0, 10); + assertNotNull(lock); + assertFalse(lock.isShared()); + } + + /** + * Getting an exclusive lock from FileChannel::open + * @throws IOException + */ + @Test + void givenAPath_whenGetExclusiveLock_lock() throws IOException { + FileLock lock = FileLocks.getExclusiveLockFromFileChannelOpen(0, 10); + assertNotNull(lock); + assertFalse(lock.isShared()); + } + + + /** + * Getting a shared (read) lock works fine when getting the lock from a FileChannel obtained through a FileInputStream. + * @throws IOException + */ + @Test + void givenAnInputStream_whenGetSharedLock_lock() throws IOException { + FileLock lock = FileLocks.getReadLockFromInputStream(0, 10); + assertNotNull(lock); + assertTrue(lock.isShared()); + + } + + + @Test + void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { + assertThrows(NonReadableChannelException.class, + () -> FileLocks.getReadLockFromOutputStream(0, 10)); + } + + @Test + void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { + FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); + assertNotNull(lock); + assertTrue(lock.isShared()); + + } + +} From 8c3099d7123926eb137b73bb3b2b39dec480b05a Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Sun, 12 Jan 2020 17:31:59 -0500 Subject: [PATCH 07/62] Added comments on unit tests. --- .../java/com/baeldung/lock/FileLocksTest.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java index 4d9fbadaca..ff20dd61b1 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java @@ -26,7 +26,7 @@ class FileLocksTest { } /** - * Getting and exclusive lock from a RandomAccessFile + * Getting an exclusive lock from a RandomAccessFile * @throws IOException */ @Test @@ -48,6 +48,18 @@ class FileLocksTest { } + // Shared locks + + /** + * Getting a shared (read) lock on the entire file. + * Fails when getting the lock from a FileChannel obtained through a FileOutputStream. + */ + @Test + void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { + assertThrows(NonReadableChannelException.class, + () -> FileLocks.getReadLockFromOutputStream(0, 10)); + } + /** * Getting a shared (read) lock works fine when getting the lock from a FileChannel obtained through a FileInputStream. * @throws IOException @@ -60,13 +72,10 @@ class FileLocksTest { } - - @Test - void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { - assertThrows(NonReadableChannelException.class, - () -> FileLocks.getReadLockFromOutputStream(0, 10)); - } - + /** + * Getting a shared lock from a RandomAccessFile + * @throws IOException + */ @Test void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); From b7e3f148a7c528a195ff5feb10259329093edb92 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Sat, 25 Jan 2020 17:39:29 -0500 Subject: [PATCH 08/62] Replaced println commands by proper logging --- .../java/com/baeldung/lock/FileLocks.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java index 9d7c84b529..42067f541c 100644 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java @@ -19,9 +19,15 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.base.Charsets; + public class FileLocks { + + private static Logger log = LoggerFactory.getLogger(FileLocks.class); // Write locks /** @@ -30,9 +36,9 @@ public class FileLocks { static void getExclusiveLockFromInputStream() throws IOException, NonWritableChannelException { Path path = Files.createTempFile("foo", "txt"); try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) { - System.out.println("This won't happen"); + log.debug("This won't happen"); } catch (NonWritableChannelException e) { - System.err.println( + log.error( "The channel obtained through a FileInputStream isn't writable. " + "You can't obtain an exclusive lock on it!"); throw e; @@ -52,7 +58,7 @@ public class FileLocks { try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); FileLock lock = file.getChannel().lock(from, size, false)) { if (lock.isValid()) { - System.out.println("This is a valid exclusive lock"); + log.debug("This is a valid exclusive lock"); return lock; } return null; @@ -76,7 +82,7 @@ public class FileLocks { while (buffer.hasRemaining()) { channel.write(buffer, channel.size()); } - System.out.println("This was written to the file"); + log.debug("This was written to the file"); Files.lines(path).forEach(System.out::println); return lock; } @@ -90,9 +96,9 @@ public class FileLocks { Path path = Files.createTempFile("foo", "txt"); try (FileOutputStream fis = new FileOutputStream(path.toFile()); FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) { - System.out.println("This won't happen"); + log.debug("This won't happen"); } catch (NonReadableChannelException e) { - System.err.println( + log.error( "The channel obtained through a FileOutputStream isn't readable. " + "You can't obtain an shared lock on it!"); throw e; @@ -112,7 +118,7 @@ public class FileLocks { try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock(from, size, true)) { if (lock.isValid()) { - System.out.println("This is a valid shared lock"); + log.debug("This is a valid shared lock"); return lock; } return null; @@ -132,12 +138,12 @@ public class FileLocks { try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "r"); // could also be "rw", but "r" is sufficient for reading FileLock lock = file.getChannel().lock(from, size, true)) { if (lock.isValid()) { - System.out.println("This is a valid shared lock"); + log.debug("This is a valid shared lock"); return lock; } return null; } catch (Exception e) { - System.out.println(e.getMessage()); + log.error(e.getMessage()); } return null; } @@ -227,7 +233,7 @@ public class FileLocks { lineCount.incrementAndGet(); System.out.println(line); }); - System.out.println("Total lines written = " + lineCount.get()); + log.info("Total lines written = " + lineCount.get()); } } From 9cbafc45df540b38501f9dc045d786f3d1410ccc Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Tue, 28 Jan 2020 11:34:42 +0200 Subject: [PATCH 09/62] Initial commit --- jcabi/pom.xml | 81 ++++++++++++++ .../com/baeldung/jcabi_aspectj/Example.java | 103 ++++++++++++++++++ .../java/com/baeldung/jcabi_aspectj/User.java | 5 + 3 files changed, 189 insertions(+) create mode 100644 jcabi/pom.xml create mode 100644 jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java create mode 100644 jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java diff --git a/jcabi/pom.xml b/jcabi/pom.xml new file mode 100644 index 0000000000..7fb9c313c5 --- /dev/null +++ b/jcabi/pom.xml @@ -0,0 +1,81 @@ + + + + 4.0.0 + jcabi + 0.1.0-SNAPSHOT + jcabi + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + com.jcabi + jcabi-aspects + ${jcabi-aspects.version} + + + + org.aspectj + aspectjrt + ${aspectjrt.version} + runtime + + + + + + jcabi + + + com.jcabi + jcabi-maven-plugin + ${jcabi-maven-plugin.version} + + + + ajc + + + + + + org.aspectj + aspectjtools + ${aspectjtools.version} + + + org.aspectj + aspectjweaver + ${aspectjweaver.version} + + + + + + + + 3.14.0 + 0.22.6 + 1.9.5 + 0.14.1 + 1.9.1 + 1.9.1 + + + diff --git a/jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java b/jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java new file mode 100644 index 0000000000..0c688ceb22 --- /dev/null +++ b/jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java @@ -0,0 +1,103 @@ +package com.baeldung.jcabi_aspectj; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import com.jcabi.aspects.Async; +import com.jcabi.aspects.Cacheable; +import com.jcabi.aspects.LogExceptions; +import com.jcabi.aspects.Loggable; +import com.jcabi.aspects.Parallel; +import com.jcabi.aspects.Quietly; +import com.jcabi.aspects.RetryOnFailure; +import com.jcabi.aspects.UnitedThrow; + +//@Loggable +public class Example { + + public static void main(String[] args) { + try { + tryAsync(); + asyncFactorial(10).get(); + System.out.println("calling 2..."); + System.out.println(called2()); + //called3(); + called4(); + System.out.println(called2()); + System.out.println(called2()); + called6(); + //called7(); + + + } catch(Exception e) { + + } + called5(); + called8(); + } + + @Async + public static void tryAsync() { + long result = factorial(10); + System.out.println(result); + } + + @Async + public static Future asyncFactorial(int number) { + Future factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number)); + return factorialFuture; + } + + /** + * Finds factorial of a number + * @param number + * @return + */ + public static long factorial(int number) { + long result = 1; + for(int i=number;i>0;i--) { + result *= i; + } + return result; + } + + @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS) + public static Double called2() { + return Math.random(); + } + + @LogExceptions + public static void called3() { + System.out.println(1/0); + } + + @Loggable + public static void called4() { + System.out.println("checking loggable"); + } + + @Quietly + public static void called5() { + int x = 1/0; + } + + @Parallel(threads = 4) + public static void called6() { + System.out.println("called6"); + } + + @RetryOnFailure + //@Quietly + public static void called7() { + System.out.println("called7..."); + int y = 1/0; + } + + @UnitedThrow //(IllegalStateException.class) + public static void called8() { + System.out.println("called8..."); + int y = 1/0; + } + +} diff --git a/jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java b/jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java new file mode 100644 index 0000000000..c918f8471c --- /dev/null +++ b/jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java @@ -0,0 +1,5 @@ +package com.baeldung.jcabi_aspectj; + +public class User { + +} From d40a5c1194febf0f7ab17a96007d079e750889db Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Sat, 8 Feb 2020 18:39:39 +0200 Subject: [PATCH 10/62] BAEL-3758 - AOP annotations of jcabi-aspects --- .../{jcabi_aspectj/Example.java => jcabi/JcabiAspectJ.java} | 0 .../src/main/java/com/baeldung/{jcabi_aspectj => jcabi}/User.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename jcabi/src/main/java/com/baeldung/{jcabi_aspectj/Example.java => jcabi/JcabiAspectJ.java} (100%) rename jcabi/src/main/java/com/baeldung/{jcabi_aspectj => jcabi}/User.java (100%) diff --git a/jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java similarity index 100% rename from jcabi/src/main/java/com/baeldung/jcabi_aspectj/Example.java rename to jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java diff --git a/jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java b/jcabi/src/main/java/com/baeldung/jcabi/User.java similarity index 100% rename from jcabi/src/main/java/com/baeldung/jcabi_aspectj/User.java rename to jcabi/src/main/java/com/baeldung/jcabi/User.java From 9ab42e61187e6a1b15e66bbe80b44905e5141b93 Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Sat, 8 Feb 2020 18:40:16 +0200 Subject: [PATCH 11/62] BAEL-3758 - AOP annotations of jcabi-aspects --- jcabi/pom.xml | 7 -- .../java/com/baeldung/jcabi/JcabiAspectJ.java | 86 ++++++++----------- .../main/java/com/baeldung/jcabi/User.java | 5 -- 3 files changed, 37 insertions(+), 61 deletions(-) delete mode 100644 jcabi/src/main/java/com/baeldung/jcabi/User.java diff --git a/jcabi/pom.xml b/jcabi/pom.xml index 7fb9c313c5..bf53f74bcd 100644 --- a/jcabi/pom.xml +++ b/jcabi/pom.xml @@ -17,12 +17,6 @@ - - org.assertj - assertj-core - ${assertj.version} - test - com.jcabi @@ -70,7 +64,6 @@ - 3.14.0 0.22.6 1.9.5 0.14.1 diff --git a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java index 0c688ceb22..1bfecd6c52 100644 --- a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java +++ b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java @@ -1,4 +1,5 @@ -package com.baeldung.jcabi_aspectj; +package com.baeldung.jcabi; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @@ -11,40 +12,42 @@ import com.jcabi.aspects.Loggable; import com.jcabi.aspects.Parallel; import com.jcabi.aspects.Quietly; import com.jcabi.aspects.RetryOnFailure; +import com.jcabi.aspects.Timeable; import com.jcabi.aspects.UnitedThrow; -//@Loggable -public class Example { +public class JcabiAspectJ { public static void main(String[] args) { try { - tryAsync(); - asyncFactorial(10).get(); - System.out.println("calling 2..."); - System.out.println(called2()); - //called3(); - called4(); - System.out.println(called2()); - System.out.println(called2()); - called6(); - //called7(); + displayFactorial(10); + getFactorial(10).get(); + Double number = cacheRandomNumber(); + if (number != cacheRandomNumber()) { + System.out.println(number); + } + + divideByZero(); } catch(Exception e) { - + e.printStackTrace(); } - called5(); - called8(); + + divideByZeroQuietly(); + parallelExecution(); + } + @Loggable @Async - public static void tryAsync() { - long result = factorial(10); + public static void displayFactorial(int number) { + long result = factorial(number); System.out.println(result); } + @Loggable @Async - public static Future asyncFactorial(int number) { + public static Future getFactorial(int number) { Future factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number)); return factorialFuture; } @@ -62,42 +65,27 @@ public class Example { return result; } - @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS) - public static Double called2() { + @Loggable + @Cacheable(lifetime = 2, unit = TimeUnit.SECONDS) + public static Double cacheRandomNumber() { return Math.random(); } - + + @UnitedThrow(IllegalStateException.class) @LogExceptions - public static void called3() { - System.out.println(1/0); - } - - @Loggable - public static void called4() { - System.out.println("checking loggable"); - } - - @Quietly - public static void called5() { + public static void divideByZero() { int x = 1/0; } - + + @RetryOnFailure(attempts = 2, types = {java.lang.NumberFormatException.class}) + @Quietly + public static void divideByZeroQuietly() { + int x = 1/0; + } + @Parallel(threads = 4) - public static void called6() { - System.out.println("called6"); - } - - @RetryOnFailure - //@Quietly - public static void called7() { - System.out.println("called7..."); - int y = 1/0; - } - - @UnitedThrow //(IllegalStateException.class) - public static void called8() { - System.out.println("called8..."); - int y = 1/0; + public static void parallelExecution() { + System.out.println("Calling Parallel..."); } } diff --git a/jcabi/src/main/java/com/baeldung/jcabi/User.java b/jcabi/src/main/java/com/baeldung/jcabi/User.java deleted file mode 100644 index c918f8471c..0000000000 --- a/jcabi/src/main/java/com/baeldung/jcabi/User.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.jcabi_aspectj; - -public class User { - -} From e138f5209c33eff17ad32574524ea1861b6b3016 Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Sat, 8 Feb 2020 19:10:10 +0200 Subject: [PATCH 12/62] BAEL-3758 - AOP Annotations of jcabi-aspects --- jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java | 5 +---- pom.xml | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java index 1bfecd6c52..c88ad5a74d 100644 --- a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java +++ b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java @@ -12,7 +12,6 @@ import com.jcabi.aspects.Loggable; import com.jcabi.aspects.Parallel; import com.jcabi.aspects.Quietly; import com.jcabi.aspects.RetryOnFailure; -import com.jcabi.aspects.Timeable; import com.jcabi.aspects.UnitedThrow; public class JcabiAspectJ { @@ -28,14 +27,12 @@ public class JcabiAspectJ { } divideByZero(); - } catch(Exception e) { e.printStackTrace(); } divideByZeroQuietly(); - parallelExecution(); - + parallelExecution(); } @Loggable diff --git a/pom.xml b/pom.xml index aeaef5f676..177792f3b8 100644 --- a/pom.xml +++ b/pom.xml @@ -470,6 +470,7 @@ javax-servlets javaxval jaxb + jcabi jee-7 jee-7-security jee-kotlin @@ -1019,6 +1020,7 @@ javax-servlets javaxval jaxb + jcabi jee-7 jee-7-security jee-kotlin From 696e4943df052eb49a6836fc660ebabd5d458ea3 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Sun, 9 Feb 2020 00:49:26 -0500 Subject: [PATCH 13/62] [BAEL-3601] - Fix code review comments. --- core-java-modules/core-java-nio-2/README.md | 3 +- .../java/com/baeldung/lock/FileLocks.java | 314 ++++++------------ .../java/com/baeldung/lock/FileLocksTest.java | 87 ----- .../com/baeldung/lock/FileLocksUnitTest.java | 48 +++ .../design-patterns-architectural/README.md | 1 - .../baeldung/hexagonal/ChatApplication.java | 45 --- .../adapters/DisplayInConsoleAdapter.java | 36 -- .../adapters/InMemoryMessageStore.java | 37 --- .../hexagonal/application/ChatManager.java | 27 -- .../hexagonal/domain/ChatMessage.java | 34 -- .../baeldung/hexagonal/domain/ChatUser.java | 14 - .../hexagonal/domain/IDisplayMessages.java | 8 - .../hexagonal/domain/ISendMessage.java | 8 - .../hexagonal/domain/IStoreMessages.java | 14 - 14 files changed, 156 insertions(+), 520 deletions(-) delete mode 100644 core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java create mode 100644 core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java delete mode 100644 patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index 1d879b3c5b..8950f650e6 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -8,5 +8,4 @@ This module contains articles about core Java non-blocking input and output (IO) - [Create a Symbolic Link with Java](https://www.baeldung.com/java-symlink) - [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector) - [Using Java MappedByteBuffer](https://www.baeldung.com/java-mapped-byte-buffer) -- [How to Lock a File in Java](https://www.baeldung.com/how-to-lock-a-file-in-java) -- [[<-- Prev]](/core-java-modules/core-java-nio) \ No newline at end of file +- [[<-- Prev]](/core-java-modules/core-java-nio) diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java index 42067f541c..4e79bdf4eb 100644 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java @@ -1,7 +1,6 @@ package com.baeldung.lock; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; @@ -10,230 +9,131 @@ import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.channels.NonReadableChannelException; import java.nio.channels.NonWritableChannelException; -import java.nio.channels.OverlappingFileLockException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardOpenOption; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Charsets; - public class FileLocks { - - private static Logger log = LoggerFactory.getLogger(FileLocks.class); - // Write locks - /** - * Trying to get an exclusive lock on a read-only FileChannel won't work. - */ - static void getExclusiveLockFromInputStream() throws IOException, NonWritableChannelException { - Path path = Files.createTempFile("foo", "txt"); - try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) { - log.debug("This won't happen"); - } catch (NonWritableChannelException e) { - log.error( - "The channel obtained through a FileInputStream isn't writable. " - + "You can't obtain an exclusive lock on it!"); - throw e; - } - } + private static final Logger LOG = LoggerFactory.getLogger(FileLocks.class); - - /** - * Getting an exclusive lock from a RandomAccessFile works if the file is in write mode. - * @param from beginning of the locked region - * @param size how many bytes to lock - * @return - * @throws IOException - */ - static FileLock getExclusiveLockFromRandomAccessFile(long from, long size) throws IOException { - Path path = Files.createTempFile("foo", "txt"); - try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); - FileLock lock = file.getChannel().lock(from, size, false)) { - if (lock.isValid()) { - log.debug("This is a valid exclusive lock"); - return lock; - } - return null; - } catch (Exception e) { - System.out.println(e.getMessage()); - } - return null; - } - - /** - * Getting a write lock on a file region - */ - static FileLock getExclusiveLockFromFileChannelOpen(long from, long size) throws IOException { - Path path = Files.createTempFile("foo", "txt"); - try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND); - FileLock lock = channel.lock(from, size, false)) { - String text = "Hello, world."; - ByteBuffer buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); - buffer.put((text + System.lineSeparator()).getBytes(Charsets.UTF_8)); - buffer.flip(); - while (buffer.hasRemaining()) { - channel.write(buffer, channel.size()); - } - log.debug("This was written to the file"); - Files.lines(path).forEach(System.out::println); - return lock; - } - } + // Write locks - // Read locks - /** - * Trying to get a shared lock on a write-only FileChannel won't work. - */ - static void getReadLockFromOutputStream(long from, long size) throws IOException { - Path path = Files.createTempFile("foo", "txt"); - try (FileOutputStream fis = new FileOutputStream(path.toFile()); - FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) { - log.debug("This won't happen"); - } catch (NonReadableChannelException e) { - log.error( - "The channel obtained through a FileOutputStream isn't readable. " - + "You can't obtain an shared lock on it!"); - throw e; - } - } - - /** - * Locking a file for reading doesn't require a writable FileChannel. - * - * @param from beginning of the locked region - * @param size how many bytes to lock - * @return - * @throws IOException - */ - static FileLock getReadLockFromInputStream(long from, long size) throws IOException { - Path path = Files.createTempFile("foo", "txt"); - try (FileInputStream fis = new FileInputStream(path.toFile()); - FileLock lock = fis.getChannel().lock(from, size, true)) { - if (lock.isValid()) { - log.debug("This is a valid shared lock"); - return lock; - } - return null; - } - } - - - /** - * Getting an exclusive lock from a RandomAccessFile works if the file is in read mode. - * @param from beginning of the locked region - * @param size how many bytes to lock - * @return - * @throws IOException - */ - static FileLock getReadLockFromRandomAccessFile(long from, long size) throws IOException { - Path path = Files.createTempFile("foo", "txt"); - try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "r"); // could also be "rw", but "r" is sufficient for reading - FileLock lock = file.getChannel().lock(from, size, true)) { - if (lock.isValid()) { - log.debug("This is a valid shared lock"); - return lock; - } - return null; - } catch (Exception e) { - log.error(e.getMessage()); - } - return null; - } + /** + * Trying to get an exclusive lock on a read-only FileChannel won't work. + */ + static void getExclusiveLockFromInputStream() throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) { + LOG.debug("This won't happen"); + } catch (NonWritableChannelException e) { + LOG.error("The channel obtained through a FileInputStream isn't writable. You can't obtain an exclusive lock on it!"); + throw e; + } + } - + /** + * Gets an exclusive lock from a RandomAccessFile. Works because the file is writable. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return A lock object representing the newly-acquired lock + * @throws IOException if there is a problem creating the temporary file + */ + static FileLock getExclusiveLockFromRandomAccessFile(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); FileLock lock = file.getChannel().lock(from, size, false)) { + if (lock.isValid()) { + LOG.debug("This is a valid exclusive lock"); + return lock; + } + return null; + } catch (Exception e) { + LOG.error(e.getMessage()); + } + return null; + } - static class Writer implements Runnable { + /** + * Acquires an exclusive lock on a file region. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return A lock object representing the newly-acquired lock + * @throws IOException if there is a problem creating the temporary file + */ + static FileLock getExclusiveLockFromFileChannelOpen(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND); FileLock lock = channel.lock(from, size, false)) { + String text = "Hello, world."; + ByteBuffer buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); + buffer.put((text + System.lineSeparator()).getBytes(StandardCharsets.UTF_8)); + buffer.flip(); + while (buffer.hasRemaining()) { + channel.write(buffer, channel.size()); + } + LOG.debug("This was written to the file"); + Files.lines(path).forEach(LOG::debug); + return lock; + } + } - private Path path; + // Read locks - private volatile RandomAccessFile file; + /** + * Trying to get a shared lock on a write-only FileChannel won't work. + */ + static void getReadLockFromOutputStream() throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileOutputStream fis = new FileOutputStream(path.toFile()); FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) { + LOG.debug("This won't happen"); + } catch (NonReadableChannelException e) { + LOG.error("The channel obtained through a FileOutputStream isn't readable. " + "You can't obtain an shared lock on it!"); + throw e; + } + } - private String text; + /** + * Gets a lock from an InputStream. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return A lock object representing the newly-acquired lock + * @throws IOException if there is a problem creating the temporary file + */ + static FileLock getReadLockFromInputStream(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock(from, size, true)) { + if (lock.isValid()) { + LOG.debug("This is a valid shared lock"); + return lock; + } + return null; + } + } - private volatile CountDownLatch countDownLatch; + /** + * Gets an exclusive lock from a RandomAccessFile. Works because the file is readable. + * @param from beginning of the locked region + * @param size how many bytes to lock + * @return A lock object representing the newly-acquired lock + * @throws IOException if there is a problem creating the temporary file + */ + static FileLock getReadLockFromRandomAccessFile(long from, long size) throws IOException { + Path path = Files.createTempFile("foo", "txt"); + try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "r"); // could also be "rw", but "r" is sufficient for reading + FileLock lock = file.getChannel().lock(from, size, true)) { + if (lock.isValid()) { + LOG.debug("This is a valid shared lock"); + return lock; + } + } catch (Exception e) { + LOG.error(e.getMessage()); + } + return null; + } - /** - * - * @param path The path to the file we will write into - * @param text The text to write - * @param countDownLatch A counter for thread synchronization - * - */ - public Writer(Path path, String text, CountDownLatch countDownLatch) { - this.path = path; - this.text = text; - this.countDownLatch = countDownLatch; - } - - @Override - public void run() { - try { - lockAndWrite(); - } catch (InterruptedException | FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - countDownLatch.countDown(); - } - - private void lockAndWrite() throws InterruptedException, FileNotFoundException { - ByteBuffer buffer = null; - if (file == null) { - file = new RandomAccessFile(path.toFile(), "rw"); - } - try (FileChannel channel = file.getChannel()) { - - try (FileLock lock = channel.tryLock(channel.size(), - channel.size() + text.length() + System.lineSeparator().length(), true)) { - if (lock != null) { - String text = "Hello, world."; - buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); - buffer.put((text + System.lineSeparator()).getBytes(Charsets.UTF_8)); - buffer.flip(); - while (buffer.hasRemaining()) { - channel.write(buffer, channel.size()); - } - } - } catch (OverlappingFileLockException e) { - // Failed to lock. Try again later. - Thread.sleep(50); - lockAndWrite(); - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - - } - - public static void main(String[] args) throws InterruptedException, IOException { - Path path = Paths.get("/tmp/foo"); - Files.deleteIfExists(path); - Files.createFile(path); - int concurrentWriters = 5; - CountDownLatch countDownLatch = new CountDownLatch(concurrentWriters); - // Launch 10 writers in parallel - final AtomicInteger count = new AtomicInteger(0); - Stream.generate(() -> new Thread(new Writer(path, "foo " + count.incrementAndGet(), countDownLatch))) - .limit(concurrentWriters).forEach(Thread::start); - - countDownLatch.await(); - AtomicInteger lineCount = new AtomicInteger(0); - Files.lines(path).forEach((line) -> { - lineCount.incrementAndGet(); - System.out.println(line); - }); - log.info("Total lines written = " + lineCount.get()); - - } } diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java deleted file mode 100644 index ff20dd61b1..0000000000 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.baeldung.lock; - -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.nio.channels.FileLock; -import java.nio.channels.NonReadableChannelException; -import java.nio.channels.NonWritableChannelException; - -import org.junit.jupiter.api.Test; - -class FileLocksTest { - - // Exclusive locks - /** - * Getting an exclusive (write) lock on the entire file. - * Fails when getting the lock from a FileChannel obtained through a FileInputStream. - */ - @Test - void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { - assertThrows(NonWritableChannelException.class, - () -> FileLocks.getExclusiveLockFromInputStream()); - } - - /** - * Getting an exclusive lock from a RandomAccessFile - * @throws IOException - */ - @Test - void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { - FileLock lock = FileLocks.getExclusiveLockFromRandomAccessFile(0, 10); - assertNotNull(lock); - assertFalse(lock.isShared()); - } - - /** - * Getting an exclusive lock from FileChannel::open - * @throws IOException - */ - @Test - void givenAPath_whenGetExclusiveLock_lock() throws IOException { - FileLock lock = FileLocks.getExclusiveLockFromFileChannelOpen(0, 10); - assertNotNull(lock); - assertFalse(lock.isShared()); - } - - - // Shared locks - - /** - * Getting a shared (read) lock on the entire file. - * Fails when getting the lock from a FileChannel obtained through a FileOutputStream. - */ - @Test - void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { - assertThrows(NonReadableChannelException.class, - () -> FileLocks.getReadLockFromOutputStream(0, 10)); - } - - /** - * Getting a shared (read) lock works fine when getting the lock from a FileChannel obtained through a FileInputStream. - * @throws IOException - */ - @Test - void givenAnInputStream_whenGetSharedLock_lock() throws IOException { - FileLock lock = FileLocks.getReadLockFromInputStream(0, 10); - assertNotNull(lock); - assertTrue(lock.isShared()); - - } - - /** - * Getting a shared lock from a RandomAccessFile - * @throws IOException - */ - @Test - void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { - FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); - assertNotNull(lock); - assertTrue(lock.isShared()); - - } - -} diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java new file mode 100644 index 0000000000..da4e321ebf --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.lock; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.channels.FileLock; +import java.nio.channels.NonReadableChannelException; +import java.nio.channels.NonWritableChannelException; + +import org.junit.jupiter.api.Test; + +class FileLocksUnitTest { + + @Test void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { + assertThrows(NonWritableChannelException.class, () -> FileLocks.getExclusiveLockFromInputStream()); + } + + @Test void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { + FileLock lock = FileLocks.getExclusiveLockFromRandomAccessFile(0, 10); + assertNotNull(lock); + assertFalse(lock.isShared()); + } + + @Test void givenAPath_whenGetExclusiveLock_lock() throws IOException { + FileLock lock = FileLocks.getExclusiveLockFromFileChannelOpen(0, 10); + assertNotNull(lock); + assertFalse(lock.isShared()); + } + + @Test void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { + assertThrows(NonReadableChannelException.class, FileLocks::getReadLockFromOutputStream); + } + + @Test void givenAnInputStream_whenGetSharedLock_lock() throws IOException { + FileLock lock = FileLocks.getReadLockFromInputStream(0, 10); + assertNotNull(lock); + assertTrue(lock.isShared()); + } + + @Test void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { + FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); + assertNotNull(lock); + assertTrue(lock.isShared()); + } +} diff --git a/patterns/design-patterns-architectural/README.md b/patterns/design-patterns-architectural/README.md index 7f3eea27af..fbe4221752 100644 --- a/patterns/design-patterns-architectural/README.md +++ b/patterns/design-patterns-architectural/README.md @@ -1,4 +1,3 @@ ### Relevant Articles: - [Service Locator Pattern](https://www.baeldung.com/java-service-locator-pattern) - [The DAO Pattern in Java](https://www.baeldung.com/java-dao-pattern) -- [A Practical Example of Hexagonal Architecture in Java](https://www.baeldung.com/java-hexagonal-pattern) diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java deleted file mode 100644 index 4e8cc457f7..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/ChatApplication.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.hexagonal; - -import com.baeldung.hexagonal.adapters.DisplayInConsoleAdapter; -import com.baeldung.hexagonal.adapters.InMemoryMessageStore; -import com.baeldung.hexagonal.application.ChatManager; -import com.baeldung.hexagonal.domain.ChatUser; -import com.baeldung.hexagonal.domain.IDisplayMessages; - -import java.util.ArrayDeque; -import java.util.Scanner; - -public class ChatApplication { - - public static void main(String[] args) { - Scanner console = new Scanner(System.in); - - System.out.print("Enter username of user 1: "); - ChatUser user1 = new ChatUser(console.nextLine()); - - System.out.printf("Enter username of user 2: "); - ChatUser user2 = new ChatUser(console.nextLine()); - - System.out.println("Chat will end when any user uses the word bye in a message."); - - InMemoryMessageStore messageStore = new InMemoryMessageStore(new ArrayDeque<>(10)); - IDisplayMessages messageDisplayer = new DisplayInConsoleAdapter(messageStore); - ChatManager chatManager = new ChatManager(messageStore, messageDisplayer); - - - while (true) { - System.out.printf("From %s to %s : ", user1, user2); - String message = console.nextLine(); - if (message.toLowerCase().contains("bye")) { - chatManager.sendMessage(user1, user2, message); - System.out.println("Chat recap:"); - messageDisplayer.displayMessages(); - System.exit(0); - } - chatManager.sendMessage(user1, user2, message); - ChatUser temp = user1; - user1 = user2; - user2 = temp; - } - } -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java deleted file mode 100644 index ea4982182b..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/DisplayInConsoleAdapter.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.hexagonal.adapters; - -import com.baeldung.hexagonal.domain.ChatMessage; -import com.baeldung.hexagonal.domain.IDisplayMessages; -import com.baeldung.hexagonal.domain.IStoreMessages; - -/** - * A Utility adapter to display the chat messages in the console - */ -public class DisplayInConsoleAdapter implements IDisplayMessages { - - IStoreMessages messageStore; - - public DisplayInConsoleAdapter(IStoreMessages messageStore) { - this.messageStore = messageStore; - } - - public static void clearScreen() { - System.out.print("\033[H\033[2J"); - System.out.flush(); - } - - @Override - public void displayMessages() { - clearScreen(); - for (ChatMessage message: messageStore.getMessages(10)) { - System.out.printf( - "%tF %tT [%s to %s]: %s %n", - message.getTimeSent(), - message.getTimeSent(), - message.getFrom(), - message.getTo(), - message.getContents()); - } - } -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java deleted file mode 100644 index 6c4c12eb6f..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/adapters/InMemoryMessageStore.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.hexagonal.adapters; - -import com.baeldung.hexagonal.domain.ChatMessage; -import com.baeldung.hexagonal.domain.IStoreMessages; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Queue; -import java.util.stream.Collectors; - -/** - * We're storing the messages in memory. We could later opt to switch to an implementation that stores messages in a - * database. - */ -public class InMemoryMessageStore implements IStoreMessages { - - private Queue messages; - - public InMemoryMessageStore(Queue messages) { - this.messages = messages; - } - - @Override - public void storeMessage(ChatMessage message) { - this.messages.add(message); - } - - @Override - public Collection getMessages(long maxNbMessages) {// @formatter:off - return messages.stream() - .sorted((m1, m2) -> m2.getTimeSent().compareTo(m1.getTimeSent())) - .limit(maxNbMessages) - .sorted(Comparator.comparing(ChatMessage::getTimeSent)) - .collect(Collectors.toList()); - // @formatter:on - } -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java deleted file mode 100644 index 3ec54f1354..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/application/ChatManager.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.hexagonal.application; - -import com.baeldung.hexagonal.domain.*; - -import java.time.LocalDateTime; - -public class ChatManager implements ISendMessage { - - // The domain doesn't need to know where messages will be stored - private IStoreMessages messageStore; - - // The domain doesn't need to know how messages will be displayed - private IDisplayMessages messageDisplayer; - - public ChatManager(IStoreMessages messageStore, IDisplayMessages displayMessages) { - this.messageStore = messageStore; - this.messageDisplayer = displayMessages; - } - - @Override - public void sendMessage(ChatUser from, ChatUser to, String message) { - ChatMessage chatMessage = new ChatMessage(LocalDateTime.now(), from, to, message); - this.messageStore.storeMessage(chatMessage); - this.messageDisplayer.displayMessages(); - } - -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java deleted file mode 100644 index 27db77a887..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatMessage.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import java.time.LocalDateTime; - -public class ChatMessage { - private LocalDateTime timeSent; - private ChatUser from; - private ChatUser to; - private String contents; - - public LocalDateTime getTimeSent() { - return timeSent; - } - - public ChatUser getFrom() { - return from; - } - - public ChatUser getTo() { - return to; - } - - public String getContents() { - return contents; - } - - public ChatMessage(LocalDateTime timeSent, ChatUser from, ChatUser to, String contents) { - this.timeSent = timeSent; - this.from = from; - this.to = to; - this.contents = contents; - } - -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java deleted file mode 100644 index e66e0c79e3..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ChatUser.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.hexagonal.domain; - -public class ChatUser { - private String name; - - public ChatUser(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java deleted file mode 100644 index beb7e71cff..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IDisplayMessages.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.domain; - -/** - * An external system displays the messages sent by users. - */ -public interface IDisplayMessages { - void displayMessages(); -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java deleted file mode 100644 index dcec7e033a..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/ISendMessage.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.hexagonal.domain; - -/** - * A user sends a message (application's use case) - */ -public interface ISendMessage { - void sendMessage(ChatUser from, ChatUser to, String message); -} diff --git a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java b/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java deleted file mode 100644 index fe6195bb67..0000000000 --- a/patterns/design-patterns-architectural/src/main/java/com/baeldung/hexagonal/domain/IStoreMessages.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.hexagonal.domain; - -import java.util.Collection; - -/** - * An external system (infrastructure) stores a message - */ -public interface IStoreMessages { - - void storeMessage(ChatMessage message); - - Collection getMessages(long maxNbMessages); - -} From f80e6c396a5c60f7b30014a9579b4696671bbe9a Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Sun, 9 Feb 2020 10:17:06 -0500 Subject: [PATCH 14/62] [BAEL-3601] - Reformatted code with eclipse. Removed unused imports. --- .../java/com/baeldung/lock/FileLocks.java | 33 ++++++++++++------- .../com/baeldung/lock/FileLocksUnitTest.java | 18 ++++++---- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java index 4e79bdf4eb..4b65221708 100644 --- a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/lock/FileLocks.java @@ -1,5 +1,8 @@ package com.baeldung.lock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -14,11 +17,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Charsets; - public class FileLocks { private static final Logger LOG = LoggerFactory.getLogger(FileLocks.class); @@ -30,7 +28,9 @@ public class FileLocks { */ static void getExclusiveLockFromInputStream() throws IOException { Path path = Files.createTempFile("foo", "txt"); - try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) { + try (FileInputStream fis = new FileInputStream(path.toFile()); + FileLock lock = fis.getChannel() + .lock()) { LOG.debug("This won't happen"); } catch (NonWritableChannelException e) { LOG.error("The channel obtained through a FileInputStream isn't writable. You can't obtain an exclusive lock on it!"); @@ -47,7 +47,9 @@ public class FileLocks { */ static FileLock getExclusiveLockFromRandomAccessFile(long from, long size) throws IOException { Path path = Files.createTempFile("foo", "txt"); - try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); FileLock lock = file.getChannel().lock(from, size, false)) { + try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "rw"); + FileLock lock = file.getChannel() + .lock(from, size, false)) { if (lock.isValid()) { LOG.debug("This is a valid exclusive lock"); return lock; @@ -70,14 +72,16 @@ public class FileLocks { Path path = Files.createTempFile("foo", "txt"); try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND); FileLock lock = channel.lock(from, size, false)) { String text = "Hello, world."; - ByteBuffer buffer = ByteBuffer.allocate(text.length() + System.lineSeparator().length()); + ByteBuffer buffer = ByteBuffer.allocate(text.length() + System.lineSeparator() + .length()); buffer.put((text + System.lineSeparator()).getBytes(StandardCharsets.UTF_8)); buffer.flip(); while (buffer.hasRemaining()) { channel.write(buffer, channel.size()); } LOG.debug("This was written to the file"); - Files.lines(path).forEach(LOG::debug); + Files.lines(path) + .forEach(LOG::debug); return lock; } } @@ -89,7 +93,9 @@ public class FileLocks { */ static void getReadLockFromOutputStream() throws IOException { Path path = Files.createTempFile("foo", "txt"); - try (FileOutputStream fis = new FileOutputStream(path.toFile()); FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) { + try (FileOutputStream fis = new FileOutputStream(path.toFile()); + FileLock lock = fis.getChannel() + .lock(0, Long.MAX_VALUE, true)) { LOG.debug("This won't happen"); } catch (NonReadableChannelException e) { LOG.error("The channel obtained through a FileOutputStream isn't readable. " + "You can't obtain an shared lock on it!"); @@ -106,7 +112,9 @@ public class FileLocks { */ static FileLock getReadLockFromInputStream(long from, long size) throws IOException { Path path = Files.createTempFile("foo", "txt"); - try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock(from, size, true)) { + try (FileInputStream fis = new FileInputStream(path.toFile()); + FileLock lock = fis.getChannel() + .lock(from, size, true)) { if (lock.isValid()) { LOG.debug("This is a valid shared lock"); return lock; @@ -125,7 +133,8 @@ public class FileLocks { static FileLock getReadLockFromRandomAccessFile(long from, long size) throws IOException { Path path = Files.createTempFile("foo", "txt"); try (RandomAccessFile file = new RandomAccessFile(path.toFile(), "r"); // could also be "rw", but "r" is sufficient for reading - FileLock lock = file.getChannel().lock(from, size, true)) { + FileLock lock = file.getChannel() + .lock(from, size, true)) { if (lock.isValid()) { LOG.debug("This is a valid shared lock"); return lock; diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index da4e321ebf..a7fd15301a 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -14,33 +14,39 @@ import org.junit.jupiter.api.Test; class FileLocksUnitTest { - @Test void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { + @Test + void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { assertThrows(NonWritableChannelException.class, () -> FileLocks.getExclusiveLockFromInputStream()); } - @Test void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { + @Test + void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { FileLock lock = FileLocks.getExclusiveLockFromRandomAccessFile(0, 10); assertNotNull(lock); assertFalse(lock.isShared()); } - @Test void givenAPath_whenGetExclusiveLock_lock() throws IOException { + @Test + void givenAPath_whenGetExclusiveLock_lock() throws IOException { FileLock lock = FileLocks.getExclusiveLockFromFileChannelOpen(0, 10); assertNotNull(lock); assertFalse(lock.isShared()); } - @Test void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { + @Test + void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { assertThrows(NonReadableChannelException.class, FileLocks::getReadLockFromOutputStream); } - @Test void givenAnInputStream_whenGetSharedLock_lock() throws IOException { + @Test + void givenAnInputStream_whenGetSharedLock_lock() throws IOException { FileLock lock = FileLocks.getReadLockFromInputStream(0, 10); assertNotNull(lock); assertTrue(lock.isShared()); } - @Test void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { + @Test + void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); assertNotNull(lock); assertTrue(lock.isShared()); From b907d2cd6e50471929d8623b170720d7c48e69bc Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Tue, 11 Feb 2020 18:02:53 +0200 Subject: [PATCH 15/62] Review changes --- .../java/com/baeldung/jcabi/JcabiAspectJ.java | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java index c88ad5a74d..6bd345c59c 100644 --- a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java +++ b/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java @@ -1,6 +1,14 @@ package com.baeldung.jcabi; +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -9,7 +17,6 @@ import com.jcabi.aspects.Async; import com.jcabi.aspects.Cacheable; import com.jcabi.aspects.LogExceptions; import com.jcabi.aspects.Loggable; -import com.jcabi.aspects.Parallel; import com.jcabi.aspects.Quietly; import com.jcabi.aspects.RetryOnFailure; import com.jcabi.aspects.UnitedThrow; @@ -20,19 +27,24 @@ public class JcabiAspectJ { try { displayFactorial(10); getFactorial(10).get(); - - Double number = cacheRandomNumber(); - if (number != cacheRandomNumber()) { - System.out.println(number); + + String result = cacheExchangeRates(); + if (result != cacheExchangeRates()) { + System.out.println(result); } - + divideByZero(); } catch(Exception e) { e.printStackTrace(); } - + divideByZeroQuietly(); - parallelExecution(); + try { + processFile(); + } catch(Exception e) { + e.printStackTrace(); + } + } @Loggable @@ -41,14 +53,14 @@ public class JcabiAspectJ { long result = factorial(number); System.out.println(result); } - + @Loggable @Async public static Future getFactorial(int number) { Future factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number)); return factorialFuture; } - + /** * Finds factorial of a number * @param number @@ -64,25 +76,37 @@ public class JcabiAspectJ { @Loggable @Cacheable(lifetime = 2, unit = TimeUnit.SECONDS) - public static Double cacheRandomNumber() { - return Math.random(); + public static String cacheExchangeRates() { + String result = null; + try { + URL exchangeRateUrl = new URL("https://api.exchangeratesapi.io/latest"); + URLConnection con = exchangeRateUrl.openConnection(); + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + result = in.readLine(); + } catch (IOException e) { + e.printStackTrace(); + } + return result; } - - @UnitedThrow(IllegalStateException.class) + @LogExceptions public static void divideByZero() { int x = 1/0; } - + @RetryOnFailure(attempts = 2, types = {java.lang.NumberFormatException.class}) @Quietly public static void divideByZeroQuietly() { int x = 1/0; } - - @Parallel(threads = 4) - public static void parallelExecution() { - System.out.println("Calling Parallel..."); + + @UnitedThrow(IllegalStateException.class) + public static void processFile() throws IOException, InterruptedException { + BufferedReader reader = new BufferedReader(new FileReader("baeldung.txt")); + reader.readLine(); + + Thread thread = new Thread(); + thread.wait(2000); } } From 9da15e9d942e6bf33c24f43433b73c84c19144a0 Mon Sep 17 00:00:00 2001 From: "ramprasad.devarakonda@gmail.com" Date: Sat, 8 Feb 2020 23:58:31 +0000 Subject: [PATCH 16/62] BAEL-3324 | Using JSON Patch in Spring REST APIs --- spring-rest-http/pom.xml | 6 ++ .../CustomerSpringBootRestApplication.java | 12 +++ .../java/com/baeldung/model/Customer.java | 79 ++++++++++++++ .../baeldung/service/CustomerIdGenerator.java | 6 ++ .../com/baeldung/service/CustomerService.java | 14 +++ .../service/impl/CustomerIdGeneratorImpl.java | 17 +++ .../service/impl/CustomerServiceImpl.java | 42 ++++++++ .../controller/CustomerRestController.java | 69 ++++++++++++ .../exception/CustomerNotFoundException.java | 5 + .../impl/CustomerIdGeneratorImplUnitTest.java | 17 +++ .../impl/CustomerServiceImplUnitTest.java | 94 ++++++++++++++++ ...CustomerRestControllerIntegrationTest.java | 72 +++++++++++++ .../CustomerRestControllerUnitTest.java | 101 ++++++++++++++++++ 13 files changed, 534 insertions(+) create mode 100644 spring-rest-http/src/main/java/com/baeldung/CustomerSpringBootRestApplication.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/model/Customer.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/service/CustomerIdGenerator.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/service/CustomerService.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerIdGeneratorImpl.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerServiceImpl.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/web/controller/CustomerRestController.java create mode 100644 spring-rest-http/src/main/java/com/baeldung/web/exception/CustomerNotFoundException.java create mode 100644 spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerIdGeneratorImplUnitTest.java create mode 100644 spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerServiceImplUnitTest.java create mode 100644 spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerIntegrationTest.java create mode 100644 spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerUnitTest.java diff --git a/spring-rest-http/pom.xml b/spring-rest-http/pom.xml index c5c6b8d44c..32d2804220 100644 --- a/spring-rest-http/pom.xml +++ b/spring-rest-http/pom.xml @@ -41,12 +41,18 @@ org.springframework.boot spring-boot-starter-test + + com.github.java-json-tools + json-patch + ${jsonpatch.version} + 1.4.9 + 1.12 diff --git a/spring-rest-http/src/main/java/com/baeldung/CustomerSpringBootRestApplication.java b/spring-rest-http/src/main/java/com/baeldung/CustomerSpringBootRestApplication.java new file mode 100644 index 0000000000..2995d4d0dc --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/CustomerSpringBootRestApplication.java @@ -0,0 +1,12 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomerSpringBootRestApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomerSpringBootRestApplication.class, args); + } +} diff --git a/spring-rest-http/src/main/java/com/baeldung/model/Customer.java b/spring-rest-http/src/main/java/com/baeldung/model/Customer.java new file mode 100644 index 0000000000..e65446c389 --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/model/Customer.java @@ -0,0 +1,79 @@ +package com.baeldung.model; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class Customer { + private String id; + private String telephone; + private List favorites; + private Map communicationPreferences; + + public Customer() { + } + + public Customer(String id, String telephone, List favorites, Map communicationPreferences) { + this(telephone, favorites, communicationPreferences); + this.id = id; + } + + public Customer(String telephone, List favorites, Map communicationPreferences) { + this.telephone = telephone; + this.favorites = favorites; + this.communicationPreferences = communicationPreferences; + } + + public static Customer fromCustomer(Customer customer) { + return new Customer(customer.getId(), customer.getTelephone(), customer.getFavorites(), customer.getCommunicationPreferences()); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTelephone() { + return telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public Map getCommunicationPreferences() { + return communicationPreferences; + } + + public void setCommunicationPreferences(Map communicationPreferences) { + this.communicationPreferences = communicationPreferences; + } + + public List getFavorites() { + return favorites; + } + + public void setFavorites(List favorites) { + this.favorites = favorites; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Customer)) { + return false; + } + Customer customer = (Customer) o; + return Objects.equals(id, customer.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/spring-rest-http/src/main/java/com/baeldung/service/CustomerIdGenerator.java b/spring-rest-http/src/main/java/com/baeldung/service/CustomerIdGenerator.java new file mode 100644 index 0000000000..f4afb79852 --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/service/CustomerIdGenerator.java @@ -0,0 +1,6 @@ +package com.baeldung.service; + +public interface CustomerIdGenerator { + int generateNextId(); +} + diff --git a/spring-rest-http/src/main/java/com/baeldung/service/CustomerService.java b/spring-rest-http/src/main/java/com/baeldung/service/CustomerService.java new file mode 100644 index 0000000000..51a6bc7474 --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/service/CustomerService.java @@ -0,0 +1,14 @@ +package com.baeldung.service; + +import com.baeldung.model.Customer; + +import java.util.Optional; + +public interface CustomerService { + + Customer createCustomer(Customer customer); + + Optional findCustomer(String id); + + void updateCustomer(Customer customer); +} diff --git a/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerIdGeneratorImpl.java b/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerIdGeneratorImpl.java new file mode 100644 index 0000000000..471fe880b8 --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerIdGeneratorImpl.java @@ -0,0 +1,17 @@ +package com.baeldung.service.impl; + +import com.baeldung.service.CustomerIdGenerator; + +import org.springframework.stereotype.Component; + +import java.util.concurrent.atomic.AtomicInteger; + +@Component +public class CustomerIdGeneratorImpl implements CustomerIdGenerator { + private static final AtomicInteger SEQUENCE = new AtomicInteger(); + + @Override + public int generateNextId() { + return SEQUENCE.incrementAndGet(); + } +} diff --git a/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerServiceImpl.java b/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerServiceImpl.java new file mode 100644 index 0000000000..c57e95deed --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/service/impl/CustomerServiceImpl.java @@ -0,0 +1,42 @@ +package com.baeldung.service.impl; + +import com.baeldung.model.Customer; +import com.baeldung.service.CustomerIdGenerator; +import com.baeldung.service.CustomerService; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class CustomerServiceImpl implements CustomerService { + private CustomerIdGenerator customerIdGenerator; + private List customers = new ArrayList<>(); + + @Autowired + public CustomerServiceImpl(CustomerIdGenerator customerIdGenerator) { + this.customerIdGenerator = customerIdGenerator; + } + + @Override + public Customer createCustomer(Customer customer) { + customer.setId(Integer.toString(customerIdGenerator.generateNextId())); + customers.add(customer); + return customer; + } + + @Override + public Optional findCustomer(String id) { + return customers.stream() + .filter(customer -> customer.getId().equals(id)) + .findFirst(); + } + + @Override + public void updateCustomer(Customer customer) { + customers.set(customers.indexOf(customer), customer); + } +} diff --git a/spring-rest-http/src/main/java/com/baeldung/web/controller/CustomerRestController.java b/spring-rest-http/src/main/java/com/baeldung/web/controller/CustomerRestController.java new file mode 100644 index 0000000000..9c248b6d2d --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/web/controller/CustomerRestController.java @@ -0,0 +1,69 @@ +package com.baeldung.web.controller; + +import com.baeldung.model.Customer; +import com.baeldung.service.CustomerService; +import com.baeldung.web.exception.CustomerNotFoundException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.fge.jsonpatch.JsonPatch; +import com.github.fge.jsonpatch.JsonPatchException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.net.URI; + +import javax.validation.Valid; + +@RestController +@RequestMapping(value = "/customers") +public class CustomerRestController { + private CustomerService customerService; + private ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public CustomerRestController(CustomerService customerService) { + this.customerService = customerService; + } + + @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity createCustomer(@RequestBody Customer customer) { + Customer customerCreated = customerService.createCustomer(customer); + URI location = ServletUriComponentsBuilder.fromCurrentRequest() + .path("/{id}") + .buildAndExpand(customerCreated.getId()) + .toUri(); + return ResponseEntity.created(location).build(); + } + + @PatchMapping(path = "/{id}", consumes = "application/json-patch+json") + public ResponseEntity updateCustomer(@PathVariable String id, + @RequestBody JsonPatch patch) { + try { + Customer customer = customerService.findCustomer(id).orElseThrow(CustomerNotFoundException::new); + Customer customerPatched = applyPatchToCustomer(patch, customer); + customerService.updateCustomer(customerPatched); + + return ResponseEntity.ok(customerPatched); + } catch (CustomerNotFoundException e) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + } catch (JsonPatchException | JsonProcessingException e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } + + private Customer applyPatchToCustomer(JsonPatch patch, Customer targetCustomer) throws JsonPatchException, JsonProcessingException { + JsonNode patched = patch.apply(objectMapper.convertValue(targetCustomer, JsonNode.class)); + return objectMapper.treeToValue(patched, Customer.class); + } +} diff --git a/spring-rest-http/src/main/java/com/baeldung/web/exception/CustomerNotFoundException.java b/spring-rest-http/src/main/java/com/baeldung/web/exception/CustomerNotFoundException.java new file mode 100644 index 0000000000..c843696402 --- /dev/null +++ b/spring-rest-http/src/main/java/com/baeldung/web/exception/CustomerNotFoundException.java @@ -0,0 +1,5 @@ +package com.baeldung.web.exception; + +public class CustomerNotFoundException extends RuntimeException { + +} diff --git a/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerIdGeneratorImplUnitTest.java b/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerIdGeneratorImplUnitTest.java new file mode 100644 index 0000000000..a855c1cda2 --- /dev/null +++ b/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerIdGeneratorImplUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.service.impl; + +import com.baeldung.service.CustomerIdGenerator; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CustomerIdGeneratorImplUnitTest { + + @Test + public void givenIdGeneratedPreviously_whenGenerated_thenIdIsIncremented(){ + CustomerIdGenerator customerIdGenerator = new CustomerIdGeneratorImpl(); + int firstId = customerIdGenerator.generateNextId(); + assertThat(customerIdGenerator.generateNextId()).isEqualTo(++firstId); + } +} diff --git a/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerServiceImplUnitTest.java b/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerServiceImplUnitTest.java new file mode 100644 index 0000000000..27f0b35714 --- /dev/null +++ b/spring-rest-http/src/test/java/com/baeldung/service/impl/CustomerServiceImplUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.service.impl; + + +import com.baeldung.model.Customer; +import com.baeldung.service.CustomerIdGenerator; +import com.baeldung.service.CustomerService; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.HashMap; +import java.util.Map; + + +import static com.baeldung.model.Customer.fromCustomer; +import static java.util.Arrays.asList; +import static java.util.Optional.empty; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +@RunWith(MockitoJUnitRunner.class) +public class CustomerServiceImplUnitTest { + + @Mock + private CustomerIdGenerator mockCustomerIdGenerator; + + private CustomerService customerService; + + @Before + public void setup() { + customerService = new CustomerServiceImpl(mockCustomerIdGenerator); + } + + @Test + public void whenCustomerIsCreated_thenNewCustomerDetailsAreCorrect() { + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); + given(mockCustomerIdGenerator.generateNextId()).willReturn(1); + + Customer newCustomer = customerService.createCustomer(customer); + + assertThat(newCustomer.getId()).isEqualTo("1"); + assertThat(newCustomer.getTelephone()).isEqualTo("001-555-1234"); + assertThat(newCustomer.getFavorites()).containsExactly("Milk", "Eggs"); + assertThat(newCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); + } + + @Test + public void givenNonExistentCustomer_whenCustomerIsLookedUp_thenCustomerCanNotBeFound() { + assertThat(customerService.findCustomer("CUST12345")).isEqualTo(empty()); + } + + @Test + public void whenCustomerIsCreated_thenCustomerCanBeFound() { + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); + given(mockCustomerIdGenerator.generateNextId()).willReturn(7890); + + customerService.createCustomer(customer); + Customer lookedUpCustomer = customerService.findCustomer("7890").get(); + + assertThat(lookedUpCustomer.getId()).isEqualTo("7890"); + assertThat(lookedUpCustomer.getTelephone()).isEqualTo("001-555-1234"); + assertThat(lookedUpCustomer.getFavorites()).containsExactly("Milk", "Eggs"); + assertThat(lookedUpCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); + } + + @Test + public void whenCustomerUpdated_thenDetailsUpdatedCorrectly() { + given(mockCustomerIdGenerator.generateNextId()).willReturn(7890); + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); + Customer newCustomer = customerService.createCustomer(customer); + + Customer customerWithUpdates = fromCustomer(newCustomer); + customerWithUpdates.setTelephone("001-555-6789"); + customerService.updateCustomer(customerWithUpdates); + Customer lookedUpCustomer = customerService.findCustomer("7890").get(); + + assertThat(lookedUpCustomer.getId()).isEqualTo("7890"); + assertThat(lookedUpCustomer.getTelephone()).isEqualTo("001-555-6789"); + assertThat(lookedUpCustomer.getFavorites()).containsExactly("Milk", "Eggs"); + assertThat(lookedUpCustomer.getCommunicationPreferences()).isEqualTo(communicationPreferences); + } +} \ No newline at end of file diff --git a/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerIntegrationTest.java b/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerIntegrationTest.java new file mode 100644 index 0000000000..f4d9ff1b92 --- /dev/null +++ b/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerIntegrationTest.java @@ -0,0 +1,72 @@ +package com.baeldung.web.controller; + +import com.baeldung.model.Customer; +import com.baeldung.service.CustomerService; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CustomerRestControllerIntegrationTest { + + @Autowired + private CustomerService customerService; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Before + public void setup() { + testRestTemplate.getRestTemplate().setRequestFactory(new HttpComponentsClientHttpRequestFactory()); + } + + @Test + public void givenExistingCustomer_whenPatched_thenOnlyPatchedFieldsUpdated() { + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer newCustomer = new Customer("001-555-1234", Arrays.asList("Milk", "Eggs"), + communicationPreferences); + Customer customer = customerService.createCustomer(newCustomer); + + + String patchBody = "[ { \"op\": \"replace\", \"path\": \"/telephone\", \"value\": \"001-555-5678\" },\n" + + "{\"op\": \"add\", \"path\": \"/favorites/0\", \"value\": \"Bread\" }]"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.valueOf("application/json-patch+json")); + ResponseEntity patchResponse + = testRestTemplate.exchange("/customers/{id}", + HttpMethod.PATCH, + new HttpEntity<>(patchBody, headers), + Customer.class, + customer.getId()); + + Customer customerPatched = patchResponse.getBody(); + assertThat(patchResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(customerPatched.getId()).isEqualTo(customer.getId()); + assertThat(customerPatched.getTelephone()).isEqualTo("001-555-5678"); + assertThat(customerPatched.getCommunicationPreferences().get("post")).isTrue(); + assertThat(customerPatched.getCommunicationPreferences().get("email")).isTrue(); + assertThat(customerPatched.getFavorites()).containsExactly("Bread", "Milk", "Eggs"); + } +} diff --git a/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerUnitTest.java b/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerUnitTest.java new file mode 100644 index 0000000000..d0fb255a5d --- /dev/null +++ b/spring-rest-http/src/test/java/com/baeldung/web/controller/CustomerRestControllerUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.web.controller; + +import com.baeldung.model.Customer; +import com.baeldung.service.CustomerService; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.HashMap; +import java.util.Map; + +import static java.util.Arrays.asList; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; +import static org.springframework.http.MediaType.APPLICATION_JSON; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc +public class CustomerRestControllerUnitTest { + + private static final String APPLICATION_JSON_PATCH_JSON = "application/json-patch+json"; + + @Autowired + private MockMvc mvc; + + @MockBean + private CustomerService mockCustomerService; + + @Autowired + ApplicationContext context; + + @Test + public void whenCustomerCreated_then201ReturnedWithNewCustomerLocation() throws Exception { + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer customer = new Customer("001-555-1234", asList("Milk", "Eggs"), communicationPreferences); + + Customer persistedCustomer = Customer.fromCustomer(customer); + persistedCustomer.setId("1"); + + given(mockCustomerService.createCustomer(customer)).willReturn(persistedCustomer); + + String createCustomerRequestBody = "{" + + "\"telephone\": \"001-555-1234\",\n" + + "\"favorites\": [\"Milk\", \"Eggs\"],\n" + + "\"communicationPreferences\": {\"post\":true, \"email\":true}\n" + + "}"; + mvc.perform(post("/customers") + .contentType(APPLICATION_JSON) + .content(createCustomerRequestBody)) + .andExpect(status().isCreated()) + .andExpect(redirectedUrlPattern("http://*/customers/1")); + } + + @Test + public void givenNonExistentCustomer_whenPatched_then404Returned() throws Exception { + given(mockCustomerService.findCustomer("1")).willReturn(empty()); + + String patchInstructions = "[{\"op\":\"replace\",\"path\": \"/telephone\",\"value\":\"001-555-5678\"}]"; + mvc.perform(patch("/customers/1") + .contentType(APPLICATION_JSON_PATCH_JSON) + .content(patchInstructions)) + .andExpect(status().isNotFound()); + } + + @Test + public void givenExistingCustomer_whenPatched_thenReturnPatchedCustomer() throws Exception { + Map communicationPreferences = new HashMap<>(); + communicationPreferences.put("post", true); + communicationPreferences.put("email", true); + Customer customer = new Customer("1", "001-555-1234", asList("Milk", "Eggs"), communicationPreferences); + + given(mockCustomerService.findCustomer("1")).willReturn(of(customer)); + + String patchInstructions = "[{\"op\":\"replace\",\"path\": \"/telephone\",\"value\":\"001-555-5678\"}]"; + mvc.perform(patch("/customers/1") + .contentType(APPLICATION_JSON_PATCH_JSON) + .content(patchInstructions)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is("1"))) + .andExpect(jsonPath("$.telephone", is("001-555-5678"))) + .andExpect(jsonPath("$.favorites", is(asList("Milk", "Eggs")))) + .andExpect(jsonPath("$.communicationPreferences", is(communicationPreferences))); + } +} From 37d822bc1243bd57b03b4d2514ac41c6993cd9ff Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:11:28 -0500 Subject: [PATCH 17/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index a7fd15301a..262bc3c128 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test; class FileLocksUnitTest { @Test - void givenAnInputStream_whenGetWriteLock_throwNonWritableChannelException() { + void givenAnInputStream_whenGetWriteLock_thenThrowNonWritableChannelException() { assertThrows(NonWritableChannelException.class, () -> FileLocks.getExclusiveLockFromInputStream()); } From 81d097732de6db39a89cd4441966b41df75c596f Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:11:34 -0500 Subject: [PATCH 18/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index 262bc3c128..6a54e2f7dc 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -20,7 +20,7 @@ class FileLocksUnitTest { } @Test - void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_lock() throws IOException { + void givenARandomAccessFileWithReadWriteAccess_whenGetWriteLock_thenLock() throws IOException { FileLock lock = FileLocks.getExclusiveLockFromRandomAccessFile(0, 10); assertNotNull(lock); assertFalse(lock.isShared()); From c6489551cfa5261b9e8c6aa03bf4797629fc561b Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:11:41 -0500 Subject: [PATCH 19/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index 6a54e2f7dc..d1e311bbf3 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -34,7 +34,7 @@ class FileLocksUnitTest { } @Test - void givenAFileOutputStream_whenGetSharedLock_throwNonReadableChannelException() { + void givenAFileOutputStream_whenGetSharedLock_thenThrowNonReadableChannelException() { assertThrows(NonReadableChannelException.class, FileLocks::getReadLockFromOutputStream); } From db20aeb12cf37cb82c22e756b2ca58c0a3864a71 Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:11:52 -0500 Subject: [PATCH 20/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index d1e311bbf3..aeda6582a1 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -27,7 +27,7 @@ class FileLocksUnitTest { } @Test - void givenAPath_whenGetExclusiveLock_lock() throws IOException { + void givenAPath_whenGetExclusiveLock_thenLock() throws IOException { FileLock lock = FileLocks.getExclusiveLockFromFileChannelOpen(0, 10); assertNotNull(lock); assertFalse(lock.isShared()); From 80d241be46ad04cd8dc418eebcfcb87ab391bdb0 Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:12:30 -0500 Subject: [PATCH 21/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index aeda6582a1..26dea5ce25 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -39,7 +39,7 @@ class FileLocksUnitTest { } @Test - void givenAnInputStream_whenGetSharedLock_lock() throws IOException { + void givenAnInputStream_whenGetSharedLock_thenLock() throws IOException { FileLock lock = FileLocks.getReadLockFromInputStream(0, 10); assertNotNull(lock); assertTrue(lock.isShared()); From bc18fd907f07f6ce4547e233d794159ba6270b83 Mon Sep 17 00:00:00 2001 From: psoares Date: Fri, 14 Feb 2020 23:12:37 -0500 Subject: [PATCH 22/62] Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java Co-Authored-By: KevinGilmore --- .../src/test/java/com/baeldung/lock/FileLocksUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java index 26dea5ce25..1de988a87b 100644 --- a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/lock/FileLocksUnitTest.java @@ -46,7 +46,7 @@ class FileLocksUnitTest { } @Test - void givenARandomAccessFile_whenGetSharedLock_lock() throws IOException { + void givenARandomAccessFile_whenGetSharedLock_thenLock() throws IOException { FileLock lock = FileLocks.getReadLockFromRandomAccessFile(0, 10); assertNotNull(lock); assertTrue(lock.isShared()); From 466d25bd056df4429a884f00c8a1913cdd8603e6 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Fri, 14 Feb 2020 23:20:05 -0500 Subject: [PATCH 23/62] Reverted change on README.md --- core-java-modules/core-java-nio-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index 8950f650e6..8b29c97385 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -8,4 +8,4 @@ This module contains articles about core Java non-blocking input and output (IO) - [Create a Symbolic Link with Java](https://www.baeldung.com/java-symlink) - [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector) - [Using Java MappedByteBuffer](https://www.baeldung.com/java-mapped-byte-buffer) -- [[<-- Prev]](/core-java-modules/core-java-nio) +- [[<-- Prev]](/core-java-modules/core-java-nio) \ No newline at end of file From 0bfbec65dd50ead02d255b77fabb5a1ec91fd011 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Mon, 17 Feb 2020 21:49:03 +0530 Subject: [PATCH 24/62] JAVA-6: Split or move spring-security-mvc-boot module --- spring-security-modules/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 7de3009f47..f4ffd9085a 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -21,7 +21,8 @@ spring-security-cors spring-security-kerberos spring-security-mvc - spring-security-mvc-boot + spring-security-mvc-boot-1 + spring-security-mvc-boot-2 spring-security-mvc-custom spring-security-mvc-digest-auth spring-security-mvc-jsonview From aecfad9448243846bc2b68d8f135c7054b15b8e8 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Mon, 17 Feb 2020 21:52:37 +0530 Subject: [PATCH 25/62] JAVA-6 : new module spring-security-mvc-boot-1 --- .../spring-security-mvc-boot-1/README.md | 17 ++ .../WebContent/META-INF/MANIFEST.MF | 3 + .../spring-security-mvc-boot-1/pom.xml | 240 ++++++++++++++++++ .../src/main/java/com/baeldung/AppConfig.java | 64 +++++ .../com/baeldung/SpringSecurityConfig.java | 89 +++++++ .../data/repositories/TweetRepository.java | 14 + .../data/repositories/UserRepository.java | 26 ++ .../java/com/baeldung/models/AppUser.java | 83 ++++++ .../main/java/com/baeldung/models/Tweet.java | 67 +++++ .../baeldung/security/AppUserPrincipal.java | 67 +++++ .../AuthenticationSuccessHandlerImpl.java | 28 ++ .../security/CustomUserDetailsService.java | 40 +++ .../com/baeldung/util/DummyContentUtil.java | 63 +++++ .../java/org/baeldung/custom/Application.java | 14 + .../custom/config/MethodSecurityConfig.java | 21 ++ .../org/baeldung/custom/config/MvcConfig.java | 41 +++ .../custom/config/SecurityConfig.java | 15 ++ .../custom/persistence/SetupData.java | 73 ++++++ .../dao/OrganizationRepository.java | 10 + .../persistence/dao/PrivilegeRepository.java | 10 + .../persistence/dao/UserRepository.java | 14 + .../custom/persistence/model/Foo.java | 94 +++++++ .../persistence/model/Organization.java | 95 +++++++ .../custom/persistence/model/Privilege.java | 95 +++++++ .../custom/persistence/model/User.java | 155 +++++++++++ ...CustomMethodSecurityExpressionHandler.java | 22 ++ .../CustomMethodSecurityExpressionRoot.java | 50 ++++ .../security/CustomPermissionEvaluator.java | 40 +++ .../security/MySecurityExpressionRoot.java | 203 +++++++++++++++ .../custom/security/MyUserDetailsService.java | 31 +++ .../custom/security/MyUserPrincipal.java | 72 ++++++ .../baeldung/custom/web/MainController.java | 68 +++++ .../java/org/baeldung/ip/IpApplication.java | 14 + .../CustomIpAuthenticationProvider.java | 53 ++++ .../baeldung/ip/config/SecurityConfig.java | 36 +++ .../baeldung/ip/config/SecurityXmlConfig.java | 9 + .../org/baeldung/ip/web/MainController.java | 42 +++ .../CustomAuthenticationProvider.java | 38 +++ .../MyLogoutSuccessHandler.java | 26 ++ .../MyUserDetailsService.java | 61 +++++ .../RolesAuthoritiesApplication.java | 17 ++ .../rolesauthorities/config/MvcConfig.java | 46 ++++ .../config/SecurityConfig.java | 90 +++++++ .../rolesauthorities/model/Privilege.java | 89 +++++++ .../baeldung/rolesauthorities/model/Role.java | 104 ++++++++ .../baeldung/rolesauthorities/model/User.java | 147 +++++++++++ .../persistence/IUserService.java | 9 + .../persistence/PrivilegeRepository.java | 12 + .../persistence/RoleRepository.java | 12 + .../persistence/SetupDataLoader.java | 97 +++++++ .../persistence/UserRepository.java | 12 + .../persistence/UserService.java | 19 ++ .../org/baeldung/voter/MinuteBasedVoter.java | 26 ++ .../org/baeldung/voter/VoterApplication.java | 16 ++ .../org/baeldung/voter/VoterMvcConfig.java | 19 ++ .../org/baeldung/voter/WebSecurityConfig.java | 55 ++++ .../org/baeldung/voter/XmlSecurityConfig.java | 15 ++ .../resources/application-defaults.properties | 13 + .../src/main/resources/application.properties | 1 + .../src/main/resources/logback.xml | 13 + .../main/resources/persistence-h2.properties | 8 + .../spring-security-custom-voter.xml | 40 +++ .../src/main/resources/spring-security-ip.xml | 21 ++ .../src/main/resources/templates/403.html | 10 + .../src/main/resources/templates/index.html | 21 ++ .../src/main/resources/templates/login.html | 27 ++ .../main/resources/templates/loginAdmin.html | 31 +++ .../main/resources/templates/loginUser.html | 30 +++ .../templates/multipleHttpElems/login.html | 27 ++ .../multipleHttpElems/loginWithWarning.html | 28 ++ .../multipleHttpElems/multipleHttpLinks.html | 18 ++ .../multipleHttpElems/myAdminPage.html | 13 + .../multipleHttpElems/myGuestPage.html | 13 + .../multipleHttpElems/myPrivateUserPage.html | 13 + .../multipleHttpElems/myUserPage.html | 13 + .../src/main/resources/templates/private.html | 10 + .../templates/rolesauthorities/home.html | 25 ++ .../templates/rolesauthorities/login.html | 57 +++++ .../protectedbyauthority.html | 24 ++ .../rolesauthorities/protectedbynothing.html | 21 ++ .../rolesauthorities/protectedbyrole.html | 24 ++ .../main/resources/templates/ssl/welcome.html | 1 + ...SpringDataWithSecurityIntegrationTest.java | 112 ++++++++ .../java/org/baeldung/SpringContextTest.java | 16 ++ .../org/baeldung/web/ApplicationLiveTest.java | 67 +++++ ...stomUserDetailsServiceIntegrationTest.java | 89 +++++++ .../java/org/baeldung/web/IpLiveTest.java | 27 ++ 87 files changed, 3801 insertions(+) create mode 100644 spring-security-modules/spring-security-mvc-boot-1/README.md create mode 100644 spring-security-modules/spring-security-mvc-boot-1/WebContent/META-INF/MANIFEST.MF create mode 100644 spring-security-modules/spring-security-mvc-boot-1/pom.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/AppConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/SpringSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/TweetRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/UserRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/AppUser.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/Tweet.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AppUserPrincipal.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/CustomUserDetailsService.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/util/DummyContentUtil.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MvcConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/SetupData.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Foo.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Organization.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Privilege.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/User.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/web/MainController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/web/MainController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Role.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/User.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/MinuteBasedVoter.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterMvcConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/WebSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/XmlSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application-defaults.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/logback.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/persistence-h2.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-custom-voter.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-ip.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/403.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/index.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/login.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginAdmin.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginUser.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/login.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/loginWithWarning.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myAdminPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myGuestPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myUserPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/private.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/home.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/login.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyauthority.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbynothing.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyrole.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/ssl/welcome.html create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/SpringContextTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java diff --git a/spring-security-modules/spring-security-mvc-boot-1/README.md b/spring-security-modules/spring-security-mvc-boot-1/README.md new file mode 100644 index 0000000000..f2c161d387 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/README.md @@ -0,0 +1,17 @@ +## Spring Boot Security MVC - 1 + +This module contains articles about Spring Security with Spring MVC in Boot applications + +### The Course +The "REST With Spring" Classes: http://github.learnspringsecurity.com + +### Relevant Articles: +- [A Custom Security Expression with Spring Security](https://www.baeldung.com/spring-security-create-new-custom-security-expression) +- [Custom AccessDecisionVoters in Spring Security](https://www.baeldung.com/spring-security-custom-voter) +- [Spring Security: Authentication with a Database-backed UserDetailsService](https://www.baeldung.com/spring-security-authentication-with-a-database) +- [Spring Data with Spring Security](https://www.baeldung.com/spring-data-security) +- [Granted Authority Versus Role in Spring Security](https://www.baeldung.com/spring-security-granted-authority-vs-role) +- [Spring Security – Whitelist IP Range](https://www.baeldung.com/spring-security-whitelist-ip-range) +- [Find the Registered Spring Security Filters](https://www.baeldung.com/spring-security-registered-filters) +- More articles: [[next -->]](/../spring-security-mvc-boot-2) + diff --git a/spring-security-modules/spring-security-mvc-boot-1/WebContent/META-INF/MANIFEST.MF b/spring-security-modules/spring-security-mvc-boot-1/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-security-modules/spring-security-mvc-boot-1/pom.xml b/spring-security-modules/spring-security-mvc-boot-1/pom.xml new file mode 100644 index 0000000000..3eeac80d2c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/pom.xml @@ -0,0 +1,240 @@ + + + 4.0.0 + spring-security-mvc-boot-1 + 0.0.1-SNAPSHOT + spring-security-mvc-boot-1 + war + Spring Security MVC Boot - 1 + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.security + spring-security-data + + + mysql + mysql-connector-java + runtime + + + com.h2database + h2 + + + org.postgresql + postgresql + runtime + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + org.springframework + spring-test + test + + + org.springframework.security + spring-security-test + test + + + taglibs + standard + ${taglibs-standard.version} + + + org.springframework.security + spring-security-taglibs + + + org.springframework.security + spring-security-core + + + javax.servlet.jsp.jstl + jstl-api + ${jstl.version} + + + org.springframework.security + spring-security-config + + + org.springframework + spring-context-support + + + net.sf.ehcache + ehcache-core + ${ehcache-core.version} + jar + + + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + tomcat8x + embedded + + + + + + + 8082 + + + + + + + + + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + entryPoints + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*IntTest.java + + + **/*EntryPointsTest.java + + + + + + + json + + + + + + + + + + org.baeldung.custom.Application + + + + 1.1.2 + 1.6.1 + 2.6.11 + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/AppConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/AppConfig.java new file mode 100644 index 0000000000..8719e39a20 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/AppConfig.java @@ -0,0 +1,64 @@ +package com.baeldung; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@SpringBootApplication +@PropertySource({"classpath:persistence-h2.properties", "classpath:application-defaults.properties"}) +@EnableJpaRepositories(basePackages = { "com.baeldung.data.repositories" }) +@EnableWebMvc +@Import(SpringSecurityConfig.class) +public class AppConfig extends WebMvcConfigurerAdapter { + + @Autowired + private Environment env; + + @Bean + public DataSource dataSource() { + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(env.getProperty("driverClassName")); + dataSource.setUrl(env.getProperty("url")); + dataSource.setUsername(env.getProperty("user")); + dataSource.setPassword(env.getProperty("password")); + return dataSource; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "com.baeldung.models" }); + em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + em.setJpaProperties(additionalProperties()); + return em; + } + + final Properties additionalProperties() { + final Properties hibernateProperties = new Properties(); + if (env.getProperty("hibernate.hbm2ddl.auto") != null) { + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + } + if (env.getProperty("hibernate.dialect") != null) { + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + } + if (env.getProperty("hibernate.show_sql") != null) { + hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); + } + return hibernateProperties; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/SpringSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/SpringSecurityConfig.java new file mode 100644 index 0000000000..ee13678a24 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/SpringSecurityConfig.java @@ -0,0 +1,89 @@ +package com.baeldung; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.security.AuthenticationSuccessHandlerImpl; +import com.baeldung.security.CustomUserDetailsService; + +@Configuration +@EnableWebSecurity +@ComponentScan("com.baeldung.security") +public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private WebApplicationContext applicationContext; + private CustomUserDetailsService userDetailsService; + @Autowired + private AuthenticationSuccessHandlerImpl successHandler; + @Autowired + private DataSource dataSource; + + @PostConstruct + public void completeSetup() { + userDetailsService = applicationContext.getBean(CustomUserDetailsService.class); + } + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService) + .passwordEncoder(encoder()) + .and() + .authenticationProvider(authenticationProvider()) + .jdbcAuthentication() + .dataSource(dataSource); + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring() + .antMatchers("/resources/**"); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/login") + .permitAll() + .and() + .formLogin() + .permitAll() + .successHandler(successHandler) + .and() + .csrf() + .disable(); + } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); + authProvider.setUserDetailsService(userDetailsService); + authProvider.setPasswordEncoder(encoder()); + return authProvider; + } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(11); + } + + @Bean + public SecurityEvaluationContextExtension securityEvaluationContextExtension() { + return new SecurityEvaluationContextExtension(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/TweetRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/TweetRepository.java new file mode 100644 index 0000000000..7d6446ed0d --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/TweetRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.data.repositories; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.baeldung.models.Tweet; + +public interface TweetRepository extends PagingAndSortingRepository { + + @Query("select twt from Tweet twt JOIN twt.likes as lk where lk = ?#{ principal?.username } or twt.owner = ?#{ principal?.username }") + Page getMyTweetsAndTheOnesILiked(Pageable pageable); +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/UserRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/UserRepository.java new file mode 100644 index 0000000000..5240c683e0 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/data/repositories/UserRepository.java @@ -0,0 +1,26 @@ +package com.baeldung.data.repositories; + +import java.util.Date; +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.models.AppUser; + +public interface UserRepository extends CrudRepository { + AppUser findByUsername(String username); + + List findByName(String name); + + @Query("UPDATE AppUser u SET u.lastLogin=:lastLogin WHERE u.username = ?#{ principal?.username }") + @Modifying + @Transactional + public void updateLastLogin(@Param("lastLogin") Date lastLogin); +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/AppUser.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/AppUser.java new file mode 100644 index 0000000000..e48233f90a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/AppUser.java @@ -0,0 +1,83 @@ +package com.baeldung.models; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class AppUser { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String name; + @Column(unique = true) + private String username; + private String password; + private boolean enabled = true; + private Date lastLogin; + + private AppUser() { + } + + public AppUser(String name, String email, String password) { + this.username = email; + this.name = name; + this.password = password; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/Tweet.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/Tweet.java new file mode 100644 index 0000000000..54a96deaf3 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/models/Tweet.java @@ -0,0 +1,67 @@ +package com.baeldung.models; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CollectionTable; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "Tweet") +public class Tweet { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + private String tweet; + private String owner; + @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER) + @CollectionTable(name = "Tweet_Likes") + private Set likes = new HashSet<>(); + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + private Tweet() { + } + + public Tweet(String tweet, String owner) { + this.tweet = tweet; + this.owner = owner; + } + + public String getTweet() { + return tweet; + } + + public void setTweet(String tweet) { + this.tweet = tweet; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Set getLikes() { + return likes; + } + + public void setLikes(Set likes) { + this.likes = likes; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AppUserPrincipal.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AppUserPrincipal.java new file mode 100644 index 0000000000..195f9f7bf6 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AppUserPrincipal.java @@ -0,0 +1,67 @@ +package com.baeldung.security; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.baeldung.models.AppUser; + +public class AppUserPrincipal implements UserDetails { + + private final AppUser user; + + // + + public AppUserPrincipal(AppUser user) { + this.user = user; + } + + // + + @Override + public String getUsername() { + return user.getUsername(); + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public Collection getAuthorities() { + final List authorities = Collections.singletonList(new SimpleGrantedAuthority("User")); + return authorities; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + // + + public AppUser getAppUser() { + return user; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java new file mode 100644 index 0000000000..3fc2bc6559 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java @@ -0,0 +1,28 @@ +package com.baeldung.security; + +import java.io.IOException; +import java.util.Date; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +import com.baeldung.data.repositories.UserRepository; + +@Component +public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler { + + @Autowired + private UserRepository userRepository; + + @Override + public void onAuthenticationSuccess(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2) throws IOException, ServletException { + userRepository.updateLastLogin(new Date()); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/CustomUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/CustomUserDetailsService.java new file mode 100644 index 0000000000..016f4f7fa9 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/security/CustomUserDetailsService.java @@ -0,0 +1,40 @@ +package com.baeldung.security; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.data.repositories.UserRepository; +import com.baeldung.models.AppUser; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + @Autowired + private WebApplicationContext applicationContext; + private UserRepository userRepository; + + public CustomUserDetailsService() { + super(); + } + + @PostConstruct + public void completeSetup() { + userRepository = applicationContext.getBean(UserRepository.class); + } + + @Override + public UserDetails loadUserByUsername(final String username) { + final AppUser appUser = userRepository.findByUsername(username); + if (appUser == null) { + throw new UsernameNotFoundException(username); + } + return new AppUserPrincipal(appUser); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/util/DummyContentUtil.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/util/DummyContentUtil.java new file mode 100644 index 0000000000..f1640264d2 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/com/baeldung/util/DummyContentUtil.java @@ -0,0 +1,63 @@ +package com.baeldung.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import com.baeldung.models.AppUser; +import com.baeldung.models.Tweet; + +public class DummyContentUtil { + + public static final List generateDummyUsers() { + List appUsers = new ArrayList<>(); + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + appUsers.add(new AppUser("Lionel Messi", "lionel@messi.com", passwordEncoder.encode("li1234"))); + appUsers.add(new AppUser("Cristiano Ronaldo", "cristiano@ronaldo.com", passwordEncoder.encode("c1234"))); + appUsers.add(new AppUser("Neymar Dos Santos", "neymar@neymar.com", passwordEncoder.encode("n1234"))); + appUsers.add(new AppUser("Luiz Suarez", "luiz@suarez.com", passwordEncoder.encode("lu1234"))); + appUsers.add(new AppUser("Andres Iniesta", "andres@iniesta.com", passwordEncoder.encode("a1234"))); + appUsers.add(new AppUser("Ivan Rakitic", "ivan@rakitic.com", passwordEncoder.encode("i1234"))); + appUsers.add(new AppUser("Ousman Dembele", "ousman@dembele.com", passwordEncoder.encode("o1234"))); + appUsers.add(new AppUser("Sergio Busquet", "sergio@busquet.com", passwordEncoder.encode("s1234"))); + appUsers.add(new AppUser("Gerard Pique", "gerard@pique.com", passwordEncoder.encode("g1234"))); + appUsers.add(new AppUser("Ter Stergen", "ter@stergen.com", passwordEncoder.encode("t1234"))); + return appUsers; + } + + public static final List generateDummyTweets(List users) { + List tweets = new ArrayList<>(); + Random random = new Random(); + IntStream.range(0, 9) + .sequential() + .forEach(i -> { + Tweet twt = new Tweet(String.format("Tweet %d", i), users.get(random.nextInt(users.size())) + .getUsername()); + twt.getLikes() + .addAll(users.subList(0, random.nextInt(users.size())) + .stream() + .map(AppUser::getUsername) + .collect(Collectors.toSet())); + tweets.add(twt); + }); + return tweets; + } + + public static Collection getAuthorities() { + Collection grantedAuthorities = new ArrayList(); + GrantedAuthority grantedAuthority = new GrantedAuthority() { + public String getAuthority() { + return "ROLE_USER"; + } + }; + grantedAuthorities.add(grantedAuthority); + return grantedAuthorities; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java new file mode 100644 index 0000000000..2bd0da48d2 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java @@ -0,0 +1,14 @@ +package org.baeldung.custom; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +public class Application extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java new file mode 100644 index 0000000000..6a005153dc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java @@ -0,0 +1,21 @@ +package org.baeldung.custom.config; + +import org.baeldung.custom.security.CustomMethodSecurityExpressionHandler; +import org.baeldung.custom.security.CustomPermissionEvaluator; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + // final DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); + final CustomMethodSecurityExpressionHandler expressionHandler = new CustomMethodSecurityExpressionHandler(); + expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator()); + return expressionHandler; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MvcConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MvcConfig.java new file mode 100644 index 0000000000..58d11ea9ae --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/MvcConfig.java @@ -0,0 +1,41 @@ +package org.baeldung.custom.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class MvcConfig implements WebMvcConfigurer { + + public MvcConfig() { + super(); + } + + // + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("forward:/index"); + registry.addViewController("/index"); + } + + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java new file mode 100644 index 0000000000..739e4d3417 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java @@ -0,0 +1,15 @@ +package org.baeldung.custom.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfig { + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(11); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/SetupData.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/SetupData.java new file mode 100644 index 0000000000..f0fcce3908 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/SetupData.java @@ -0,0 +1,73 @@ +package org.baeldung.custom.persistence; + +import java.util.Arrays; +import java.util.HashSet; + +import javax.annotation.PostConstruct; + +import org.baeldung.custom.persistence.dao.OrganizationRepository; +import org.baeldung.custom.persistence.dao.PrivilegeRepository; +import org.baeldung.custom.persistence.dao.UserRepository; +import org.baeldung.custom.persistence.model.Organization; +import org.baeldung.custom.persistence.model.Privilege; +import org.baeldung.custom.persistence.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +@Component +public class SetupData { + @Autowired + private UserRepository userRepository; + + @Autowired + private PrivilegeRepository privilegeRepository; + + @Autowired + private OrganizationRepository organizationRepository; + + @Autowired + private PasswordEncoder encoder; + + @PostConstruct + public void init() { + initOrganizations(); + initPrivileges(); + initUsers(); + } + + private void initUsers() { + final Privilege privilege1 = privilegeRepository.findByName("FOO_READ_PRIVILEGE"); + final Privilege privilege2 = privilegeRepository.findByName("FOO_WRITE_PRIVILEGE"); + // + final User user1 = new User(); + user1.setUsername("john"); + user1.setPassword(encoder.encode("123")); + user1.setPrivileges(new HashSet(Arrays.asList(privilege1))); + user1.setOrganization(organizationRepository.findByName("FirstOrg")); + userRepository.save(user1); + // + final User user2 = new User(); + user2.setUsername("tom"); + user2.setPassword(encoder.encode("111")); + user2.setPrivileges(new HashSet(Arrays.asList(privilege1, privilege2))); + user2.setOrganization(organizationRepository.findByName("SecondOrg")); + userRepository.save(user2); + } + + private void initOrganizations() { + final Organization org1 = new Organization("FirstOrg"); + organizationRepository.save(org1); + // + final Organization org2 = new Organization("SecondOrg"); + organizationRepository.save(org2); + } + + private void initPrivileges() { + final Privilege privilege1 = new Privilege("FOO_READ_PRIVILEGE"); + privilegeRepository.save(privilege1); + // + final Privilege privilege2 = new Privilege("FOO_WRITE_PRIVILEGE"); + privilegeRepository.save(privilege2); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java new file mode 100644 index 0000000000..1319a7b9f8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java @@ -0,0 +1,10 @@ +package org.baeldung.custom.persistence.dao; + +import org.baeldung.custom.persistence.model.Organization; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrganizationRepository extends JpaRepository { + + public Organization findByName(String name); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java new file mode 100644 index 0000000000..c232bb986c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java @@ -0,0 +1,10 @@ +package org.baeldung.custom.persistence.dao; + +import org.baeldung.custom.persistence.model.Privilege; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PrivilegeRepository extends JpaRepository { + + public Privilege findByName(String name); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java new file mode 100644 index 0000000000..68dd1d756c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java @@ -0,0 +1,14 @@ +package org.baeldung.custom.persistence.dao; + +import org.baeldung.custom.persistence.model.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; + +public interface UserRepository extends JpaRepository { + + User findByUsername(final String username); + + @Transactional + void removeUserByUsername(String username); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Foo.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Foo.java new file mode 100644 index 0000000000..f139382eea --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Foo.java @@ -0,0 +1,94 @@ +package org.baeldung.custom.persistence.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Foo { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String name; + + // + + public Foo() { + super(); + } + + public Foo(String name) { + super(); + this.name = name; + } + + // + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + // + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Foo [id=").append(id).append(", name=").append(name).append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((id == null) ? 0 : id.hashCode()); + result = (prime * result) + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Foo other = (Foo) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Organization.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Organization.java new file mode 100644 index 0000000000..1fdb88e320 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Organization.java @@ -0,0 +1,95 @@ +package org.baeldung.custom.persistence.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Organization { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false, unique = true) + private String name; + + // + + public Organization() { + super(); + } + + public Organization(String name) { + super(); + this.name = name; + } + + // + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + // + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Organization [id=").append(id).append(", name=").append(name).append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((id == null) ? 0 : id.hashCode()); + result = (prime * result) + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Organization other = (Organization) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Privilege.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Privilege.java new file mode 100644 index 0000000000..ed3edd5085 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/Privilege.java @@ -0,0 +1,95 @@ +package org.baeldung.custom.persistence.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Privilege { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false, unique = true) + private String name; + + // + + public Privilege() { + super(); + } + + public Privilege(String name) { + super(); + this.name = name; + } + + // + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + // + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Privilege [id=").append(id).append(", name=").append(name).append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((id == null) ? 0 : id.hashCode()); + result = (prime * result) + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Privilege other = (Privilege) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/User.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/User.java new file mode 100644 index 0000000000..c14ef034b4 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/persistence/model/User.java @@ -0,0 +1,155 @@ +package org.baeldung.custom.persistence.model; + +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "user_table") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false, unique = true) + private String username; + + private String password; + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "users_privileges", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id")) + private Set privileges; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "organization_id", referencedColumnName = "id") + private Organization organization; + + // + + public User() { + super(); + } + + // + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Set getPrivileges() { + return privileges; + } + + public void setPrivileges(Set privileges) { + this.privileges = privileges; + } + + public Organization getOrganization() { + return organization; + } + + public void setOrganization(Organization organization) { + this.organization = organization; + } + + // + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("User [id=").append(id).append(", username=").append(username).append(", password=").append(password).append(", privileges=").append(privileges).append(", organization=").append(organization).append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + ((id == null) ? 0 : id.hashCode()); + result = (prime * result) + ((organization == null) ? 0 : organization.hashCode()); + result = (prime * result) + ((password == null) ? 0 : password.hashCode()); + result = (prime * result) + ((privileges == null) ? 0 : privileges.hashCode()); + result = (prime * result) + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final User other = (User) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (organization == null) { + if (other.organization != null) { + return false; + } + } else if (!organization.equals(other.organization)) { + return false; + } + if (password == null) { + if (other.password != null) { + return false; + } + } else if (!password.equals(other.password)) { + return false; + } + if (privileges == null) { + if (other.privileges != null) { + return false; + } + } else if (!privileges.equals(other.privileges)) { + return false; + } + if (username == null) { + if (other.username != null) { + return false; + } + } else if (!username.equals(other.username)) { + return false; + } + return true; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java new file mode 100644 index 0000000000..646f5a387f --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java @@ -0,0 +1,22 @@ +package org.baeldung.custom.security; + +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; +import org.springframework.security.core.Authentication; + +public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { + private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); + + @Override + protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { + // final CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication); + final MySecurityExpressionRoot root = new MySecurityExpressionRoot(authentication); + root.setPermissionEvaluator(getPermissionEvaluator()); + root.setTrustResolver(this.trustResolver); + root.setRoleHierarchy(getRoleHierarchy()); + return root; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java new file mode 100644 index 0000000000..b2f2be8cf5 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java @@ -0,0 +1,50 @@ +package org.baeldung.custom.security; + +import org.baeldung.custom.persistence.model.User; +import org.springframework.security.access.expression.SecurityExpressionRoot; +import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; +import org.springframework.security.core.Authentication; + +public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations { + + private Object filterObject; + private Object returnObject; + + public CustomMethodSecurityExpressionRoot(Authentication authentication) { + super(authentication); + } + + // + public boolean isMember(Long OrganizationId) { + final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); + return user.getOrganization().getId().longValue() == OrganizationId.longValue(); + } + + // + + @Override + public Object getFilterObject() { + return this.filterObject; + } + + @Override + public Object getReturnObject() { + return this.returnObject; + } + + @Override + public Object getThis() { + return this; + } + + @Override + public void setFilterObject(Object obj) { + this.filterObject = obj; + } + + @Override + public void setReturnObject(Object obj) { + this.returnObject = obj; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java new file mode 100644 index 0000000000..f436b4488b --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java @@ -0,0 +1,40 @@ +package org.baeldung.custom.security; + +import java.io.Serializable; + +import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; + +public class CustomPermissionEvaluator implements PermissionEvaluator { + + @Override + public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) { + if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)) { + return false; + } + final String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase(); + return hasPrivilege(auth, targetType, permission.toString().toUpperCase()); + } + + @Override + public boolean hasPermission(Authentication auth, Serializable targetId, String targetType, Object permission) { + if ((auth == null) || (targetType == null) || !(permission instanceof String)) { + return false; + } + return hasPrivilege(auth, targetType.toUpperCase(), permission.toString().toUpperCase()); + } + + private boolean hasPrivilege(Authentication auth, String targetType, String permission) { + for (final GrantedAuthority grantedAuth : auth.getAuthorities()) { + System.out.println("here " + grantedAuth); + if (grantedAuth.getAuthority().startsWith(targetType)) { + if (grantedAuth.getAuthority().contains(permission)) { + return true; + } + } + } + return false; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java new file mode 100644 index 0000000000..03d18cb755 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java @@ -0,0 +1,203 @@ +package org.baeldung.custom.security; + +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.baeldung.custom.persistence.model.User; +import org.springframework.security.access.PermissionEvaluator; +import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; +import org.springframework.security.access.hierarchicalroles.RoleHierarchy; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; + +public class MySecurityExpressionRoot implements MethodSecurityExpressionOperations { + protected final Authentication authentication; + private AuthenticationTrustResolver trustResolver; + private RoleHierarchy roleHierarchy; + private Set roles; + private String defaultRolePrefix = "ROLE_"; + + public final boolean permitAll = true; + public final boolean denyAll = false; + private PermissionEvaluator permissionEvaluator; + public final String read = "read"; + public final String write = "write"; + public final String create = "create"; + public final String delete = "delete"; + public final String admin = "administration"; + + // + + private Object filterObject; + private Object returnObject; + + public MySecurityExpressionRoot(Authentication authentication) { + if (authentication == null) { + throw new IllegalArgumentException("Authentication object cannot be null"); + } + this.authentication = authentication; + } + + @Override + public final boolean hasAuthority(String authority) { + throw new RuntimeException("method hasAuthority() not allowed"); + } + + // + public boolean isMember(Long OrganizationId) { + final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); + return user.getOrganization().getId().longValue() == OrganizationId.longValue(); + } + + // + + @Override + public final boolean hasAnyAuthority(String... authorities) { + return hasAnyAuthorityName(null, authorities); + } + + @Override + public final boolean hasRole(String role) { + return hasAnyRole(role); + } + + @Override + public final boolean hasAnyRole(String... roles) { + return hasAnyAuthorityName(defaultRolePrefix, roles); + } + + private boolean hasAnyAuthorityName(String prefix, String... roles) { + final Set roleSet = getAuthoritySet(); + + for (final String role : roles) { + final String defaultedRole = getRoleWithDefaultPrefix(prefix, role); + if (roleSet.contains(defaultedRole)) { + return true; + } + } + + return false; + } + + @Override + public final Authentication getAuthentication() { + return authentication; + } + + @Override + public final boolean permitAll() { + return true; + } + + @Override + public final boolean denyAll() { + return false; + } + + @Override + public final boolean isAnonymous() { + return trustResolver.isAnonymous(authentication); + } + + @Override + public final boolean isAuthenticated() { + return !isAnonymous(); + } + + @Override + public final boolean isRememberMe() { + return trustResolver.isRememberMe(authentication); + } + + @Override + public final boolean isFullyAuthenticated() { + return !trustResolver.isAnonymous(authentication) && !trustResolver.isRememberMe(authentication); + } + + public Object getPrincipal() { + return authentication.getPrincipal(); + } + + public void setTrustResolver(AuthenticationTrustResolver trustResolver) { + this.trustResolver = trustResolver; + } + + public void setRoleHierarchy(RoleHierarchy roleHierarchy) { + this.roleHierarchy = roleHierarchy; + } + + public void setDefaultRolePrefix(String defaultRolePrefix) { + this.defaultRolePrefix = defaultRolePrefix; + } + + private Set getAuthoritySet() { + if (roles == null) { + roles = new HashSet(); + Collection userAuthorities = authentication.getAuthorities(); + + if (roleHierarchy != null) { + userAuthorities = roleHierarchy.getReachableGrantedAuthorities(userAuthorities); + } + + roles = AuthorityUtils.authorityListToSet(userAuthorities); + } + + return roles; + } + + @Override + public boolean hasPermission(Object target, Object permission) { + return permissionEvaluator.hasPermission(authentication, target, permission); + } + + @Override + public boolean hasPermission(Object targetId, String targetType, Object permission) { + return permissionEvaluator.hasPermission(authentication, (Serializable) targetId, targetType, permission); + } + + public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) { + this.permissionEvaluator = permissionEvaluator; + } + + private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) { + if (role == null) { + return role; + } + if ((defaultRolePrefix == null) || (defaultRolePrefix.length() == 0)) { + return role; + } + if (role.startsWith(defaultRolePrefix)) { + return role; + } + return defaultRolePrefix + role; + } + + @Override + public Object getFilterObject() { + return this.filterObject; + } + + @Override + public Object getReturnObject() { + return this.returnObject; + } + + @Override + public Object getThis() { + return this; + } + + @Override + public void setFilterObject(Object obj) { + this.filterObject = obj; + } + + @Override + public void setReturnObject(Object obj) { + this.returnObject = obj; + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java new file mode 100644 index 0000000000..b9b40fbcb9 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java @@ -0,0 +1,31 @@ +package org.baeldung.custom.security; + +import org.baeldung.custom.persistence.dao.UserRepository; +import org.baeldung.custom.persistence.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class MyUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + public MyUserDetailsService() { + super(); + } + + // API + + @Override + public UserDetails loadUserByUsername(final String username) { + final User user = userRepository.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException(username); + } + return new MyUserPrincipal(user); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java new file mode 100644 index 0000000000..7d57227316 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java @@ -0,0 +1,72 @@ +package org.baeldung.custom.security; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.baeldung.custom.persistence.model.Privilege; +import org.baeldung.custom.persistence.model.User; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +public class MyUserPrincipal implements UserDetails { + + private static final long serialVersionUID = 1L; + + private final User user; + + // + + public MyUserPrincipal(User user) { + this.user = user; + } + + // + + @Override + public String getUsername() { + return user.getUsername(); + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public Collection getAuthorities() { + final List authorities = new ArrayList(); + for (final Privilege privilege : user.getPrivileges()) { + authorities.add(new SimpleGrantedAuthority(privilege.getName())); + } + return authorities; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + // + + public User getUser() { + return user; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/web/MainController.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/web/MainController.java new file mode 100644 index 0000000000..74de45d1a8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/web/MainController.java @@ -0,0 +1,68 @@ +package org.baeldung.custom.web; + +import org.baeldung.custom.persistence.dao.OrganizationRepository; +import org.baeldung.custom.persistence.model.Foo; +import org.baeldung.custom.persistence.model.Organization; +import org.baeldung.custom.security.MyUserPrincipal; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Controller +public class MainController { + + @Autowired + private OrganizationRepository organizationRepository; + + // @PostAuthorize("hasPermission(returnObject, 'read')") + @PreAuthorize("hasPermission(#id, 'Foo', 'read')") + @GetMapping("/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id) { + return new Foo("Sample"); + } + + @PreAuthorize("hasPermission(#foo, 'write')") + @PostMapping("/foos") + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + public Foo create(@RequestBody final Foo foo) { + return foo; + } + + // + + @PreAuthorize("hasAuthority('FOO_READ_PRIVILEGE')") + @GetMapping("/foos") + @ResponseBody + public Foo findFooByName(@RequestParam final String name) { + return new Foo(name); + } + + // + + @PreAuthorize("isMember(#id)") + @GetMapping("/organizations/{id}") + @ResponseBody + public Organization findOrgById(@PathVariable final long id) { + return organizationRepository.findById(id) + .orElse(null); + } + + @PreAuthorize("hasPermission(#id, 'Foo', 'read')") + @GetMapping("/user") + @ResponseBody + public MyUserPrincipal retrieveUserDetails(@AuthenticationPrincipal MyUserPrincipal principal) { + return principal; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java new file mode 100644 index 0000000000..b68abbaed1 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java @@ -0,0 +1,14 @@ +package org.baeldung.ip; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +public class IpApplication extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(IpApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java new file mode 100644 index 0000000000..078dd81259 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java @@ -0,0 +1,53 @@ +package org.baeldung.ip.config; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Component; + +@Component +public class CustomIpAuthenticationProvider implements AuthenticationProvider { + + Set whitelist = new HashSet(); + + public CustomIpAuthenticationProvider() { + super(); + whitelist.add("11.11.11.11"); + whitelist.add("127.0.0.1"); + } + + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails(); + String userIp = details.getRemoteAddress(); + if(! whitelist.contains(userIp)){ + throw new BadCredentialsException("Invalid IP Address"); + } + final String name = auth.getName(); + final String password = auth.getCredentials().toString(); + + if (name.equals("john") && password.equals("123")) { + List authorities =new ArrayList(); + authorities.add(new SimpleGrantedAuthority("ROLE_USER")); + return new UsernamePasswordAuthenticationToken(name, password, authorities); + } + else{ + throw new BadCredentialsException("Invalid username or password"); + } + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityConfig.java new file mode 100644 index 0000000000..3a8032a734 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityConfig.java @@ -0,0 +1,36 @@ +package org.baeldung.ip.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity//(debug = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomIpAuthenticationProvider authenticationProvider; + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("john").password("{noop}123").authorities("ROLE_USER"); + // auth.authenticationProvider(authenticationProvider); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers("/login").permitAll() +// .antMatchers("/foos/**").hasIpAddress("11.11.11.11") + .antMatchers("/foos/**").access("isAuthenticated() and hasIpAddress('11.11.11.11')") + .anyRequest().authenticated() + .and().formLogin().permitAll() + .and().csrf().disable(); + // @formatter:on + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java new file mode 100644 index 0000000000..1d22ca4c67 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java @@ -0,0 +1,9 @@ +package org.baeldung.ip.config; + + +//@Configuration +//@EnableWebSecurity +//@ImportResource({ "classpath:spring-security-ip.xml" }) +public class SecurityXmlConfig { + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/web/MainController.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/web/MainController.java new file mode 100644 index 0000000000..940194c421 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/web/MainController.java @@ -0,0 +1,42 @@ +package org.baeldung.ip.web; + +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.http.HttpServletRequest; + +import org.baeldung.custom.persistence.model.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class MainController { + + @Autowired + @Qualifier("springSecurityFilterChain") + private Filter springSecurityFilterChain; + + @RequestMapping(method = RequestMethod.GET, value = "/filters") + @ResponseBody + public void getFilters() { + FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain; + List list = filterChainProxy.getFilterChains(); + list.stream() + .flatMap(chain -> chain.getFilters().stream()) + .forEach(filter -> System.out.println(filter.getClass())); + } + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id, HttpServletRequest request) { + return new Foo("Sample"); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java new file mode 100644 index 0000000000..d7195ac358 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java @@ -0,0 +1,38 @@ +package org.baeldung.rolesauthorities; + +import org.baeldung.rolesauthorities.model.User; +import org.baeldung.rolesauthorities.persistence.UserRepository; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetailsService; + +public class CustomAuthenticationProvider extends DaoAuthenticationProvider { + + private final UserRepository userRepository; + @SuppressWarnings("unused") + private UserDetailsService userDetailsService; + + public CustomAuthenticationProvider(UserRepository userRepository, UserDetailsService userDetailsService){ + super(); + this.setUserDetailsService(userDetailsService); + this.userRepository = userRepository; + } + + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + final User user = userRepository.findByEmail(auth.getName()); + if ((user == null)) { + throw new BadCredentialsException("Invalid username or password"); + } + final Authentication result = super.authenticate(auth); + return new UsernamePasswordAuthenticationToken(user, result.getCredentials(), result.getAuthorities()); + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java new file mode 100644 index 0000000000..b0dc0b7537 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java @@ -0,0 +1,26 @@ +package org.baeldung.rolesauthorities; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.stereotype.Component; + +@Component("myLogoutSuccessHandler") +public class MyLogoutSuccessHandler implements LogoutSuccessHandler { + + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + final HttpSession session = request.getSession(); + if (session != null) { + session.removeAttribute("user"); + } + + response.sendRedirect("/"); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java new file mode 100644 index 0000000000..f38b867a75 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java @@ -0,0 +1,61 @@ +package org.baeldung.rolesauthorities; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.baeldung.rolesauthorities.model.Role; +import org.baeldung.rolesauthorities.model.User; +import org.baeldung.rolesauthorities.persistence.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("userDetailsService") +@Transactional +public class MyUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + public MyUserDetailsService() { + super(); + } + + // API + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + + try { + User user = userRepository.findByEmail(email); + if (user == null) { + throw new UsernameNotFoundException("No user found with username: " + email); + } + org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, getAuthorities(user.getRoles())); + return userDetails; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + // UTIL + + private final Collection getAuthorities(Collection roles) { + List authorities = new ArrayList(); + for (Role role: roles) { + authorities.add(new SimpleGrantedAuthority(role.getName())); + authorities.addAll(role.getPrivileges() + .stream() + .map(p -> new SimpleGrantedAuthority(p.getName())) + .collect(Collectors.toList())); + } + return authorities; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java new file mode 100644 index 0000000000..3c4e6f7b5a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java @@ -0,0 +1,17 @@ +package org.baeldung.rolesauthorities; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan("org.baeldung.rolesauthorities") +public class RolesAuthoritiesApplication extends SpringBootServletInitializer { + public static void main(String[] args) { + System.setProperty("spring.profiles.default", "rolesauthorities"); + SpringApplication.run(RolesAuthoritiesApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java new file mode 100644 index 0000000000..c42958457e --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java @@ -0,0 +1,46 @@ +package org.baeldung.rolesauthorities.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class MvcConfig implements WebMvcConfigurer { + + public MvcConfig() { + super(); + } + + // + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("forward:/home"); + registry.addViewController("/protectedbynothing").setViewName("rolesauthorities/protectedbynothing"); + registry.addViewController("/protectedbyrole").setViewName("rolesauthorities/protectedbyrole"); + registry.addViewController("/protectedbyauthority").setViewName("rolesauthorities/protectedbyauthority"); + registry.addViewController("/login").setViewName("rolesauthorities/login"); + registry.addViewController("/home").setViewName("rolesauthorities/home"); + registry.addViewController("/logout"); + } + + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java new file mode 100644 index 0000000000..7624dd7d39 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java @@ -0,0 +1,90 @@ +package org.baeldung.rolesauthorities.config; + +import org.baeldung.rolesauthorities.CustomAuthenticationProvider; +import org.baeldung.rolesauthorities.persistence.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +@Configuration +@ComponentScan(basePackages = { "org.baeldung.rolesauthorities" }) +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserRepository userRepository; + + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private LogoutSuccessHandler myLogoutSuccessHandler; + + public SecurityConfig() { + super(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(authProvider()); + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring() + .antMatchers("/resources/**"); + } + + + @Override + protected void configure(HttpSecurity http) throws Exception { + + // @formatter:off + http + .csrf().disable() + .authorizeRequests() + .antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll() + .antMatchers("/protectedbyrole").hasRole("USER") + .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE") + .and() + .formLogin() + .loginPage("/login") + .failureUrl("/login?error=true") + .permitAll() + .and() + .logout() + .logoutSuccessHandler(myLogoutSuccessHandler) + .invalidateHttpSession(false) + .logoutSuccessUrl("/logout.html?logSucc=true") + .deleteCookies("JSESSIONID") + .permitAll(); + // @formatter:on + } + + // beans + + @Bean + public DaoAuthenticationProvider authProvider() { + final CustomAuthenticationProvider authProvider + = new CustomAuthenticationProvider(userRepository, userDetailsService); + authProvider.setPasswordEncoder(encoder()); + return authProvider; + } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(11); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java new file mode 100644 index 0000000000..ab2cd08610 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java @@ -0,0 +1,89 @@ +package org.baeldung.rolesauthorities.model; + +import java.util.Collection; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; + +@Entity +public class Privilege { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + @ManyToMany(mappedBy = "privileges") + private Collection roles; + + public Privilege() { + super(); + } + + public Privilege(String name) { + super(); + this.name = name; + } + + // + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Collection getRoles() { + return roles; + } + + public void setRoles(Collection roles) { + this.roles = roles; + } + + @Override + public int hashCode() { + int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Privilege other = (Privilege) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Privilege [name=").append(name).append("]").append("[id=").append(id).append("]"); + return builder.toString(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Role.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Role.java new file mode 100644 index 0000000000..ac33e32fcf --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/Role.java @@ -0,0 +1,104 @@ +package org.baeldung.rolesauthorities.model; + +import java.util.Collection; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; + +@Entity +public class Role { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToMany(mappedBy = "roles") + private Collection users; + + @ManyToMany + @JoinTable(name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id")) + private Collection privileges; + + private String name; + + public Role() { + super(); + } + + public Role(String name) { + super(); + this.name = name; + } + + // + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Collection getUsers() { + return users; + } + + public void setUsers(Collection users) { + this.users = users; + } + + public Collection getPrivileges() { + return privileges; + } + + public void setPrivileges(Collection privileges) { + this.privileges = privileges; + } + + @Override + public int hashCode() { + int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Role role = (Role) obj; + if (!role.equals(role.name)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Role [name=").append(name).append("]").append("[id=").append(id).append("]"); + return builder.toString(); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/User.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/User.java new file mode 100644 index 0000000000..dc1096541d --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/model/User.java @@ -0,0 +1,147 @@ +package org.baeldung.rolesauthorities.model; + +import java.util.Collection; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + + +@Entity +@Table(name = "user_account") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String firstName; + + private String lastName; + + private String email; + + @Column(length = 60) + private String password; + + private boolean enabled; + + private boolean isUsing2FA; + + // + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) + private Collection roles; + + public User() { + super(); + this.enabled = false; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String username) { + this.email = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Collection getRoles() { + return roles; + } + + public void setRoles(Collection roles) { + this.roles = roles; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isUsing2FA() { + return isUsing2FA; + } + + public void setUsing2FA(boolean isUsing2FA) { + this.isUsing2FA = isUsing2FA; + } + + @Override + public int hashCode() { + int prime = 31; + int result = 1; + result = (prime * result) + ((email == null) ? 0 : email.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + User user = (User) obj; + if (!email.equals(user.email)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("User [id=").append(id).append(", firstName=") + .append(firstName).append(", lastName=").append(lastName).append(", email=").append(email).append(", password=").append(password).append(", enabled=").append(enabled).append(", roles=").append(roles).append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java new file mode 100644 index 0000000000..2c508cbd20 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java @@ -0,0 +1,9 @@ +package org.baeldung.rolesauthorities.persistence; + +import org.baeldung.rolesauthorities.model.User; + +public interface IUserService { + + User findUserByEmail(String email); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java new file mode 100644 index 0000000000..05d5f2b870 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java @@ -0,0 +1,12 @@ +package org.baeldung.rolesauthorities.persistence; + +import org.baeldung.rolesauthorities.model.Privilege; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PrivilegeRepository extends JpaRepository { + + Privilege findByName(String name); + + void delete(Privilege privilege); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java new file mode 100644 index 0000000000..25e3b3a1f6 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java @@ -0,0 +1,12 @@ +package org.baeldung.rolesauthorities.persistence; + +import org.baeldung.rolesauthorities.model.Role; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RoleRepository extends JpaRepository { + + Role findByName(String name); + + void delete(Role role); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java new file mode 100644 index 0000000000..46dad4f06d --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java @@ -0,0 +1,97 @@ +package org.baeldung.rolesauthorities.persistence; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.baeldung.rolesauthorities.model.Privilege; +import org.baeldung.rolesauthorities.model.Role; +import org.baeldung.rolesauthorities.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + + +@Component +public class SetupDataLoader implements ApplicationListener { + + private boolean alreadySetup = false; + + @Autowired + private UserRepository userRepository; + + @Autowired + private RoleRepository roleRepository; + + @Autowired + private PrivilegeRepository privilegeRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + @Transactional + public void onApplicationEvent(ContextRefreshedEvent event) { + if (alreadySetup) { + return; + } + + // == create initial privileges + Privilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE"); + Privilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE"); + + // == create initial roles + List adminPrivileges = Arrays.asList(readPrivilege, writePrivilege); + createRoleIfNotFound("ROLE_ADMIN", adminPrivileges); + List rolePrivileges = new ArrayList<>(); + createRoleIfNotFound("ROLE_USER", rolePrivileges); + + Role adminRole = roleRepository.findByName("ROLE_ADMIN"); + User user = new User(); + user.setFirstName("Admin"); + user.setLastName("Admin"); + user.setEmail("admin@test.com"); + user.setPassword(passwordEncoder.encode("admin")); + user.setRoles(Arrays.asList(adminRole)); + user.setEnabled(true); + userRepository.save(user); + + Role basicRole = roleRepository.findByName("ROLE_USER"); + User basicUser = new User(); + basicUser.setFirstName("User"); + basicUser.setLastName("User"); + basicUser.setEmail("user@test.com"); + basicUser.setPassword(passwordEncoder.encode("user")); + basicUser.setRoles(Arrays.asList(basicRole)); + basicUser.setEnabled(true); + userRepository.save(basicUser); + + alreadySetup = true; + } + + @Transactional + private Privilege createPrivilegeIfNotFound(String name) { + Privilege privilege = privilegeRepository.findByName(name); + if (privilege == null) { + privilege = new Privilege(name); + privilegeRepository.save(privilege); + } + return privilege; + } + + @Transactional + private Role createRoleIfNotFound(String name, Collection privileges) { + Role role = roleRepository.findByName(name); + if (role == null) { + role = new Role(name); + role.setPrivileges(privileges); + roleRepository.save(role); + } + return role; + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java new file mode 100644 index 0000000000..bca2953153 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java @@ -0,0 +1,12 @@ +package org.baeldung.rolesauthorities.persistence; + +import org.baeldung.rolesauthorities.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + + User findByEmail(String email); + + void delete(User user); + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java new file mode 100644 index 0000000000..3b16c78898 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java @@ -0,0 +1,19 @@ +package org.baeldung.rolesauthorities.persistence; + +import javax.transaction.Transactional; + +import org.baeldung.rolesauthorities.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@Transactional +public class UserService implements IUserService { + + @Autowired + private UserRepository repository; + + public User findUserByEmail(String email) { + return repository.findByEmail(email); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/MinuteBasedVoter.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/MinuteBasedVoter.java new file mode 100644 index 0000000000..2beda1e557 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/MinuteBasedVoter.java @@ -0,0 +1,26 @@ +package org.baeldung.voter; + +import java.time.LocalDateTime; +import java.util.Collection; + +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; + +public class MinuteBasedVoter implements AccessDecisionVoter { + @Override + public boolean supports(ConfigAttribute attribute) { + return true; + } + + @Override + public boolean supports(Class clazz) { + return true; + } + + @Override + public int vote(Authentication authentication, Object object, Collection collection) { + return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).filter(r -> "ROLE_USER".equals(r) && LocalDateTime.now().getMinute() % 2 != 0).findAny().map(s -> ACCESS_DENIED).orElseGet(() -> ACCESS_ABSTAIN); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterApplication.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterApplication.java new file mode 100644 index 0000000000..d2078e6115 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterApplication.java @@ -0,0 +1,16 @@ +package org.baeldung.voter; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan(basePackages = { "org.baeldung.voter" }) +public class VoterApplication { + + public static void main(String[] args) { + SpringApplication.run(VoterApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterMvcConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterMvcConfig.java new file mode 100644 index 0000000000..8f41153f06 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/VoterMvcConfig.java @@ -0,0 +1,19 @@ +package org.baeldung.voter; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * Created by ambrusadrianz on 30/09/2016. + */ + +@Configuration +public class VoterMvcConfig implements WebMvcConfigurer { + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("private"); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/WebSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/WebSecurityConfig.java new file mode 100644 index 0000000000..84ed070e8e --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/WebSecurityConfig.java @@ -0,0 +1,55 @@ +package org.baeldung.voter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.vote.AuthenticatedVoter; +import org.springframework.security.access.vote.RoleVoter; +import org.springframework.security.access.vote.UnanimousBased; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.access.expression.WebExpressionVoter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import java.util.Arrays; +import java.util.List; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + // @formatter: off + auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("pass")).roles("USER").and().withUser("admin").password(passwordEncoder().encode("pass")).roles("ADMIN"); + // @formatter: on + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter: off + http + // needed so our login could work + .csrf().disable().authorizeRequests().anyRequest().authenticated().accessDecisionManager(accessDecisionManager()).antMatchers("/").hasAnyRole("ROLE_ADMIN", "ROLE_USER").and().formLogin().permitAll().and().logout().permitAll() + .deleteCookies("JSESSIONID").logoutSuccessUrl("/login"); + // @formatter: on + } + + @Bean + public AccessDecisionManager accessDecisionManager() { + // @formatter: off + List> decisionVoters = Arrays.asList(new WebExpressionVoter(), new RoleVoter(), new AuthenticatedVoter(), new MinuteBasedVoter()); + // @formatter: on + return new UnanimousBased(decisionVoters); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/XmlSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/XmlSecurityConfig.java new file mode 100644 index 0000000000..8041585f42 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/voter/XmlSecurityConfig.java @@ -0,0 +1,15 @@ +package org.baeldung.voter; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +/** + * Created by ambrusadrianz on 09/10/2016. + */ +// @Configuration +// @ImportResource({ "classpath:spring-security-custom-voter.xml" }) +public class XmlSecurityConfig { + public XmlSecurityConfig() { + super(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application-defaults.properties b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application-defaults.properties new file mode 100644 index 0000000000..e2032c4a6b --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application-defaults.properties @@ -0,0 +1,13 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.database=H2 +spring.jpa.show-sql=false +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + +#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG + +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application.properties b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application.properties new file mode 100644 index 0000000000..3cf12afeb9 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8082 diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/logback.xml b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/persistence-h2.properties b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..a4b2af6361 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/persistence-h2.properties @@ -0,0 +1,8 @@ +driverClassName=org.h2.Driver +url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1 +username=sa +password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-custom-voter.xml b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-custom-voter.xml new file mode 100644 index 0000000000..0b334a3694 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-custom-voter.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-ip.xml b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-ip.xml new file mode 100644 index 0000000000..31796ad134 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/spring-security-ip.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/403.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/403.html new file mode 100644 index 0000000000..20550768cf --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/403.html @@ -0,0 +1,10 @@ + + + + + + + +You do not have permission to view this page. + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/index.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/index.html new file mode 100644 index 0000000000..8e7394ad6a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/index.html @@ -0,0 +1,21 @@ + + + + +Spring Security Thymeleaf + + + + + +
+ Welcome +
+ + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/login.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/login.html new file mode 100644 index 0000000000..dd6bd04767 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/login.html @@ -0,0 +1,27 @@ + + + + +

Login

+ +
+ + + + + + + + + + + + + + +
User:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginAdmin.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginAdmin.html new file mode 100644 index 0000000000..43d0e73233 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginAdmin.html @@ -0,0 +1,31 @@ + + + + +Insert title here + + + +

Admin login page

+
+ + + + + + + + + + + + + +
User:
Password:
+ +
+ +

Login failed!

+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginUser.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginUser.html new file mode 100644 index 0000000000..bf4ddd48bc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/loginUser.html @@ -0,0 +1,30 @@ + + + + +Login + + + +

User login page

+ +
+ + + + + + + + + + + + +
User:
Password:
+ +
+

Login failed!

+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/login.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/login.html new file mode 100644 index 0000000000..2119baec66 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/login.html @@ -0,0 +1,27 @@ + + + + +

Login

+ +
+ + + + + + + + + + + + + + +
Username:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/loginWithWarning.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/loginWithWarning.html new file mode 100644 index 0000000000..a5b2eaf3dc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/loginWithWarning.html @@ -0,0 +1,28 @@ + + + + +

Login

+

Warning! You are about to access sensible data!

+ +
+ + + + + + + + + + + + + + +
Username:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html new file mode 100644 index 0000000000..676badb16f --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html @@ -0,0 +1,18 @@ + + + + +Multiple Http Elements Links + + + +Admin page +
+User page +
+Private user page +
+Guest page + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myAdminPage.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myAdminPage.html new file mode 100644 index 0000000000..3003833562 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myAdminPage.html @@ -0,0 +1,13 @@ + + + + +Admin Page + + +Welcome admin! + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myGuestPage.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myGuestPage.html new file mode 100644 index 0000000000..47a4c9c44a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myGuestPage.html @@ -0,0 +1,13 @@ + + + + +Guest Page + + +Welcome guest! + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html new file mode 100644 index 0000000000..52045ec320 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html @@ -0,0 +1,13 @@ + + + + +Insert title here + + +Welcome user to your private page! Logout + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myUserPage.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myUserPage.html new file mode 100644 index 0000000000..f6c2def0b8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/multipleHttpElems/myUserPage.html @@ -0,0 +1,13 @@ + + + + +User Page + + +Welcome user! Logout + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/private.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/private.html new file mode 100644 index 0000000000..035d84bbbd --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/private.html @@ -0,0 +1,10 @@ + + + + Private + + +

Congrats!

+ + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/home.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/home.html new file mode 100644 index 0000000000..a302721570 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/home.html @@ -0,0 +1,25 @@ + + + + + +Role vs Granted Authority Example + + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/login.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/login.html new file mode 100644 index 0000000000..eacde18459 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/login.html @@ -0,0 +1,57 @@ + + + + +Login + + + + + + +
+
+

Login

+

+ +
+ + + + +

+ + + +

+ + +
+
+
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyauthority.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyauthority.html new file mode 100644 index 0000000000..c62a111ebc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyauthority.html @@ -0,0 +1,24 @@ + + + + +Protected By Authority + + + +
+

Protected By Authority

+
+ + + + diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbynothing.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbynothing.html new file mode 100644 index 0000000000..a6cd0666db --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbynothing.html @@ -0,0 +1,21 @@ + + + + +Protected By Nothing + + + +
+

Protected By Nothing

+
+ + + + diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyrole.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyrole.html new file mode 100644 index 0000000000..f4bac55b55 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/rolesauthorities/protectedbyrole.html @@ -0,0 +1,24 @@ + + + + +Protected By Role + + + +
+

Protected By Role

+
+ + + + diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/ssl/welcome.html b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/ssl/welcome.html new file mode 100644 index 0000000000..93b3577f5c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/resources/templates/ssl/welcome.html @@ -0,0 +1 @@ +

Welcome to Secured Site

\ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java new file mode 100644 index 0000000000..b2def82c51 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java @@ -0,0 +1,112 @@ +package com.baeldung.relationships; + +import com.baeldung.AppConfig; +import com.baeldung.data.repositories.TweetRepository; +import com.baeldung.data.repositories.UserRepository; +import com.baeldung.models.AppUser; +import com.baeldung.models.Tweet; +import com.baeldung.security.AppUserPrincipal; +import com.baeldung.util.DummyContentUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.jdbc.JdbcTestUtils; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +import javax.servlet.ServletContext; +import java.util.Date; +import java.util.List; + +import static org.springframework.util.Assert.isTrue; + +@RunWith(SpringRunner.class) +@WebAppConfiguration +@ContextConfiguration +@DirtiesContext +public class SpringDataWithSecurityIntegrationTest { + AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); + @Autowired + private ServletContext servletContext; + private static UserRepository userRepository; + private static TweetRepository tweetRepository; + + @Before + public void testInit() { + ctx.register(AppConfig.class); + ctx.setServletContext(servletContext); + ctx.refresh(); + userRepository = ctx.getBean(UserRepository.class); + tweetRepository = ctx.getBean(TweetRepository.class); + List appUsers = (List) userRepository.saveAll(DummyContentUtil.generateDummyUsers()); + tweetRepository.saveAll(DummyContentUtil.generateDummyTweets(appUsers)); + } + + /** + * This is to ensure the tables are dropped in proper order. + * After the Spring Boot 2.2.2 upgrade, DDL statements generated automatically try to drop Tweet table first. + * As a result we get org.h2.jdbc.JdbcSQLSyntaxErrorException because Tweet_Likes table depends on Tweet. + * + * @see + * StackOverflow#59364212 + * + * @see + * StackOverflow#59561551 + * + */ + @After + public void tearDown() { + JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class); + JdbcTestUtils.dropTables(jdbcTemplate, "Tweet_Likes", "Tweet"); + } + + @Test + public void givenAppUser_whenLoginSuccessful_shouldUpdateLastLogin() { + AppUser appUser = userRepository.findByUsername("lionel@messi.com"); + Authentication auth = new UsernamePasswordAuthenticationToken(new AppUserPrincipal(appUser), null, DummyContentUtil.getAuthorities()); + SecurityContextHolder.getContext() + .setAuthentication(auth); + userRepository.updateLastLogin(new Date()); + } + + @Test(expected = InvalidDataAccessApiUsageException.class) + public void givenNoAppUserInSecurityContext_whenUpdateLastLoginAttempted_shouldFail() { + userRepository.updateLastLogin(new Date()); + } + + @Test + public void givenAppUser_whenLoginSuccessful_shouldReadMyPagedTweets() { + AppUser appUser = userRepository.findByUsername("lionel@messi.com"); + Authentication auth = new UsernamePasswordAuthenticationToken(new AppUserPrincipal(appUser), null, DummyContentUtil.getAuthorities()); + SecurityContextHolder.getContext() + .setAuthentication(auth); + Page page = null; + do { + page = tweetRepository.getMyTweetsAndTheOnesILiked(PageRequest.of(page != null ? page.getNumber() + 1 : 0, 5)); + for (Tweet twt : page.getContent()) { + isTrue((twt.getOwner() == appUser.getUsername()) || (twt.getLikes() + .contains(appUser.getUsername())), "I do not have any Tweets"); + } + } while (page.hasNext()); + } + + @Test(expected = InvalidDataAccessApiUsageException.class) + public void givenNoAppUser_whenPaginatedResultsRetrievalAttempted_shouldFail() { + Page page = null; + do { + page = tweetRepository.getMyTweetsAndTheOnesILiked(PageRequest.of(page != null ? page.getNumber() + 1 : 0, 5)); + } while (page != null && page.hasNext()); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..2041249b71 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/SpringContextTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.custom.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java new file mode 100644 index 0000000000..dfcfcad609 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java @@ -0,0 +1,67 @@ +package org.baeldung.web; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.baeldung.custom.persistence.model.Foo; + +import io.restassured.RestAssured; +import io.restassured.authentication.FormAuthConfig; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; + +import org.junit.Test; +import org.springframework.http.MediaType; + + +public class ApplicationLiveTest { + + @Test + public void givenUserWithReadPrivilegeAndHasPermission_whenGetFooById_thenOK() { + final Response response = givenAuth("john", "123").get("http://localhost:8082/foos/1"); + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("id")); + } + + @Test + public void givenUserWithNoWritePrivilegeAndHasPermission_whenPostFoo_thenForbidden() { + final Response response = givenAuth("john", "123").contentType(MediaType.APPLICATION_JSON_VALUE).body(new Foo("sample")).post("http://localhost:8082/foos"); + assertEquals(403, response.getStatusCode()); + } + + @Test + public void givenUserWithWritePrivilegeAndHasPermission_whenPostFoo_thenOk() { + final Response response = givenAuth("tom", "111").and().body(new Foo("sample")).and().contentType(MediaType.APPLICATION_JSON_VALUE).post("http://localhost:8082/foos"); + assertEquals(201, response.getStatusCode()); + assertTrue(response.asString().contains("id")); + } + + // + + @Test + public void givenUserMemberInOrganization_whenGetOrganization_thenOK() { + final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/1"); + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("id")); + } + + @Test + public void givenUserMemberNotInOrganization_whenGetOrganization_thenForbidden() { + final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/2"); + assertEquals(403, response.getStatusCode()); + } + + // + + @Test + public void givenDisabledSecurityExpression_whenGetFooByName_thenError() { + final Response response = givenAuth("john", "123").get("http://localhost:8082/foos?name=sample"); + assertEquals(500, response.getStatusCode()); + assertTrue(response.asString().contains("method hasAuthority() not allowed")); + } + + // + private RequestSpecification givenAuth(String username, String password) { + return RestAssured.given().log().uri().auth().form(username, password, new FormAuthConfig("/login","username","password")); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java new file mode 100644 index 0000000000..d16acc729a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java @@ -0,0 +1,89 @@ +package org.baeldung.web; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.apache.http.HttpHeaders; +import org.baeldung.custom.Application; +import org.baeldung.custom.persistence.model.Foo; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithAnonymousUser; +import org.springframework.security.test.context.support.WithUserDetails; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@SpringBootTest(classes = { Application.class }) +@AutoConfigureMockMvc +public class CustomUserDetailsServiceIntegrationTest { + + @Autowired + private MockMvc mvc; + + @Test + @WithUserDetails("john") + public void givenUserWithReadPermissions_whenRequestUserInfo_thenRetrieveUserData() throws Exception { + this.mvc.perform(get("/user").with(csrf())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.user.privileges[0].name").value("FOO_READ_PRIVILEGE")) + .andExpect(jsonPath("$.user.organization.name").value("FirstOrg")) + .andExpect(jsonPath("$.user.username").value("john")); + } + + @Test + @WithUserDetails("tom") + public void givenUserWithWritePermissions_whenRequestUserInfo_thenRetrieveUserData() throws Exception { + this.mvc.perform(get("/user").with(csrf())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.user.privileges").isArray()) + .andExpect(jsonPath("$.user.organization.name").value("SecondOrg")) + .andExpect(jsonPath("$.user.username").value("tom")); + } + + @Test + @WithUserDetails("john") + public void givenUserWithReadPermissions_whenRequestFoo_thenRetrieveSampleFoo() throws Exception { + this.mvc.perform(get("/foos/1").with(csrf())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.name").value("Sample")); + } + + @Test + @WithAnonymousUser + public void givenAnonymous_whenRequestFoo_thenRetrieveUnauthorized() throws Exception { + this.mvc.perform(get("/foos/1").with(csrf())) + .andExpect(status().isUnauthorized()); + } + + @Test + @WithUserDetails("john") + public void givenUserWithReadPermissions_whenCreateNewFoo_thenForbiddenStatusRetrieved() throws Exception { + this.mvc.perform(post("/foos").with(csrf()) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .content(asJsonString(new Foo()))) + .andExpect(status().isForbidden()); + } + + @Test + @WithUserDetails("tom") + public void givenUserWithWritePermissions_whenCreateNewFoo_thenOkStatusRetrieved() throws Exception { + this.mvc.perform(post("/foos").with(csrf()) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .content(asJsonString(new Foo()))) + .andExpect(status().isCreated()); + } + + private static String asJsonString(final Object obj) throws Exception { + final ObjectMapper mapper = new ObjectMapper(); + final String jsonContent = mapper.writeValueAsString(obj); + return jsonContent; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java new file mode 100644 index 0000000000..e12e2f87b0 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java @@ -0,0 +1,27 @@ +package org.baeldung.web; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.restassured.RestAssured; +import io.restassured.response.Response; + +import org.junit.Test; + + +public class IpLiveTest { + + @Test + public void givenUser_whenGetHomePage_thenOK() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/"); + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("Welcome")); + } + + @Test + public void givenUserWithWrongIP_whenGetFooById_thenForbidden() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/foos/1"); + assertEquals(403, response.getStatusCode()); + assertTrue(response.asString().contains("Forbidden")); + } + +} \ No newline at end of file From b9f2e1745667d1c399a3cef1bebe3280d9cbb056 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Mon, 17 Feb 2020 21:53:47 +0530 Subject: [PATCH 26/62] JAVA-6 : new module spring-security-mvc-boot-2 --- .../spring-security-mvc-boot-2/README.md | 13 + .../WebContent/META-INF/MANIFEST.MF | 3 + .../spring-security-mvc-boot-2/pom.xml | 246 ++++++++++++++++++ .../h2/H2JdbcAuthenticationApplication.java | 17 ++ .../h2/config/SecurityConfiguration.java | 51 ++++ .../h2/web/UserController.java | 17 ++ .../MySqlJdbcAuthenticationApplication.java | 15 ++ .../mysql/config/SecurityConfiguration.java | 35 +++ .../mysql/web/UserController.java | 17 ++ .../PostgreJdbcAuthenticationApplication.java | 15 ++ .../postgre/config/SecurityConfiguration.java | 29 +++ .../postgre/web/UserController.java | 17 ++ .../CustomAuthenticationProvider.java | 31 +++ .../MultipleAuthController.java | 13 + .../MultipleAuthProvidersApplication.java | 14 + .../MultipleAuthProvidersSecurityConfig.java | 42 +++ .../MultipleEntryPointsApplication.java | 14 + .../MultipleEntryPointsSecurityConfig.java | 99 +++++++ .../multipleentrypoints/PagesController.java | 48 ++++ .../MultipleLoginApplication.java | 15 ++ .../multiplelogin/MultipleLoginMvcConfig.java | 44 ++++ .../MultipleLoginSecurityConfig.java | 78 ++++++ .../multiplelogin/UsersController.java | 38 +++ .../baeldung/ssl/HttpsEnabledApplication.java | 16 ++ .../java/org/baeldung/ssl/SecurityConfig.java | 16 ++ .../org/baeldung/ssl/WelcomeController.java | 15 ++ .../resources/application-defaults.properties | 13 + .../resources/application-mysql.properties | 9 + .../resources/application-postgre.properties | 7 + .../main/resources/application-ssl.properties | 20 ++ .../src/main/resources/application.properties | 1 + .../src/main/resources/data-mysql.sql | 4 + .../src/main/resources/data-postgre.sql | 4 + .../src/main/resources/keystore/baeldung.p12 | Bin 0 -> 2603 bytes .../src/main/resources/logback.xml | 13 + .../main/resources/persistence-h2.properties | 8 + .../src/main/resources/schema-mysql.sql | 18 ++ .../src/main/resources/schema-postgre.sql | 16 ++ ...pring-security-multiple-auth-providers.xml | 24 ++ .../spring-security-multiple-entry.xml | 65 +++++ .../src/main/resources/templates/403.html | 10 + .../main/resources/templates/adminPage.html | 13 + .../src/main/resources/templates/index.html | 21 ++ .../src/main/resources/templates/login.html | 27 ++ .../main/resources/templates/loginAdmin.html | 31 +++ .../main/resources/templates/loginUser.html | 30 +++ .../templates/multipleHttpElems/login.html | 27 ++ .../multipleHttpElems/loginWithWarning.html | 28 ++ .../multipleHttpElems/multipleHttpLinks.html | 18 ++ .../multipleHttpElems/myAdminPage.html | 13 + .../multipleHttpElems/myGuestPage.html | 13 + .../multipleHttpElems/myPrivateUserPage.html | 13 + .../multipleHttpElems/myUserPage.html | 13 + .../src/main/resources/templates/private.html | 10 + .../resources/templates/protectedLinks.html | 13 + .../main/resources/templates/ssl/welcome.html | 1 + .../main/resources/templates/userPage.html | 12 + .../h2/SpringContextTest.java | 16 ++ .../h2/web/UserControllerLiveTest.java | 35 +++ .../mysql/web/UserControllerLiveTest.java | 35 +++ .../postgre/web/UserControllerLiveTest.java | 35 +++ .../web/HttpsApplicationIntegrationTest.java | 56 ++++ ...thProvidersApplicationIntegrationTest.java | 61 +++++ .../MultipleEntryPointsIntegrationTest.java | 67 +++++ 64 files changed, 1758 insertions(+) create mode 100644 spring-security-modules/spring-security-mvc-boot-2/README.md create mode 100644 spring-security-modules/spring-security-mvc-boot-2/WebContent/META-INF/MANIFEST.MF create mode 100644 spring-security-modules/spring-security-mvc-boot-2/pom.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/PagesController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/UsersController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/SecurityConfig.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/WelcomeController.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-defaults.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-mysql.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-postgre.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-ssl.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-mysql.sql create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-postgre.sql create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/keystore/baeldung.p12 create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/logback.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/persistence-h2.properties create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-mysql.sql create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-postgre.sql create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-auth-providers.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-entry.xml create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/403.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/adminPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/index.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/login.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginAdmin.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginUser.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/login.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/loginWithWarning.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myAdminPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myGuestPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myUserPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/private.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/protectedLinks.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/ssl/welcome.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/userPage.html create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java create mode 100644 spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java diff --git a/spring-security-modules/spring-security-mvc-boot-2/README.md b/spring-security-modules/spring-security-mvc-boot-2/README.md new file mode 100644 index 0000000000..3c95086d21 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/README.md @@ -0,0 +1,13 @@ +## Spring Boot Security MVC + +This module contains articles about Spring Security with Spring MVC in Boot applications + +### The Course +The "REST With Spring" Classes: http://github.learnspringsecurity.com + +### Relevant Articles: +- [Multiple Entry Points in Spring Security](https://www.baeldung.com/spring-security-multiple-entry-points) +- [Multiple Authentication Providers in Spring Security](https://www.baeldung.com/spring-security-multiple-auth-providers) +- [Two Login Pages with Spring Security](https://www.baeldung.com/spring-security-two-login-pages) +- [HTTPS using Self-Signed Certificate in Spring Boot](https://www.baeldung.com/spring-boot-https-self-signed-certificate) +- [Spring Security: Exploring JDBC Authentication](https://www.baeldung.com/spring-security-jdbc-authentication) \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/WebContent/META-INF/MANIFEST.MF b/spring-security-modules/spring-security-mvc-boot-2/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-security-modules/spring-security-mvc-boot-2/pom.xml b/spring-security-modules/spring-security-mvc-boot-2/pom.xml new file mode 100644 index 0000000000..fca38b9714 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/pom.xml @@ -0,0 +1,246 @@ + + + 4.0.0 + spring-security-mvc-boot-2 + 0.0.1-SNAPSHOT + spring-security-mvc-boot-2 + war + Spring Security MVC Boot - 2 + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.security + spring-security-data + + + mysql + mysql-connector-java + runtime + + + com.h2database + h2 + + + org.postgresql + postgresql + runtime + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + org.springframework + spring-test + test + + + org.springframework.security + spring-security-test + test + + + taglibs + standard + ${taglibs-standard.version} + + + org.springframework.security + spring-security-taglibs + + + org.springframework.security + spring-security-core + + + javax.servlet.jsp.jstl + jstl-api + ${jstl.version} + + + org.springframework.security + spring-security-config + + + org.springframework + spring-context-support + + + net.sf.ehcache + ehcache-core + ${ehcache-core.version} + jar + + + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + tomcat8x + embedded + + + + + + + 8082 + + + + + + + + + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + entryPoints + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*IntTest.java + + + **/*EntryPointsTest.java + + + + + + + json + + + + + + + + + + org.baeldung.custom.Application + + + + + + + + 1.1.2 + 1.6.1 + 2.6.11 + + + diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java new file mode 100644 index 0000000000..6936cdc560 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.h2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@SpringBootApplication +@EnableWebSecurity +@PropertySource("classpath:application-defaults.properties") +public class H2JdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(H2JdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java new file mode 100644 index 0000000000..8b8696f0b2 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java @@ -0,0 +1,51 @@ +package org.baeldung.jdbcauthentication.h2.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity.authorizeRequests() + .antMatchers("/h2-console/**") + .permitAll() + .anyRequest() + .authenticated() + .and() + .formLogin() + .permitAll(); + httpSecurity.csrf() + .ignoringAntMatchers("/h2-console/**"); + httpSecurity.headers() + .frameOptions() + .sameOrigin(); + } + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource) + .withDefaultSchema() + .withUser(User.withUsername("user") + .password(passwordEncoder().encode("pass")) + .roles("USER")); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java new file mode 100644 index 0000000000..0955061614 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.h2.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..52934e0096 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.jdbcauthentication.mysql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-mysql.properties") +public class MySqlJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(MySqlJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java new file mode 100644 index 0000000000..157c0be748 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java @@ -0,0 +1,35 @@ +package org.baeldung.jdbcauthentication.mysql.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration { + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource) + .usersByUsernameQuery("select email,password,enabled " + + "from bael_users " + + "where email = ?") + .authoritiesByUsernameQuery("select email,authority " + + "from authorities " + + "where email = ?"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java new file mode 100644 index 0000000000..f1060b5f78 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.mysql.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..2c4d1a5255 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.jdbcauthentication.postgre; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-postgre.properties") +public class PostgreJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(PostgreJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java new file mode 100644 index 0000000000..ba79635852 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java @@ -0,0 +1,29 @@ +package org.baeldung.jdbcauthentication.postgre.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration { + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java new file mode 100644 index 0000000000..c8fd3812b1 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.postgre.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java new file mode 100644 index 0000000000..1a89c362cd --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java @@ -0,0 +1,31 @@ +package org.baeldung.multipleauthproviders; + +import java.util.Collections; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.stereotype.Component; + +@Component +public class CustomAuthenticationProvider implements AuthenticationProvider { + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + final String username = auth.getName(); + final String password = auth.getCredentials() + .toString(); + + if ("externaluser".equals(username) && "pass".equals(password)) { + return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList()); + } else { + throw new BadCredentialsException("External system authentication failed"); + } + } + + @Override + public boolean supports(Class auth) { + return auth.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java new file mode 100644 index 0000000000..b63169bb00 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java @@ -0,0 +1,13 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MultipleAuthController { + + @GetMapping("/api/ping") + public String getPing() { + return "OK"; + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java new file mode 100644 index 0000000000..1f641298c3 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java @@ -0,0 +1,14 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +// @ImportResource({ "classpath*:spring-security-multiple-auth-providers.xml" }) +public class MultipleAuthProvidersApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleAuthProvidersApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java new file mode 100644 index 0000000000..3819e981a2 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java @@ -0,0 +1,42 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@EnableWebSecurity +public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + CustomAuthenticationProvider customAuthProvider; + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.authenticationProvider(customAuthProvider); + + auth.inMemoryAuthentication() + .withUser("memuser") + .password(passwordEncoder().encode("pass")) + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic() + .and() + .authorizeRequests() + .antMatchers("/api/**") + .authenticated(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java new file mode 100644 index 0000000000..847dab073e --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java @@ -0,0 +1,14 @@ +package org.baeldung.multipleentrypoints; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +// @ImportResource({"classpath*:spring-security-multiple-entry.xml"}) +public class MultipleEntryPointsApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleEntryPointsApplication.class, args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java new file mode 100644 index 0000000000..dc89c83cde --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java @@ -0,0 +1,99 @@ +package org.baeldung.multipleentrypoints; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@Configuration +@EnableWebSecurity +public class MultipleEntryPointsSecurityConfig { + + @Bean + public UserDetailsService userDetailsService() throws Exception { + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); + manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); + return manager; + } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + + @Configuration + @Order(1) + public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + //@formatter:off + http.antMatcher("/admin/**") + .authorizeRequests().anyRequest().hasRole("ADMIN") + .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and().exceptionHandling().accessDeniedPage("/403"); + //@formatter:on + } + + @Bean + public AuthenticationEntryPoint authenticationEntryPoint(){ + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("admin realm"); + return entryPoint; + } + } + + @Configuration + @Order(2) + public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { + + protected void configure(HttpSecurity http) throws Exception { + + //@formatter:off + http.antMatcher("/user/**") + .authorizeRequests().anyRequest().hasRole("USER") + .and().formLogin().loginProcessingUrl("/user/login") + .failureUrl("/userLogin?error=loginError").defaultSuccessUrl("/user/myUserPage") + .and().logout().logoutUrl("/user/logout").logoutSuccessUrl("/multipleHttpLinks") + .deleteCookies("JSESSIONID") + .and().exceptionHandling() + .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPointWithWarning(), new AntPathRequestMatcher("/user/private/**")) + .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPoint(), new AntPathRequestMatcher("/user/general/**")) + .accessDeniedPage("/403") + .and().csrf().disable(); + //@formatter:on + } + + @Bean + public AuthenticationEntryPoint loginUrlauthenticationEntryPoint(){ + return new LoginUrlAuthenticationEntryPoint("/userLogin"); + } + + @Bean + public AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning(){ + return new LoginUrlAuthenticationEntryPoint("/userLoginWithWarning"); + } + } + + @Configuration + @Order(3) + public static class App3ConfigurationAdapter extends WebSecurityConfigurerAdapter { + + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/guest/**").authorizeRequests().anyRequest().permitAll(); + } + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/PagesController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/PagesController.java new file mode 100644 index 0000000000..b3462d4061 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multipleentrypoints/PagesController.java @@ -0,0 +1,48 @@ +package org.baeldung.multipleentrypoints; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class PagesController { + + @RequestMapping("/multipleHttpLinks") + public String getMultipleHttpLinksPage() { + return "multipleHttpElems/multipleHttpLinks"; + } + + @RequestMapping("/admin/myAdminPage") + public String getAdminPage() { + return "multipleHttpElems/myAdminPage"; + } + + @RequestMapping("/user/general/myUserPage") + public String getUserPage() { + return "multipleHttpElems/myUserPage"; + } + + @RequestMapping("/user/private/myPrivateUserPage") + public String getPrivateUserPage() { + return "multipleHttpElems/myPrivateUserPage"; + } + + @RequestMapping("/guest/myGuestPage") + public String getGuestPage() { + return "multipleHttpElems/myGuestPage"; + } + + @RequestMapping("/userLogin") + public String getUserLoginPage() { + return "multipleHttpElems/login"; + } + + @RequestMapping("/userLoginWithWarning") + public String getUserLoginPageWithWarning() { + return "multipleHttpElems/loginWithWarning"; + } + + @RequestMapping("/403") + public String getAccessDeniedPage() { + return "403"; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java new file mode 100644 index 0000000000..90bb5e4260 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.multiplelogin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +@ComponentScan("org.baeldung.multiplelogin") +public class MultipleLoginApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleLoginApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java new file mode 100644 index 0000000000..204b186411 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java @@ -0,0 +1,44 @@ +package org.baeldung.multiplelogin; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; +import org.springframework.context.annotation.ComponentScan; + +@EnableWebMvc +@Configuration +@ComponentScan("org.baeldung.controller") +public class MultipleLoginMvcConfig implements WebMvcConfigurer { + + public MultipleLoginMvcConfig() { + super(); + } + + // API + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/anonymous.html"); + + registry.addViewController("/login.html"); + registry.addViewController("/homepage.html"); + registry.addViewController("/console.html"); + } + + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver bean = new InternalResourceViewResolver(); + + bean.setViewClass(JstlView.class); + bean.setPrefix("/WEB-INF/view/"); + bean.setSuffix(".jsp"); + + return bean; + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java new file mode 100644 index 0000000000..9962bf41a9 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java @@ -0,0 +1,78 @@ +package org.baeldung.multiplelogin; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; + +@Configuration +@EnableWebSecurity +public class MultipleLoginSecurityConfig { + + @Bean + public UserDetailsService userDetailsService() throws Exception { + InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); + manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); + manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); + return manager; + } + + @Bean + public static PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + + @Configuration + @Order(1) + public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { + + public App1ConfigurationAdapter() { + super(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("admin").password(encoder().encode("admin")).roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/admin*").authorizeRequests().anyRequest().hasRole("ADMIN") + // log in + .and().formLogin().loginPage("/loginAdmin").loginProcessingUrl("/admin_login").failureUrl("/loginAdmin?error=loginError").defaultSuccessUrl("/adminPage") + // logout + .and().logout().logoutUrl("/admin_logout").logoutSuccessUrl("/protectedLinks").deleteCookies("JSESSIONID").and().exceptionHandling().accessDeniedPage("/403").and().csrf().disable(); + } + } + + @Configuration + @Order(2) + public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { + + public App2ConfigurationAdapter() { + super(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("user").password(encoder().encode("user")).roles("USER"); + } + + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/user*").authorizeRequests().anyRequest().hasRole("USER") + // log in + .and().formLogin().loginPage("/loginUser").loginProcessingUrl("/user_login").failureUrl("/loginUser?error=loginError").defaultSuccessUrl("/userPage") + // logout + .and().logout().logoutUrl("/user_logout").logoutSuccessUrl("/protectedLinks").deleteCookies("JSESSIONID").and().exceptionHandling().accessDeniedPage("/403").and().csrf().disable(); + } + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/UsersController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/UsersController.java new file mode 100644 index 0000000000..61d7da127c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/multiplelogin/UsersController.java @@ -0,0 +1,38 @@ +package org.baeldung.multiplelogin; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class UsersController { + + @GetMapping("/protectedLinks") + public String getAnonymousPage() { + return "protectedLinks"; + } + + @GetMapping("/userPage") + public String getUserPage() { + return "userPage"; + } + + @GetMapping("/adminPage") + public String getAdminPage() { + return "adminPage"; + } + + @GetMapping("/loginAdmin") + public String getAdminLoginPage() { + return "loginAdmin"; + } + + @GetMapping("/loginUser") + public String getUserLoginPage() { + return "loginUser"; + } + + @GetMapping("/403") + public String getAccessDeniedPage() { + return "403"; + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java new file mode 100644 index 0000000000..17c249067c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java @@ -0,0 +1,16 @@ +package org.baeldung.ssl; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-defaults.properties") +public class HttpsEnabledApplication { + + public static void main(String... args) { + SpringApplication application = new SpringApplication(HttpsEnabledApplication.class); + application.setAdditionalProfiles("ssl"); + application.run(args); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/SecurityConfig.java new file mode 100644 index 0000000000..92f92d8fc7 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/SecurityConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.ssl; + +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/**") + .permitAll(); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/WelcomeController.java b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/WelcomeController.java new file mode 100644 index 0000000000..72ad8abb85 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/java/org/baeldung/ssl/WelcomeController.java @@ -0,0 +1,15 @@ +package org.baeldung.ssl; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class WelcomeController { + + @GetMapping("/welcome") + public String welcome() { + return "ssl/welcome"; + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-defaults.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-defaults.properties new file mode 100644 index 0000000000..e2032c4a6b --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-defaults.properties @@ -0,0 +1,13 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.database=H2 +spring.jpa.show-sql=false +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + +#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG + +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-mysql.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-mysql.properties new file mode 100644 index 0000000000..568d0c5ca3 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-mysql.properties @@ -0,0 +1,9 @@ +spring.datasource.platform=mysql +spring.datasource.url=jdbc:mysql://localhost:3306/jdbc_authentication +spring.datasource.username=root +spring.datasource.password=pass + +spring.datasource.initialization-mode=always +spring.jpa.hibernate.ddl-auto=none + +spring.profiles.active=mysql diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-postgre.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-postgre.properties new file mode 100644 index 0000000000..69faece45e --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-postgre.properties @@ -0,0 +1,7 @@ +spring.datasource.platform=postgre +spring.datasource.url=jdbc:postgresql://localhost:5432/jdbc_authentication +spring.datasource.username=postgres +spring.datasource.password=pass + +spring.datasource.initialization-mode=always +spring.jpa.hibernate.ddl-auto=none diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-ssl.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-ssl.properties new file mode 100644 index 0000000000..090b775d03 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application-ssl.properties @@ -0,0 +1,20 @@ + +http.port=8080 + +server.port=8443 + +security.require-ssl=true + +# The format used for the keystore +server.ssl.key-store-type=PKCS12 +# The path to the keystore containing the certificate +server.ssl.key-store=classpath:keystore/baeldung.p12 +# The password used to generate the certificate +server.ssl.key-store-password=password +# The alias mapped to the certificate +server.ssl.key-alias=baeldung + +#trust store location +trust.store=classpath:keystore/baeldung.p12 +#trust store password +trust.store.password=password diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application.properties new file mode 100644 index 0000000000..3cf12afeb9 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8082 diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-mysql.sql b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-mysql.sql new file mode 100644 index 0000000000..8214fd8204 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-mysql.sql @@ -0,0 +1,4 @@ +-- User user@email.com/pass +INSERT INTO bael_users (name, email, password, enabled) values ('user', 'user@email.com', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', 1); + +INSERT INTO authorities (email, authority) values ('user@email.com', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-postgre.sql b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-postgre.sql new file mode 100644 index 0000000000..fcc6b54949 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/data-postgre.sql @@ -0,0 +1,4 @@ +-- User user/pass +INSERT INTO users (username, password, enabled) values ('user', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', true); + +INSERT INTO authorities (username, authority) values ('user', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/keystore/baeldung.p12 b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/keystore/baeldung.p12 new file mode 100644 index 0000000000000000000000000000000000000000..cd8eb284297009e987aa1a1d6b53c48af587776e GIT binary patch literal 2603 zcmY+EXEYlM8^;r3M9o+w1hFbbqGHbuyEIm+snTk!hO1FpR7GP|aZ6j;auK8UtQAG7 zV$YhT2qmc9Vcsg&`=0l`_uLQ9dCvL$|IhRBhaz(+vH)38WbiCI7!hqAy~_jS08+@{ zK@b_-cZ|DGWH#S_MQko0G8^s~V~@v<{lx#SxVeBV6f)>1iVWICDY0|?A0I!5f`s^3 zu&dJJ6F~Z?bJm7OhKe^z>^=)CfQ|u?L7h6GkAgI65DwJB{KM&_MXKTI9lIqxhN`1} z`A*KRClYJWaEY_s^N|voc6A00ThR7qHjQvZX+gn$-BvCy^h*XXd@(9FFl&uIA(ye3~t$x%OvdtZ6kea z?f2mYKd}#kcfPd2Qj@BWsJYAQV?UWEV$3xr?2MMkh<@aOLyI5fS+HWE`b(`(J^ht} zkR*eWyqT*v5%MaZOvmUzs+mdtjCG$7e zk&q|W%V|!jeWjxuJY*Pp@C-pN0z$3MU$4}90$#HPd)>y0K?<6Y7T0Chq0uke7wbomuc|C+P#-z{m`4c1|1GBI(woGP!Qhl7t_2@B=gTCU}klA|2uD~LA$B|Hf z9?q|vYv$T8RN`JF0)WU?;jGXd*@?42n)lJLP?O%qsJ(!~)+G!#4|R;Q2h*6mO8XIX z_P~j+liPKyQLV85WsE0HQ+2F7!T=w$#*rGM@2eK}v3Xvw^kEK*b_!6)K@Oy{^#nzK zYsydd{?(y@;X^STEU`R(o3B3DQ=gQ{TalEFacTQ$WwZ_3$NLf1A`ue15ske5Gbvrn zMVwpM5 z$^;r{*cZwNsXDeph+W0HFoH3@>rvgs;VhhQP@SeG3Lch{p&iNZS<9O-`k>9`V^$Bvi__Z&f2RwKK4svAZO_QzY-Q+9boQ0)of~0dFq|de&s}-DZ zouW8d&sajPQE^wEim{+NZ&76^e#4I@Eafg)-eAhQByD>`a|b0n*iCC6(-a?G59!K! z%WNH4FA|B~`8ZHpAgsSh=iwt@gM6V;X^Lic=Ze*TrTDT{_smO{wb$xT3!aB9Ix$ zDHJb#IrUW=`ki_aY+ttWxkRR7JPdppxA8pLHc788pN$m`*!udm1)o>{gp13CMePDg z>Tgwoh14K0et;X`2EZNQ1Hc0U0lxt}Q8ND&gw=#V5C?BxcWE^ZbsbGD4K!Lq9j$XL zP=~)u9PGzVH91CSS%84!rTb3;{Fi0f|6^H4*Oa*e3xdCLeiF;!_o?hv z0tk<&E}^>5tfsiw#0xZ84jjfMZW)O9@|xuvB=#S%RSw(YvpJl=fCsPWzeWCMix(mA7RsU@{fe{o=Xy>Pp*}`%+i`nlk|N9x!FxG2)|X4 zEKw@1^=34F&2qQi9j@PN8d^HCdnwkH+SwDtAaoOs>MrPVqq+6GsLWG{iP!raR{296 zn)bo1Ypxj{s&Zq3PJ)r!`Io^PGnnr+kk7{UX+IJgRt#f%T8fU$?%w|Vop*RwEGqa{ z(WG3c0FW|}N4&}s$|j#RGGV2oSE>W{OZ@E-b47trP;YC$ z=vPW$1m1o3sc292)J35Y(%$!P4;0VKD5xumEa}b>FU(NpzSChk7S=$(X973=-bj9{y};Q81=IyKM8_P=YATS4wxXidLc;YHIX!VEoy)KSNh5GdGhbD-AIfz3o9_1@)sB) B#c}`u literal 0 HcmV?d00001 diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/logback.xml b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/persistence-h2.properties b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..a4b2af6361 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/persistence-h2.properties @@ -0,0 +1,8 @@ +driverClassName=org.h2.Driver +url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1 +username=sa +password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-mysql.sql b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-mysql.sql new file mode 100644 index 0000000000..bb38c74366 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-mysql.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS authorities; +DROP TABLE IF EXISTS bael_users; + +CREATE TABLE bael_users ( + name VARCHAR(50) NOT NULL, + email VARCHAR(50) NOT NULL, + password VARCHAR(100) NOT NULL, + enabled TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (email) +); + +CREATE TABLE authorities ( + email VARCHAR(50) NOT NULL, + authority VARCHAR(50) NOT NULL, + FOREIGN KEY (email) REFERENCES bael_users(email) +); + +CREATE UNIQUE INDEX ix_auth_email on authorities (email,authority); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-postgre.sql b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-postgre.sql new file mode 100644 index 0000000000..d78edfb528 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/schema-postgre.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS authorities; +DROP TABLE IF EXISTS users; + +CREATE TABLE users ( + username varchar(50) NOT NULL PRIMARY KEY, + password varchar(100) NOT NULL, + enabled boolean not null DEFAULT true +); + +CREATE TABLE authorities ( + username varchar(50) NOT NULL, + authority varchar(50) NOT NULL, + CONSTRAINT foreign_authorities_users_1 foreign key(username) references users(username) +); + +CREATE UNIQUE INDEX ix_auth_username on authorities (username,authority); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-auth-providers.xml b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-auth-providers.xml new file mode 100644 index 0000000000..4cfa6bbf26 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-auth-providers.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-entry.xml b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-entry.xml new file mode 100644 index 0000000000..c026700810 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/spring-security-multiple-entry.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/403.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/403.html new file mode 100644 index 0000000000..20550768cf --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/403.html @@ -0,0 +1,10 @@ + + + + + + + +You do not have permission to view this page. + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/adminPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/adminPage.html new file mode 100644 index 0000000000..13aff9b15a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/adminPage.html @@ -0,0 +1,13 @@ + + + + +Insert title here + + +Welcome admin! Logout + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/index.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/index.html new file mode 100644 index 0000000000..8e7394ad6a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/index.html @@ -0,0 +1,21 @@ + + + + +Spring Security Thymeleaf + + + + + +
+ Welcome +
+ + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/login.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/login.html new file mode 100644 index 0000000000..dd6bd04767 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/login.html @@ -0,0 +1,27 @@ + + + + +

Login

+ +
+ + + + + + + + + + + + + + +
User:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginAdmin.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginAdmin.html new file mode 100644 index 0000000000..43d0e73233 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginAdmin.html @@ -0,0 +1,31 @@ + + + + +Insert title here + + + +

Admin login page

+
+ + + + + + + + + + + + + +
User:
Password:
+ +
+ +

Login failed!

+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginUser.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginUser.html new file mode 100644 index 0000000000..bf4ddd48bc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/loginUser.html @@ -0,0 +1,30 @@ + + + + +Login + + + +

User login page

+ +
+ + + + + + + + + + + + +
User:
Password:
+ +
+

Login failed!

+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/login.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/login.html new file mode 100644 index 0000000000..2119baec66 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/login.html @@ -0,0 +1,27 @@ + + + + +

Login

+ +
+ + + + + + + + + + + + + + +
Username:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/loginWithWarning.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/loginWithWarning.html new file mode 100644 index 0000000000..a5b2eaf3dc --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/loginWithWarning.html @@ -0,0 +1,28 @@ + + + + +

Login

+

Warning! You are about to access sensible data!

+ +
+ + + + + + + + + + + + + + +
Username:
Password:
+ +
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html new file mode 100644 index 0000000000..676badb16f --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html @@ -0,0 +1,18 @@ + + + + +Multiple Http Elements Links + + + +Admin page +
+User page +
+Private user page +
+Guest page + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myAdminPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myAdminPage.html new file mode 100644 index 0000000000..3003833562 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myAdminPage.html @@ -0,0 +1,13 @@ + + + + +Admin Page + + +Welcome admin! + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myGuestPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myGuestPage.html new file mode 100644 index 0000000000..47a4c9c44a --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myGuestPage.html @@ -0,0 +1,13 @@ + + + + +Guest Page + + +Welcome guest! + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html new file mode 100644 index 0000000000..52045ec320 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html @@ -0,0 +1,13 @@ + + + + +Insert title here + + +Welcome user to your private page! Logout + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myUserPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myUserPage.html new file mode 100644 index 0000000000..f6c2def0b8 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/multipleHttpElems/myUserPage.html @@ -0,0 +1,13 @@ + + + + +User Page + + +Welcome user! Logout + +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/private.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/private.html new file mode 100644 index 0000000000..035d84bbbd --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/private.html @@ -0,0 +1,10 @@ + + + + Private + + +

Congrats!

+ + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/protectedLinks.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/protectedLinks.html new file mode 100644 index 0000000000..1877464fe5 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/protectedLinks.html @@ -0,0 +1,13 @@ + + + + +Insert title here + + + +User page +
+Admin page + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/ssl/welcome.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/ssl/welcome.html new file mode 100644 index 0000000000..93b3577f5c --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/ssl/welcome.html @@ -0,0 +1 @@ +

Welcome to Secured Site

\ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/userPage.html b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/userPage.html new file mode 100644 index 0000000000..894a225871 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/main/resources/templates/userPage.html @@ -0,0 +1,12 @@ + + + + +Insert title here + + +Welcome user! Logout +

+Back to links + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java new file mode 100644 index 0000000000..659dad9155 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java @@ -0,0 +1,16 @@ +package org.baeldung.jdbcauthentication.h2; + +import org.baeldung.jdbcauthentication.h2.H2JdbcAuthenticationApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = H2JdbcAuthenticationApplication.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..638e9d7919 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.baeldung.jdbcauthentication.h2.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.authentication.FormAuthConfig; +import io.restassured.filter.session.SessionFilter; + +/** + * This Live Test requires the H2JdbcAuthenticationApplication application to be up and running + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + SessionFilter filter = new SessionFilter(); + given().auth() + .form("user", "pass", new FormAuthConfig("/login", "username", "password").withCsrfFieldName("_csrf")) + .and() + .filter(filter) + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user")) + .body("name", is("user")); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..261063cbb6 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.baeldung.jdbcauthentication.mysql.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * This Live Test requires: + * * a MySql instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication + * (e.g. with the following command `docker run -p 3306:3306 --name bael-mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=jdbc_authentication mysql:latest`) + * * the service up and running + * + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + given().auth() + .preemptive() + .basic("user@email.com", "pass") + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user@email.com")) + .body("name", is("user@email.com")); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..82bf6df8db --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.baeldung.jdbcauthentication.postgre.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * This Live Test requires: + * * a PostgreSQL instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication + * (e.g. with the following command `docker run -p 5432:5432 --name bael-postgre -e POSTGRES_PASSWORD=pass -e POSTGRES_DB=jdbc_authentication postgres:latest`) + * * the service up and running + * + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + given().auth() + .preemptive() + .basic("user", "pass") + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user")) + .body("name", is("user")); + } + +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java new file mode 100644 index 0000000000..fe7883ec94 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java @@ -0,0 +1,56 @@ +package org.baeldung.web; + +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.baeldung.ssl.HttpsEnabledApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.SSLContext; +import java.util.Collections; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = HttpsEnabledApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ActiveProfiles("ssl") +public class HttpsApplicationIntegrationTest { + + private static final String WELCOME_URL = "https://localhost:8443/welcome"; + + @Value("${trust.store}") + private Resource trustStore; + + @Value("${trust.store.password}") + private String trustStorePassword; + + @Test + public void whenGETanHTTPSResource_thenCorrectResponse() throws Exception { + ResponseEntity response = restTemplate().getForEntity(WELCOME_URL, String.class, Collections.emptyMap()); + + assertEquals("

Welcome to Secured Site

", response.getBody()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + RestTemplate restTemplate() throws Exception { + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) + .build(); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); + HttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(socketFactory) + .build(); + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); + return new RestTemplate(factory); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java new file mode 100644 index 0000000000..9ef09f1f67 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java @@ -0,0 +1,61 @@ +package org.baeldung.web; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class) +public class MultipleAuthProvidersApplicationIntegrationTest { + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void givenMemUsers_whenGetPingWithValidUser_thenOk() { + ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { + ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenAuthProviders_whenGetPingWithNoCred_then401() { + ResponseEntity result = makeRestCallToGetPing(); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + @Test + public void givenAuthProviders_whenGetPingWithBadCred_then401() { + ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + private ResponseEntity makeRestCallToGetPing(String username, String password) { + return restTemplate.withBasicAuth(username, password) + .getForEntity("/api/ping", String.class, Collections.emptyMap()); + } + + private ResponseEntity makeRestCallToGetPing() { + return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap()); + } +} diff --git a/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java new file mode 100644 index 0000000000..422be2ac88 --- /dev/null +++ b/spring-security-modules/spring-security-mvc-boot-2/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java @@ -0,0 +1,67 @@ +package org.baeldung.web; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.baeldung.multipleentrypoints.MultipleEntryPointsApplication; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; + +@RunWith(SpringRunner.class) +@WebAppConfiguration +@SpringBootTest(classes = MultipleEntryPointsApplication.class) +public class MultipleEntryPointsIntegrationTest { + + @Autowired + private WebApplicationContext wac; + + @Autowired + private FilterChainProxy springSecurityFilterChain; + + private MockMvc mockMvc; + + @Before + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(springSecurityFilterChain).build(); + } + + @Test + public void whenTestAdminCredentials_thenOk() throws Exception { + mockMvc.perform(get("/admin/myAdminPage")).andExpect(status().isUnauthorized()); + + mockMvc.perform(get("/admin/myAdminPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk()); + + mockMvc.perform(get("/user/myUserPage").with(user("admin").password("adminPass").roles("ADMIN"))).andExpect(status().isForbidden()); + + } + + @Test + public void whenTestUserCredentials_thenOk() throws Exception { + mockMvc.perform(get("/user/general/myUserPage")).andExpect(status().isFound()); + + mockMvc.perform(get("/user/general/myUserPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk()); + + mockMvc.perform(get("/admin/myAdminPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isForbidden()); + } + + @Test + public void givenAnyUser_whenGetGuestPage_thenOk() throws Exception { + mockMvc.perform(get("/guest/myGuestPage")).andExpect(status().isOk()); + + mockMvc.perform(get("/guest/myGuestPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk()); + + mockMvc.perform(get("/guest/myGuestPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk()); + } +} From 1e9390a5d093e8b607507983717b9dd5dab2b929 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Mon, 17 Feb 2020 21:56:20 +0530 Subject: [PATCH 27/62] JAVA-6 : deleted module spring-security-mvc-boot --- .../spring-security-mvc-boot/README.md | 21 -- .../WebContent/META-INF/MANIFEST.MF | 3 - .../spring-security-mvc-boot/pom.xml | 249 ------------------ .../src/main/java/com/baeldung/AppConfig.java | 64 ----- .../com/baeldung/SpringSecurityConfig.java | 89 ------- .../data/repositories/TweetRepository.java | 14 - .../data/repositories/UserRepository.java | 27 -- .../java/com/baeldung/models/AppUser.java | 83 ------ .../main/java/com/baeldung/models/Tweet.java | 67 ----- .../baeldung/security/AppUserPrincipal.java | 67 ----- .../AuthenticationSuccessHandlerImpl.java | 28 -- .../security/CustomUserDetailsService.java | 40 --- .../com/baeldung/util/DummyContentUtil.java | 63 ----- .../java/org/baeldung/custom/Application.java | 14 - .../custom/config/MethodSecurityConfig.java | 21 -- .../org/baeldung/custom/config/MvcConfig.java | 41 --- .../custom/config/SecurityConfig.java | 15 -- .../custom/persistence/SetupData.java | 73 ----- .../dao/OrganizationRepository.java | 10 - .../persistence/dao/PrivilegeRepository.java | 10 - .../persistence/dao/UserRepository.java | 14 - .../custom/persistence/model/Foo.java | 94 ------- .../persistence/model/Organization.java | 95 ------- .../custom/persistence/model/Privilege.java | 95 ------- .../custom/persistence/model/User.java | 155 ----------- ...CustomMethodSecurityExpressionHandler.java | 22 -- .../CustomMethodSecurityExpressionRoot.java | 50 ---- .../security/CustomPermissionEvaluator.java | 40 --- .../security/MySecurityExpressionRoot.java | 203 -------------- .../custom/security/MyUserDetailsService.java | 31 --- .../custom/security/MyUserPrincipal.java | 72 ----- .../baeldung/custom/web/MainController.java | 68 ----- .../java/org/baeldung/ip/IpApplication.java | 14 - .../CustomIpAuthenticationProvider.java | 53 ---- .../baeldung/ip/config/SecurityConfig.java | 36 --- .../baeldung/ip/config/SecurityXmlConfig.java | 9 - .../org/baeldung/ip/web/MainController.java | 42 --- .../h2/H2JdbcAuthenticationApplication.java | 17 -- .../h2/config/SecurityConfiguration.java | 51 ---- .../h2/web/UserController.java | 17 -- .../MySqlJdbcAuthenticationApplication.java | 15 -- .../mysql/config/SecurityConfiguration.java | 35 --- .../mysql/web/UserController.java | 17 -- .../PostgreJdbcAuthenticationApplication.java | 15 -- .../postgre/config/SecurityConfiguration.java | 29 -- .../postgre/web/UserController.java | 17 -- .../CustomAuthenticationProvider.java | 31 --- .../MultipleAuthController.java | 13 - .../MultipleAuthProvidersApplication.java | 14 - .../MultipleAuthProvidersSecurityConfig.java | 42 --- .../MultipleEntryPointsApplication.java | 14 - .../MultipleEntryPointsSecurityConfig.java | 99 ------- .../multipleentrypoints/PagesController.java | 48 ---- .../MultipleLoginApplication.java | 15 -- .../multiplelogin/MultipleLoginMvcConfig.java | 44 ---- .../MultipleLoginSecurityConfig.java | 78 ------ .../multiplelogin/UsersController.java | 38 --- .../CustomAuthenticationProvider.java | 38 --- .../MyLogoutSuccessHandler.java | 26 -- .../MyUserDetailsService.java | 61 ----- .../RolesAuthoritiesApplication.java | 17 -- .../rolesauthorities/config/MvcConfig.java | 46 ---- .../config/SecurityConfig.java | 90 ------- .../rolesauthorities/model/Privilege.java | 89 ------- .../baeldung/rolesauthorities/model/Role.java | 104 -------- .../baeldung/rolesauthorities/model/User.java | 147 ----------- .../persistence/IUserService.java | 9 - .../persistence/PrivilegeRepository.java | 12 - .../persistence/RoleRepository.java | 12 - .../persistence/SetupDataLoader.java | 97 ------- .../persistence/UserRepository.java | 12 - .../persistence/UserService.java | 19 -- .../baeldung/ssl/HttpsEnabledApplication.java | 16 -- .../java/org/baeldung/ssl/SecurityConfig.java | 16 -- .../org/baeldung/ssl/WelcomeController.java | 15 -- .../org/baeldung/voter/MinuteBasedVoter.java | 26 -- .../org/baeldung/voter/VoterApplication.java | 16 -- .../org/baeldung/voter/VoterMvcConfig.java | 19 -- .../org/baeldung/voter/WebSecurityConfig.java | 55 ---- .../org/baeldung/voter/XmlSecurityConfig.java | 15 -- .../resources/application-defaults.properties | 13 - .../resources/application-mysql.properties | 9 - .../resources/application-postgre.properties | 7 - .../main/resources/application-ssl.properties | 20 -- .../src/main/resources/application.properties | 1 - .../src/main/resources/data-mysql.sql | 4 - .../src/main/resources/data-postgre.sql | 4 - .../src/main/resources/keystore/baeldung.p12 | Bin 2603 -> 0 bytes .../src/main/resources/logback.xml | 13 - .../main/resources/persistence-h2.properties | 8 - .../src/main/resources/schema-mysql.sql | 18 -- .../src/main/resources/schema-postgre.sql | 16 -- .../spring-security-custom-voter.xml | 40 --- .../src/main/resources/spring-security-ip.xml | 21 -- ...pring-security-multiple-auth-providers.xml | 24 -- .../spring-security-multiple-entry.xml | 65 ----- .../src/main/resources/templates/403.html | 10 - .../main/resources/templates/adminPage.html | 13 - .../src/main/resources/templates/index.html | 21 -- .../src/main/resources/templates/login.html | 27 -- .../main/resources/templates/loginAdmin.html | 31 --- .../main/resources/templates/loginUser.html | 30 --- .../templates/multipleHttpElems/login.html | 27 -- .../multipleHttpElems/loginWithWarning.html | 28 -- .../multipleHttpElems/multipleHttpLinks.html | 18 -- .../multipleHttpElems/myAdminPage.html | 13 - .../multipleHttpElems/myGuestPage.html | 13 - .../multipleHttpElems/myPrivateUserPage.html | 13 - .../multipleHttpElems/myUserPage.html | 13 - .../src/main/resources/templates/private.html | 10 - .../resources/templates/protectedLinks.html | 13 - .../templates/rolesauthorities/home.html | 25 -- .../templates/rolesauthorities/login.html | 57 ---- .../protectedbyauthority.html | 24 -- .../rolesauthorities/protectedbynothing.html | 21 -- .../rolesauthorities/protectedbyrole.html | 24 -- .../main/resources/templates/ssl/welcome.html | 1 - .../main/resources/templates/userPage.html | 12 - ...SpringDataWithSecurityIntegrationTest.java | 112 -------- .../java/org/baeldung/SpringContextTest.java | 16 -- .../h2/SpringContextTest.java | 15 -- .../h2/web/UserControllerLiveTest.java | 35 --- .../mysql/web/UserControllerLiveTest.java | 35 --- .../postgre/web/UserControllerLiveTest.java | 35 --- .../org/baeldung/web/ApplicationLiveTest.java | 67 ----- ...stomUserDetailsServiceIntegrationTest.java | 89 ------- .../web/HttpsApplicationIntegrationTest.java | 56 ---- .../java/org/baeldung/web/IpLiveTest.java | 27 -- ...thProvidersApplicationIntegrationTest.java | 61 ----- .../MultipleEntryPointsIntegrationTest.java | 65 ----- 130 files changed, 5018 deletions(-) delete mode 100644 spring-security-modules/spring-security-mvc-boot/README.md delete mode 100644 spring-security-modules/spring-security-mvc-boot/WebContent/META-INF/MANIFEST.MF delete mode 100644 spring-security-modules/spring-security-mvc-boot/pom.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/application-defaults.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/application-mysql.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/application-postgre.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/application-ssl.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/application.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/data-mysql.sql delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/data-postgre.sql delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/keystore/baeldung.p12 delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/logback.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/persistence-h2.properties delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-mysql.sql delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-postgre.sql delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/403.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/adminPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/index.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/login.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginUser.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/private.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/userPage.html delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java delete mode 100644 spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java diff --git a/spring-security-modules/spring-security-mvc-boot/README.md b/spring-security-modules/spring-security-mvc-boot/README.md deleted file mode 100644 index a1056cc130..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/README.md +++ /dev/null @@ -1,21 +0,0 @@ -## Spring Boot Security MVC - -This module contains articles about Spring Security with Spring MVC in Boot applications - -### The Course -The "REST With Spring" Classes: http://github.learnspringsecurity.com - -### Relevant Articles: -- [A Custom Security Expression with Spring Security](https://www.baeldung.com/spring-security-create-new-custom-security-expression) -- [Custom AccessDecisionVoters in Spring Security](https://www.baeldung.com/spring-security-custom-voter) -- [Spring Security: Authentication with a Database-backed UserDetailsService](https://www.baeldung.com/spring-security-authentication-with-a-database) -- [Two Login Pages with Spring Security](https://www.baeldung.com/spring-security-two-login-pages) -- [Multiple Entry Points in Spring Security](https://www.baeldung.com/spring-security-multiple-entry-points) -- [Multiple Authentication Providers in Spring Security](https://www.baeldung.com/spring-security-multiple-auth-providers) -- [Granted Authority Versus Role in Spring Security](https://www.baeldung.com/spring-security-granted-authority-vs-role) -- [Spring Data with Spring Security](https://www.baeldung.com/spring-data-security) -- [Spring Security – Whitelist IP Range](https://www.baeldung.com/spring-security-whitelist-ip-range) -- [Find the Registered Spring Security Filters](https://www.baeldung.com/spring-security-registered-filters) -- [HTTPS using Self-Signed Certificate in Spring Boot](https://www.baeldung.com/spring-boot-https-self-signed-certificate) -- [Spring Security: Exploring JDBC Authentication](https://www.baeldung.com/spring-security-jdbc-authentication) - diff --git a/spring-security-modules/spring-security-mvc-boot/WebContent/META-INF/MANIFEST.MF b/spring-security-modules/spring-security-mvc-boot/WebContent/META-INF/MANIFEST.MF deleted file mode 100644 index 254272e1c0..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/WebContent/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: - diff --git a/spring-security-modules/spring-security-mvc-boot/pom.xml b/spring-security-modules/spring-security-mvc-boot/pom.xml deleted file mode 100644 index 489ec2d427..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/pom.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - 4.0.0 - spring-security-mvc-boot - 0.0.1-SNAPSHOT - spring-security-mvc-boot - war - Spring Security MVC Boot - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity5 - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.security - spring-security-data - - - mysql - mysql-connector-java - runtime - - - com.h2database - h2 - - - org.postgresql - postgresql - runtime - - - org.hamcrest - hamcrest-core - test - - - org.hamcrest - hamcrest-library - test - - - org.springframework - spring-test - test - - - org.springframework.security - spring-security-test - test - - - taglibs - standard - ${taglibs-standard.version} - - - org.springframework.security - spring-security-taglibs - - - org.springframework.security - spring-security-core - - - javax.servlet.jsp.jstl - jstl-api - ${jstl.version} - - - org.springframework.security - spring-security-config - - - org.springframework - spring-context-support - - - net.sf.ehcache - ehcache-core - ${ehcache-core.version} - jar - - - - - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - tomcat8x - embedded - - - - - - - 8082 - - - - - - - - - - live - - - - org.codehaus.cargo - cargo-maven2-plugin - - - start-server - pre-integration-test - - start - - - - stop-server - post-integration-test - - stop - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - none - - - **/*LiveTest.java - - - cargo - - - - - - - - - - - entryPoints - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*IntTest.java - - - **/*EntryPointsTest.java - - - - - - - json - - - - - - - - - - org.baeldung.custom.Application - - - - - - - - - - 1.1.2 - 1.6.1 - 2.6.11 - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java deleted file mode 100644 index 8719e39a20..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.baeldung; - -import java.util.Properties; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@SpringBootApplication -@PropertySource({"classpath:persistence-h2.properties", "classpath:application-defaults.properties"}) -@EnableJpaRepositories(basePackages = { "com.baeldung.data.repositories" }) -@EnableWebMvc -@Import(SpringSecurityConfig.class) -public class AppConfig extends WebMvcConfigurerAdapter { - - @Autowired - private Environment env; - - @Bean - public DataSource dataSource() { - final DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(env.getProperty("driverClassName")); - dataSource.setUrl(env.getProperty("url")); - dataSource.setUsername(env.getProperty("user")); - dataSource.setPassword(env.getProperty("password")); - return dataSource; - } - - @Bean - public LocalContainerEntityManagerFactoryBean entityManagerFactory() { - final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "com.baeldung.models" }); - em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - em.setJpaProperties(additionalProperties()); - return em; - } - - final Properties additionalProperties() { - final Properties hibernateProperties = new Properties(); - if (env.getProperty("hibernate.hbm2ddl.auto") != null) { - hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); - } - if (env.getProperty("hibernate.dialect") != null) { - hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - } - if (env.getProperty("hibernate.show_sql") != null) { - hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); - } - return hibernateProperties; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java deleted file mode 100644 index ee13678a24..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.baeldung; - -import javax.annotation.PostConstruct; -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension; -import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.security.AuthenticationSuccessHandlerImpl; -import com.baeldung.security.CustomUserDetailsService; - -@Configuration -@EnableWebSecurity -@ComponentScan("com.baeldung.security") -public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private WebApplicationContext applicationContext; - private CustomUserDetailsService userDetailsService; - @Autowired - private AuthenticationSuccessHandlerImpl successHandler; - @Autowired - private DataSource dataSource; - - @PostConstruct - public void completeSetup() { - userDetailsService = applicationContext.getBean(CustomUserDetailsService.class); - } - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService) - .passwordEncoder(encoder()) - .and() - .authenticationProvider(authenticationProvider()) - .jdbcAuthentication() - .dataSource(dataSource); - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring() - .antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - http.authorizeRequests() - .antMatchers("/login") - .permitAll() - .and() - .formLogin() - .permitAll() - .successHandler(successHandler) - .and() - .csrf() - .disable(); - } - - @Bean - public DaoAuthenticationProvider authenticationProvider() { - final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); - authProvider.setUserDetailsService(userDetailsService); - authProvider.setPasswordEncoder(encoder()); - return authProvider; - } - - @Bean - public PasswordEncoder encoder() { - return new BCryptPasswordEncoder(11); - } - - @Bean - public SecurityEvaluationContextExtension securityEvaluationContextExtension() { - return new SecurityEvaluationContextExtension(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java deleted file mode 100644 index 7d6446ed0d..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.data.repositories; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.PagingAndSortingRepository; - -import com.baeldung.models.Tweet; - -public interface TweetRepository extends PagingAndSortingRepository { - - @Query("select twt from Tweet twt JOIN twt.likes as lk where lk = ?#{ principal?.username } or twt.owner = ?#{ principal?.username }") - Page getMyTweetsAndTheOnesILiked(Pageable pageable); -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java deleted file mode 100644 index 9f13c3197e..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.data.repositories; - -import java.util.Date; -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import com.baeldung.models.AppUser; -import com.baeldung.models.Tweet; - -public interface UserRepository extends CrudRepository { - AppUser findByUsername(String username); - - List findByName(String name); - - @Query("UPDATE AppUser u SET u.lastLogin=:lastLogin WHERE u.username = ?#{ principal?.username }") - @Modifying - @Transactional - public void updateLastLogin(@Param("lastLogin") Date lastLogin); -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java deleted file mode 100644 index e48233f90a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.baeldung.models; - -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "users") -public class AppUser { - - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private long id; - - private String name; - @Column(unique = true) - private String username; - private String password; - private boolean enabled = true; - private Date lastLogin; - - private AppUser() { - } - - public AppUser(String name, String email, String password) { - this.username = email; - this.name = name; - this.password = password; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Date getLastLogin() { - return lastLogin; - } - - public void setLastLogin(Date lastLogin) { - this.lastLogin = lastLogin; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java deleted file mode 100644 index 54a96deaf3..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.baeldung.models; - -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.CollectionTable; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "Tweet") -public class Tweet { - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE) - private long id; - private String tweet; - private String owner; - @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER) - @CollectionTable(name = "Tweet_Likes") - private Set likes = new HashSet<>(); - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - private Tweet() { - } - - public Tweet(String tweet, String owner) { - this.tweet = tweet; - this.owner = owner; - } - - public String getTweet() { - return tweet; - } - - public void setTweet(String tweet) { - this.tweet = tweet; - } - - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - - public Set getLikes() { - return likes; - } - - public void setLikes(Set likes) { - this.likes = likes; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java deleted file mode 100644 index 195f9f7bf6..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.baeldung.security; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import com.baeldung.models.AppUser; - -public class AppUserPrincipal implements UserDetails { - - private final AppUser user; - - // - - public AppUserPrincipal(AppUser user) { - this.user = user; - } - - // - - @Override - public String getUsername() { - return user.getUsername(); - } - - @Override - public String getPassword() { - return user.getPassword(); - } - - @Override - public Collection getAuthorities() { - final List authorities = Collections.singletonList(new SimpleGrantedAuthority("User")); - return authorities; - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } - - // - - public AppUser getAppUser() { - return user; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java deleted file mode 100644 index 3fc2bc6559..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.security; - -import java.io.IOException; -import java.util.Date; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -import com.baeldung.data.repositories.UserRepository; - -@Component -public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler { - - @Autowired - private UserRepository userRepository; - - @Override - public void onAuthenticationSuccess(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2) throws IOException, ServletException { - userRepository.updateLastLogin(new Date()); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java deleted file mode 100644 index 016f4f7fa9..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.baeldung.security; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; -import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.data.repositories.UserRepository; -import com.baeldung.models.AppUser; - -@Service -public class CustomUserDetailsService implements UserDetailsService { - - @Autowired - private WebApplicationContext applicationContext; - private UserRepository userRepository; - - public CustomUserDetailsService() { - super(); - } - - @PostConstruct - public void completeSetup() { - userRepository = applicationContext.getBean(UserRepository.class); - } - - @Override - public UserDetails loadUserByUsername(final String username) { - final AppUser appUser = userRepository.findByUsername(username); - if (appUser == null) { - throw new UsernameNotFoundException(username); - } - return new AppUserPrincipal(appUser); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java deleted file mode 100644 index f1640264d2..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.baeldung.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - -import com.baeldung.models.AppUser; -import com.baeldung.models.Tweet; - -public class DummyContentUtil { - - public static final List generateDummyUsers() { - List appUsers = new ArrayList<>(); - BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - appUsers.add(new AppUser("Lionel Messi", "lionel@messi.com", passwordEncoder.encode("li1234"))); - appUsers.add(new AppUser("Cristiano Ronaldo", "cristiano@ronaldo.com", passwordEncoder.encode("c1234"))); - appUsers.add(new AppUser("Neymar Dos Santos", "neymar@neymar.com", passwordEncoder.encode("n1234"))); - appUsers.add(new AppUser("Luiz Suarez", "luiz@suarez.com", passwordEncoder.encode("lu1234"))); - appUsers.add(new AppUser("Andres Iniesta", "andres@iniesta.com", passwordEncoder.encode("a1234"))); - appUsers.add(new AppUser("Ivan Rakitic", "ivan@rakitic.com", passwordEncoder.encode("i1234"))); - appUsers.add(new AppUser("Ousman Dembele", "ousman@dembele.com", passwordEncoder.encode("o1234"))); - appUsers.add(new AppUser("Sergio Busquet", "sergio@busquet.com", passwordEncoder.encode("s1234"))); - appUsers.add(new AppUser("Gerard Pique", "gerard@pique.com", passwordEncoder.encode("g1234"))); - appUsers.add(new AppUser("Ter Stergen", "ter@stergen.com", passwordEncoder.encode("t1234"))); - return appUsers; - } - - public static final List generateDummyTweets(List users) { - List tweets = new ArrayList<>(); - Random random = new Random(); - IntStream.range(0, 9) - .sequential() - .forEach(i -> { - Tweet twt = new Tweet(String.format("Tweet %d", i), users.get(random.nextInt(users.size())) - .getUsername()); - twt.getLikes() - .addAll(users.subList(0, random.nextInt(users.size())) - .stream() - .map(AppUser::getUsername) - .collect(Collectors.toSet())); - tweets.add(twt); - }); - return tweets; - } - - public static Collection getAuthorities() { - Collection grantedAuthorities = new ArrayList(); - GrantedAuthority grantedAuthority = new GrantedAuthority() { - public String getAuthority() { - return "ROLE_USER"; - } - }; - grantedAuthorities.add(grantedAuthority); - return grantedAuthorities; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java deleted file mode 100644 index 2bd0da48d2..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.custom; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -public class Application extends SpringBootServletInitializer { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java deleted file mode 100644 index 6a005153dc..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.custom.config; - -import org.baeldung.custom.security.CustomMethodSecurityExpressionHandler; -import org.baeldung.custom.security.CustomPermissionEvaluator; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; - -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { - - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - // final DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); - final CustomMethodSecurityExpressionHandler expressionHandler = new CustomMethodSecurityExpressionHandler(); - expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator()); - return expressionHandler; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java deleted file mode 100644 index 58d11ea9ae..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.baeldung.custom.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -@EnableWebMvc -public class MvcConfig implements WebMvcConfigurer { - - public MvcConfig() { - super(); - } - - // - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java deleted file mode 100644 index 739e4d3417..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.custom.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class SecurityConfig { - - @Bean - public PasswordEncoder encoder() { - return new BCryptPasswordEncoder(11); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java deleted file mode 100644 index f0fcce3908..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.baeldung.custom.persistence; - -import java.util.Arrays; -import java.util.HashSet; - -import javax.annotation.PostConstruct; - -import org.baeldung.custom.persistence.dao.OrganizationRepository; -import org.baeldung.custom.persistence.dao.PrivilegeRepository; -import org.baeldung.custom.persistence.dao.UserRepository; -import org.baeldung.custom.persistence.model.Organization; -import org.baeldung.custom.persistence.model.Privilege; -import org.baeldung.custom.persistence.model.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Component; - -@Component -public class SetupData { - @Autowired - private UserRepository userRepository; - - @Autowired - private PrivilegeRepository privilegeRepository; - - @Autowired - private OrganizationRepository organizationRepository; - - @Autowired - private PasswordEncoder encoder; - - @PostConstruct - public void init() { - initOrganizations(); - initPrivileges(); - initUsers(); - } - - private void initUsers() { - final Privilege privilege1 = privilegeRepository.findByName("FOO_READ_PRIVILEGE"); - final Privilege privilege2 = privilegeRepository.findByName("FOO_WRITE_PRIVILEGE"); - // - final User user1 = new User(); - user1.setUsername("john"); - user1.setPassword(encoder.encode("123")); - user1.setPrivileges(new HashSet(Arrays.asList(privilege1))); - user1.setOrganization(organizationRepository.findByName("FirstOrg")); - userRepository.save(user1); - // - final User user2 = new User(); - user2.setUsername("tom"); - user2.setPassword(encoder.encode("111")); - user2.setPrivileges(new HashSet(Arrays.asList(privilege1, privilege2))); - user2.setOrganization(organizationRepository.findByName("SecondOrg")); - userRepository.save(user2); - } - - private void initOrganizations() { - final Organization org1 = new Organization("FirstOrg"); - organizationRepository.save(org1); - // - final Organization org2 = new Organization("SecondOrg"); - organizationRepository.save(org2); - } - - private void initPrivileges() { - final Privilege privilege1 = new Privilege("FOO_READ_PRIVILEGE"); - privilegeRepository.save(privilege1); - // - final Privilege privilege2 = new Privilege("FOO_WRITE_PRIVILEGE"); - privilegeRepository.save(privilege2); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java deleted file mode 100644 index 1319a7b9f8..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.baeldung.custom.persistence.dao; - -import org.baeldung.custom.persistence.model.Organization; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface OrganizationRepository extends JpaRepository { - - public Organization findByName(String name); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java deleted file mode 100644 index c232bb986c..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.baeldung.custom.persistence.dao; - -import org.baeldung.custom.persistence.model.Privilege; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface PrivilegeRepository extends JpaRepository { - - public Privilege findByName(String name); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java deleted file mode 100644 index 68dd1d756c..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.custom.persistence.dao; - -import org.baeldung.custom.persistence.model.User; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.transaction.annotation.Transactional; - -public interface UserRepository extends JpaRepository { - - User findByUsername(final String username); - - @Transactional - void removeUserByUsername(String username); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java deleted file mode 100644 index f139382eea..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.baeldung.custom.persistence.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Foo { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false) - private String name; - - // - - public Foo() { - super(); - } - - public Foo(String name) { - super(); - this.name = name; - } - - // - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - // - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("Foo [id=").append(id).append(", name=").append(name).append("]"); - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((id == null) ? 0 : id.hashCode()); - result = (prime * result) + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Foo other = (Foo) obj; - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java deleted file mode 100644 index 1fdb88e320..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.baeldung.custom.persistence.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Organization { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false, unique = true) - private String name; - - // - - public Organization() { - super(); - } - - public Organization(String name) { - super(); - this.name = name; - } - - // - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - // - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("Organization [id=").append(id).append(", name=").append(name).append("]"); - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((id == null) ? 0 : id.hashCode()); - result = (prime * result) + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Organization other = (Organization) obj; - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java deleted file mode 100644 index ed3edd5085..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.baeldung.custom.persistence.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Privilege { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false, unique = true) - private String name; - - // - - public Privilege() { - super(); - } - - public Privilege(String name) { - super(); - this.name = name; - } - - // - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - // - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("Privilege [id=").append(id).append(", name=").append(name).append("]"); - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((id == null) ? 0 : id.hashCode()); - result = (prime * result) + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Privilege other = (Privilege) obj; - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - return true; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java deleted file mode 100644 index c14ef034b4..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.baeldung.custom.persistence.model; - -import java.util.Set; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name = "user_table") -public class User { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @Column(nullable = false, unique = true) - private String username; - - private String password; - - @ManyToMany(fetch = FetchType.EAGER) - @JoinTable(name = "users_privileges", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id")) - private Set privileges; - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "organization_id", referencedColumnName = "id") - private Organization organization; - - // - - public User() { - super(); - } - - // - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Set getPrivileges() { - return privileges; - } - - public void setPrivileges(Set privileges) { - this.privileges = privileges; - } - - public Organization getOrganization() { - return organization; - } - - public void setOrganization(Organization organization) { - this.organization = organization; - } - - // - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("User [id=").append(id).append(", username=").append(username).append(", password=").append(password).append(", privileges=").append(privileges).append(", organization=").append(organization).append("]"); - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((id == null) ? 0 : id.hashCode()); - result = (prime * result) + ((organization == null) ? 0 : organization.hashCode()); - result = (prime * result) + ((password == null) ? 0 : password.hashCode()); - result = (prime * result) + ((privileges == null) ? 0 : privileges.hashCode()); - result = (prime * result) + ((username == null) ? 0 : username.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final User other = (User) obj; - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (organization == null) { - if (other.organization != null) { - return false; - } - } else if (!organization.equals(other.organization)) { - return false; - } - if (password == null) { - if (other.password != null) { - return false; - } - } else if (!password.equals(other.password)) { - return false; - } - if (privileges == null) { - if (other.privileges != null) { - return false; - } - } else if (!privileges.equals(other.privileges)) { - return false; - } - if (username == null) { - if (other.username != null) { - return false; - } - } else if (!username.equals(other.username)) { - return false; - } - return true; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java deleted file mode 100644 index 646f5a387f..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.custom.security; - -import org.aopalliance.intercept.MethodInvocation; -import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; -import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; -import org.springframework.security.authentication.AuthenticationTrustResolver; -import org.springframework.security.authentication.AuthenticationTrustResolverImpl; -import org.springframework.security.core.Authentication; - -public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler { - private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); - - @Override - protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { - // final CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication); - final MySecurityExpressionRoot root = new MySecurityExpressionRoot(authentication); - root.setPermissionEvaluator(getPermissionEvaluator()); - root.setTrustResolver(this.trustResolver); - root.setRoleHierarchy(getRoleHierarchy()); - return root; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java deleted file mode 100644 index b2f2be8cf5..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.baeldung.custom.security; - -import org.baeldung.custom.persistence.model.User; -import org.springframework.security.access.expression.SecurityExpressionRoot; -import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; -import org.springframework.security.core.Authentication; - -public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations { - - private Object filterObject; - private Object returnObject; - - public CustomMethodSecurityExpressionRoot(Authentication authentication) { - super(authentication); - } - - // - public boolean isMember(Long OrganizationId) { - final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); - return user.getOrganization().getId().longValue() == OrganizationId.longValue(); - } - - // - - @Override - public Object getFilterObject() { - return this.filterObject; - } - - @Override - public Object getReturnObject() { - return this.returnObject; - } - - @Override - public Object getThis() { - return this; - } - - @Override - public void setFilterObject(Object obj) { - this.filterObject = obj; - } - - @Override - public void setReturnObject(Object obj) { - this.returnObject = obj; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java deleted file mode 100644 index f436b4488b..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.custom.security; - -import java.io.Serializable; - -import org.springframework.security.access.PermissionEvaluator; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; - -public class CustomPermissionEvaluator implements PermissionEvaluator { - - @Override - public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) { - if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)) { - return false; - } - final String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase(); - return hasPrivilege(auth, targetType, permission.toString().toUpperCase()); - } - - @Override - public boolean hasPermission(Authentication auth, Serializable targetId, String targetType, Object permission) { - if ((auth == null) || (targetType == null) || !(permission instanceof String)) { - return false; - } - return hasPrivilege(auth, targetType.toUpperCase(), permission.toString().toUpperCase()); - } - - private boolean hasPrivilege(Authentication auth, String targetType, String permission) { - for (final GrantedAuthority grantedAuth : auth.getAuthorities()) { - System.out.println("here " + grantedAuth); - if (grantedAuth.getAuthority().startsWith(targetType)) { - if (grantedAuth.getAuthority().contains(permission)) { - return true; - } - } - } - return false; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java deleted file mode 100644 index 03d18cb755..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java +++ /dev/null @@ -1,203 +0,0 @@ -package org.baeldung.custom.security; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.baeldung.custom.persistence.model.User; -import org.springframework.security.access.PermissionEvaluator; -import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; -import org.springframework.security.access.hierarchicalroles.RoleHierarchy; -import org.springframework.security.authentication.AuthenticationTrustResolver; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; - -public class MySecurityExpressionRoot implements MethodSecurityExpressionOperations { - protected final Authentication authentication; - private AuthenticationTrustResolver trustResolver; - private RoleHierarchy roleHierarchy; - private Set roles; - private String defaultRolePrefix = "ROLE_"; - - public final boolean permitAll = true; - public final boolean denyAll = false; - private PermissionEvaluator permissionEvaluator; - public final String read = "read"; - public final String write = "write"; - public final String create = "create"; - public final String delete = "delete"; - public final String admin = "administration"; - - // - - private Object filterObject; - private Object returnObject; - - public MySecurityExpressionRoot(Authentication authentication) { - if (authentication == null) { - throw new IllegalArgumentException("Authentication object cannot be null"); - } - this.authentication = authentication; - } - - @Override - public final boolean hasAuthority(String authority) { - throw new RuntimeException("method hasAuthority() not allowed"); - } - - // - public boolean isMember(Long OrganizationId) { - final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); - return user.getOrganization().getId().longValue() == OrganizationId.longValue(); - } - - // - - @Override - public final boolean hasAnyAuthority(String... authorities) { - return hasAnyAuthorityName(null, authorities); - } - - @Override - public final boolean hasRole(String role) { - return hasAnyRole(role); - } - - @Override - public final boolean hasAnyRole(String... roles) { - return hasAnyAuthorityName(defaultRolePrefix, roles); - } - - private boolean hasAnyAuthorityName(String prefix, String... roles) { - final Set roleSet = getAuthoritySet(); - - for (final String role : roles) { - final String defaultedRole = getRoleWithDefaultPrefix(prefix, role); - if (roleSet.contains(defaultedRole)) { - return true; - } - } - - return false; - } - - @Override - public final Authentication getAuthentication() { - return authentication; - } - - @Override - public final boolean permitAll() { - return true; - } - - @Override - public final boolean denyAll() { - return false; - } - - @Override - public final boolean isAnonymous() { - return trustResolver.isAnonymous(authentication); - } - - @Override - public final boolean isAuthenticated() { - return !isAnonymous(); - } - - @Override - public final boolean isRememberMe() { - return trustResolver.isRememberMe(authentication); - } - - @Override - public final boolean isFullyAuthenticated() { - return !trustResolver.isAnonymous(authentication) && !trustResolver.isRememberMe(authentication); - } - - public Object getPrincipal() { - return authentication.getPrincipal(); - } - - public void setTrustResolver(AuthenticationTrustResolver trustResolver) { - this.trustResolver = trustResolver; - } - - public void setRoleHierarchy(RoleHierarchy roleHierarchy) { - this.roleHierarchy = roleHierarchy; - } - - public void setDefaultRolePrefix(String defaultRolePrefix) { - this.defaultRolePrefix = defaultRolePrefix; - } - - private Set getAuthoritySet() { - if (roles == null) { - roles = new HashSet(); - Collection userAuthorities = authentication.getAuthorities(); - - if (roleHierarchy != null) { - userAuthorities = roleHierarchy.getReachableGrantedAuthorities(userAuthorities); - } - - roles = AuthorityUtils.authorityListToSet(userAuthorities); - } - - return roles; - } - - @Override - public boolean hasPermission(Object target, Object permission) { - return permissionEvaluator.hasPermission(authentication, target, permission); - } - - @Override - public boolean hasPermission(Object targetId, String targetType, Object permission) { - return permissionEvaluator.hasPermission(authentication, (Serializable) targetId, targetType, permission); - } - - public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) { - this.permissionEvaluator = permissionEvaluator; - } - - private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) { - if (role == null) { - return role; - } - if ((defaultRolePrefix == null) || (defaultRolePrefix.length() == 0)) { - return role; - } - if (role.startsWith(defaultRolePrefix)) { - return role; - } - return defaultRolePrefix + role; - } - - @Override - public Object getFilterObject() { - return this.filterObject; - } - - @Override - public Object getReturnObject() { - return this.returnObject; - } - - @Override - public Object getThis() { - return this; - } - - @Override - public void setFilterObject(Object obj) { - this.filterObject = obj; - } - - @Override - public void setReturnObject(Object obj) { - this.returnObject = obj; - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java deleted file mode 100644 index b9b40fbcb9..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.baeldung.custom.security; - -import org.baeldung.custom.persistence.dao.UserRepository; -import org.baeldung.custom.persistence.model.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -@Service -public class MyUserDetailsService implements UserDetailsService { - - @Autowired - private UserRepository userRepository; - - public MyUserDetailsService() { - super(); - } - - // API - - @Override - public UserDetails loadUserByUsername(final String username) { - final User user = userRepository.findByUsername(username); - if (user == null) { - throw new UsernameNotFoundException(username); - } - return new MyUserPrincipal(user); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java deleted file mode 100644 index 7d57227316..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.baeldung.custom.security; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.baeldung.custom.persistence.model.Privilege; -import org.baeldung.custom.persistence.model.User; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -public class MyUserPrincipal implements UserDetails { - - private static final long serialVersionUID = 1L; - - private final User user; - - // - - public MyUserPrincipal(User user) { - this.user = user; - } - - // - - @Override - public String getUsername() { - return user.getUsername(); - } - - @Override - public String getPassword() { - return user.getPassword(); - } - - @Override - public Collection getAuthorities() { - final List authorities = new ArrayList(); - for (final Privilege privilege : user.getPrivileges()) { - authorities.add(new SimpleGrantedAuthority(privilege.getName())); - } - return authorities; - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } - - // - - public User getUser() { - return user; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java deleted file mode 100644 index 74de45d1a8..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.baeldung.custom.web; - -import org.baeldung.custom.persistence.dao.OrganizationRepository; -import org.baeldung.custom.persistence.model.Foo; -import org.baeldung.custom.persistence.model.Organization; -import org.baeldung.custom.security.MyUserPrincipal; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; - -@Controller -public class MainController { - - @Autowired - private OrganizationRepository organizationRepository; - - // @PostAuthorize("hasPermission(returnObject, 'read')") - @PreAuthorize("hasPermission(#id, 'Foo', 'read')") - @GetMapping("/foos/{id}") - @ResponseBody - public Foo findById(@PathVariable final long id) { - return new Foo("Sample"); - } - - @PreAuthorize("hasPermission(#foo, 'write')") - @PostMapping("/foos") - @ResponseStatus(HttpStatus.CREATED) - @ResponseBody - public Foo create(@RequestBody final Foo foo) { - return foo; - } - - // - - @PreAuthorize("hasAuthority('FOO_READ_PRIVILEGE')") - @GetMapping("/foos") - @ResponseBody - public Foo findFooByName(@RequestParam final String name) { - return new Foo(name); - } - - // - - @PreAuthorize("isMember(#id)") - @GetMapping("/organizations/{id}") - @ResponseBody - public Organization findOrgById(@PathVariable final long id) { - return organizationRepository.findById(id) - .orElse(null); - } - - @PreAuthorize("hasPermission(#id, 'Foo', 'read')") - @GetMapping("/user") - @ResponseBody - public MyUserPrincipal retrieveUserDetails(@AuthenticationPrincipal MyUserPrincipal principal) { - return principal; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java deleted file mode 100644 index b68abbaed1..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.ip; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -public class IpApplication extends SpringBootServletInitializer { - public static void main(String[] args) { - SpringApplication.run(IpApplication.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java deleted file mode 100644 index 078dd81259..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.baeldung.ip.config; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.web.authentication.WebAuthenticationDetails; -import org.springframework.stereotype.Component; - -@Component -public class CustomIpAuthenticationProvider implements AuthenticationProvider { - - Set whitelist = new HashSet(); - - public CustomIpAuthenticationProvider() { - super(); - whitelist.add("11.11.11.11"); - whitelist.add("127.0.0.1"); - } - - @Override - public Authentication authenticate(Authentication auth) throws AuthenticationException { - WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails(); - String userIp = details.getRemoteAddress(); - if(! whitelist.contains(userIp)){ - throw new BadCredentialsException("Invalid IP Address"); - } - final String name = auth.getName(); - final String password = auth.getCredentials().toString(); - - if (name.equals("john") && password.equals("123")) { - List authorities =new ArrayList(); - authorities.add(new SimpleGrantedAuthority("ROLE_USER")); - return new UsernamePasswordAuthenticationToken(name, password, authorities); - } - else{ - throw new BadCredentialsException("Invalid username or password"); - } - } - - @Override - public boolean supports(Class authentication) { - return authentication.equals(UsernamePasswordAuthenticationToken.class); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java deleted file mode 100644 index 3a8032a734..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.baeldung.ip.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity//(debug = true) -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private CustomIpAuthenticationProvider authenticationProvider; - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("john").password("{noop}123").authorities("ROLE_USER"); - // auth.authenticationProvider(authenticationProvider); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() -// .antMatchers("/foos/**").hasIpAddress("11.11.11.11") - .antMatchers("/foos/**").access("isAuthenticated() and hasIpAddress('11.11.11.11')") - .anyRequest().authenticated() - .and().formLogin().permitAll() - .and().csrf().disable(); - // @formatter:on - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java deleted file mode 100644 index 1d22ca4c67..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.baeldung.ip.config; - - -//@Configuration -//@EnableWebSecurity -//@ImportResource({ "classpath:spring-security-ip.xml" }) -public class SecurityXmlConfig { - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java deleted file mode 100644 index 940194c421..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.ip.web; - -import java.util.List; - -import javax.servlet.Filter; -import javax.servlet.http.HttpServletRequest; - -import org.baeldung.custom.persistence.model.Foo; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -@Controller -public class MainController { - - @Autowired - @Qualifier("springSecurityFilterChain") - private Filter springSecurityFilterChain; - - @RequestMapping(method = RequestMethod.GET, value = "/filters") - @ResponseBody - public void getFilters() { - FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain; - List list = filterChainProxy.getFilterChains(); - list.stream() - .flatMap(chain -> chain.getFilters().stream()) - .forEach(filter -> System.out.println(filter.getClass())); - } - - @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") - @ResponseBody - public Foo findById(@PathVariable final long id, HttpServletRequest request) { - return new Foo("Sample"); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java deleted file mode 100644 index 6936cdc560..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.jdbcauthentication.h2; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; - -@SpringBootApplication -@EnableWebSecurity -@PropertySource("classpath:application-defaults.properties") -public class H2JdbcAuthenticationApplication { - - public static void main(String[] args) { - SpringApplication.run(H2JdbcAuthenticationApplication.class, args); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java deleted file mode 100644 index 8b8696f0b2..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.baeldung.jdbcauthentication.h2.config; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - httpSecurity.authorizeRequests() - .antMatchers("/h2-console/**") - .permitAll() - .anyRequest() - .authenticated() - .and() - .formLogin() - .permitAll(); - httpSecurity.csrf() - .ignoringAntMatchers("/h2-console/**"); - httpSecurity.headers() - .frameOptions() - .sameOrigin(); - } - - @Autowired - private DataSource dataSource; - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.jdbcAuthentication() - .dataSource(dataSource) - .withDefaultSchema() - .withUser(User.withUsername("user") - .password(passwordEncoder().encode("pass")) - .roles("USER")); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java deleted file mode 100644 index 0955061614..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.jdbcauthentication.h2.web; - -import java.security.Principal; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/principal") -public class UserController { - - @GetMapping - public Principal retrievePrincipal(Principal principal) { - return principal; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java deleted file mode 100644 index 52934e0096..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.jdbcauthentication.mysql; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-mysql.properties") -public class MySqlJdbcAuthenticationApplication { - - public static void main(String[] args) { - SpringApplication.run(MySqlJdbcAuthenticationApplication.class, args); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java deleted file mode 100644 index 157c0be748..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.jdbcauthentication.mysql.config; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class SecurityConfiguration { - - @Autowired - private DataSource dataSource; - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.jdbcAuthentication() - .dataSource(dataSource) - .usersByUsernameQuery("select email,password,enabled " - + "from bael_users " - + "where email = ?") - .authoritiesByUsernameQuery("select email,authority " - + "from authorities " - + "where email = ?"); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java deleted file mode 100644 index f1060b5f78..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.jdbcauthentication.mysql.web; - -import java.security.Principal; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/principal") -public class UserController { - - @GetMapping - public Principal retrievePrincipal(Principal principal) { - return principal; - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java deleted file mode 100644 index 2c4d1a5255..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.jdbcauthentication.postgre; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-postgre.properties") -public class PostgreJdbcAuthenticationApplication { - - public static void main(String[] args) { - SpringApplication.run(PostgreJdbcAuthenticationApplication.class, args); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java deleted file mode 100644 index ba79635852..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.baeldung.jdbcauthentication.postgre.config; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class SecurityConfiguration { - - @Autowired - private DataSource dataSource; - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.jdbcAuthentication() - .dataSource(dataSource); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java deleted file mode 100644 index c8fd3812b1..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.jdbcauthentication.postgre.web; - -import java.security.Principal; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/principal") -public class UserController { - - @GetMapping - public Principal retrievePrincipal(Principal principal) { - return principal; - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java deleted file mode 100644 index 1a89c362cd..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.baeldung.multipleauthproviders; - -import java.util.Collections; - -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.stereotype.Component; - -@Component -public class CustomAuthenticationProvider implements AuthenticationProvider { - @Override - public Authentication authenticate(Authentication auth) throws AuthenticationException { - final String username = auth.getName(); - final String password = auth.getCredentials() - .toString(); - - if ("externaluser".equals(username) && "pass".equals(password)) { - return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList()); - } else { - throw new BadCredentialsException("External system authentication failed"); - } - } - - @Override - public boolean supports(Class auth) { - return auth.equals(UsernamePasswordAuthenticationToken.class); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java deleted file mode 100644 index b63169bb00..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.baeldung.multipleauthproviders; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class MultipleAuthController { - - @GetMapping("/api/ping") - public String getPing() { - return "OK"; - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java deleted file mode 100644 index 1f641298c3..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.multipleauthproviders; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -// @ImportResource({ "classpath*:spring-security-multiple-auth-providers.xml" }) -public class MultipleAuthProvidersApplication { - public static void main(String[] args) { - SpringApplication.run(MultipleAuthProvidersApplication.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java deleted file mode 100644 index 3819e981a2..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.multipleauthproviders; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@EnableWebSecurity -public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - CustomAuthenticationProvider customAuthProvider; - - @Override - public void configure(AuthenticationManagerBuilder auth) throws Exception { - - auth.authenticationProvider(customAuthProvider); - - auth.inMemoryAuthentication() - .withUser("memuser") - .password(passwordEncoder().encode("pass")) - .roles("USER"); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.httpBasic() - .and() - .authorizeRequests() - .antMatchers("/api/**") - .authenticated(); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java deleted file mode 100644 index 847dab073e..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.multipleentrypoints; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -// @ImportResource({"classpath*:spring-security-multiple-entry.xml"}) -public class MultipleEntryPointsApplication { - public static void main(String[] args) { - SpringApplication.run(MultipleEntryPointsApplication.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java deleted file mode 100644 index dc89c83cde..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.baeldung.multipleentrypoints; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; -import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -@Configuration -@EnableWebSecurity -public class MultipleEntryPointsSecurityConfig { - - @Bean - public UserDetailsService userDetailsService() throws Exception { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); - manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); - return manager; - } - - @Bean - public PasswordEncoder encoder() { - return new BCryptPasswordEncoder(); - } - - @Configuration - @Order(1) - public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - //@formatter:off - http.antMatcher("/admin/**") - .authorizeRequests().anyRequest().hasRole("ADMIN") - .and().httpBasic().authenticationEntryPoint(authenticationEntryPoint()) - .and().exceptionHandling().accessDeniedPage("/403"); - //@formatter:on - } - - @Bean - public AuthenticationEntryPoint authenticationEntryPoint(){ - BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); - entryPoint.setRealmName("admin realm"); - return entryPoint; - } - } - - @Configuration - @Order(2) - public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { - - protected void configure(HttpSecurity http) throws Exception { - - //@formatter:off - http.antMatcher("/user/**") - .authorizeRequests().anyRequest().hasRole("USER") - .and().formLogin().loginProcessingUrl("/user/login") - .failureUrl("/userLogin?error=loginError").defaultSuccessUrl("/user/myUserPage") - .and().logout().logoutUrl("/user/logout").logoutSuccessUrl("/multipleHttpLinks") - .deleteCookies("JSESSIONID") - .and().exceptionHandling() - .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPointWithWarning(), new AntPathRequestMatcher("/user/private/**")) - .defaultAuthenticationEntryPointFor(loginUrlauthenticationEntryPoint(), new AntPathRequestMatcher("/user/general/**")) - .accessDeniedPage("/403") - .and().csrf().disable(); - //@formatter:on - } - - @Bean - public AuthenticationEntryPoint loginUrlauthenticationEntryPoint(){ - return new LoginUrlAuthenticationEntryPoint("/userLogin"); - } - - @Bean - public AuthenticationEntryPoint loginUrlauthenticationEntryPointWithWarning(){ - return new LoginUrlAuthenticationEntryPoint("/userLoginWithWarning"); - } - } - - @Configuration - @Order(3) - public static class App3ConfigurationAdapter extends WebSecurityConfigurerAdapter { - - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/guest/**").authorizeRequests().anyRequest().permitAll(); - } - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java deleted file mode 100644 index b3462d4061..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.baeldung.multipleentrypoints; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class PagesController { - - @RequestMapping("/multipleHttpLinks") - public String getMultipleHttpLinksPage() { - return "multipleHttpElems/multipleHttpLinks"; - } - - @RequestMapping("/admin/myAdminPage") - public String getAdminPage() { - return "multipleHttpElems/myAdminPage"; - } - - @RequestMapping("/user/general/myUserPage") - public String getUserPage() { - return "multipleHttpElems/myUserPage"; - } - - @RequestMapping("/user/private/myPrivateUserPage") - public String getPrivateUserPage() { - return "multipleHttpElems/myPrivateUserPage"; - } - - @RequestMapping("/guest/myGuestPage") - public String getGuestPage() { - return "multipleHttpElems/myGuestPage"; - } - - @RequestMapping("/userLogin") - public String getUserLoginPage() { - return "multipleHttpElems/login"; - } - - @RequestMapping("/userLoginWithWarning") - public String getUserLoginPageWithWarning() { - return "multipleHttpElems/loginWithWarning"; - } - - @RequestMapping("/403") - public String getAccessDeniedPage() { - return "403"; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java deleted file mode 100644 index 90bb5e4260..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.multiplelogin; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -@ComponentScan("org.baeldung.multiplelogin") -public class MultipleLoginApplication { - public static void main(String[] args) { - SpringApplication.run(MultipleLoginApplication.class, args); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java deleted file mode 100644 index 204b186411..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.baeldung.multiplelogin; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.springframework.context.annotation.ComponentScan; - -@EnableWebMvc -@Configuration -@ComponentScan("org.baeldung.controller") -public class MultipleLoginMvcConfig implements WebMvcConfigurer { - - public MultipleLoginMvcConfig() { - super(); - } - - // API - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - registry.addViewController("/anonymous.html"); - - registry.addViewController("/login.html"); - registry.addViewController("/homepage.html"); - registry.addViewController("/console.html"); - } - - @Bean - public ViewResolver viewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/view/"); - bean.setSuffix(".jsp"); - - return bean; - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java deleted file mode 100644 index 9962bf41a9..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.baeldung.multiplelogin; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -@Configuration -@EnableWebSecurity -public class MultipleLoginSecurityConfig { - - @Bean - public UserDetailsService userDetailsService() throws Exception { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); - manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); - return manager; - } - - @Bean - public static PasswordEncoder encoder() { - return new BCryptPasswordEncoder(); - } - - @Configuration - @Order(1) - public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { - - public App1ConfigurationAdapter() { - super(); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("admin").password(encoder().encode("admin")).roles("ADMIN"); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/admin*").authorizeRequests().anyRequest().hasRole("ADMIN") - // log in - .and().formLogin().loginPage("/loginAdmin").loginProcessingUrl("/admin_login").failureUrl("/loginAdmin?error=loginError").defaultSuccessUrl("/adminPage") - // logout - .and().logout().logoutUrl("/admin_logout").logoutSuccessUrl("/protectedLinks").deleteCookies("JSESSIONID").and().exceptionHandling().accessDeniedPage("/403").and().csrf().disable(); - } - } - - @Configuration - @Order(2) - public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { - - public App2ConfigurationAdapter() { - super(); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user").password(encoder().encode("user")).roles("USER"); - } - - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/user*").authorizeRequests().anyRequest().hasRole("USER") - // log in - .and().formLogin().loginPage("/loginUser").loginProcessingUrl("/user_login").failureUrl("/loginUser?error=loginError").defaultSuccessUrl("/userPage") - // logout - .and().logout().logoutUrl("/user_logout").logoutSuccessUrl("/protectedLinks").deleteCookies("JSESSIONID").and().exceptionHandling().accessDeniedPage("/403").and().csrf().disable(); - } - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java deleted file mode 100644 index 61d7da127c..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.baeldung.multiplelogin; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -@Controller -public class UsersController { - - @GetMapping("/protectedLinks") - public String getAnonymousPage() { - return "protectedLinks"; - } - - @GetMapping("/userPage") - public String getUserPage() { - return "userPage"; - } - - @GetMapping("/adminPage") - public String getAdminPage() { - return "adminPage"; - } - - @GetMapping("/loginAdmin") - public String getAdminLoginPage() { - return "loginAdmin"; - } - - @GetMapping("/loginUser") - public String getUserLoginPage() { - return "loginUser"; - } - - @GetMapping("/403") - public String getAccessDeniedPage() { - return "403"; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java deleted file mode 100644 index d7195ac358..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.baeldung.rolesauthorities; - -import org.baeldung.rolesauthorities.model.User; -import org.baeldung.rolesauthorities.persistence.UserRepository; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetailsService; - -public class CustomAuthenticationProvider extends DaoAuthenticationProvider { - - private final UserRepository userRepository; - @SuppressWarnings("unused") - private UserDetailsService userDetailsService; - - public CustomAuthenticationProvider(UserRepository userRepository, UserDetailsService userDetailsService){ - super(); - this.setUserDetailsService(userDetailsService); - this.userRepository = userRepository; - } - - @Override - public Authentication authenticate(Authentication auth) throws AuthenticationException { - final User user = userRepository.findByEmail(auth.getName()); - if ((user == null)) { - throw new BadCredentialsException("Invalid username or password"); - } - final Authentication result = super.authenticate(auth); - return new UsernamePasswordAuthenticationToken(user, result.getCredentials(), result.getAuthorities()); - } - - @Override - public boolean supports(Class authentication) { - return authentication.equals(UsernamePasswordAuthenticationToken.class); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java deleted file mode 100644 index b0dc0b7537..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.baeldung.rolesauthorities; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; -import org.springframework.stereotype.Component; - -@Component("myLogoutSuccessHandler") -public class MyLogoutSuccessHandler implements LogoutSuccessHandler { - - @Override - public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - final HttpSession session = request.getSession(); - if (session != null) { - session.removeAttribute("user"); - } - - response.sendRedirect("/"); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java deleted file mode 100644 index f38b867a75..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.baeldung.rolesauthorities; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import org.baeldung.rolesauthorities.model.Role; -import org.baeldung.rolesauthorities.model.User; -import org.baeldung.rolesauthorities.persistence.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service("userDetailsService") -@Transactional -public class MyUserDetailsService implements UserDetailsService { - - @Autowired - private UserRepository userRepository; - - public MyUserDetailsService() { - super(); - } - - // API - - @Override - public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { - - try { - User user = userRepository.findByEmail(email); - if (user == null) { - throw new UsernameNotFoundException("No user found with username: " + email); - } - org.springframework.security.core.userdetails.User userDetails = new org.springframework.security.core.userdetails.User(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, getAuthorities(user.getRoles())); - return userDetails; - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - - // UTIL - - private final Collection getAuthorities(Collection roles) { - List authorities = new ArrayList(); - for (Role role: roles) { - authorities.add(new SimpleGrantedAuthority(role.getName())); - authorities.addAll(role.getPrivileges() - .stream() - .map(p -> new SimpleGrantedAuthority(p.getName())) - .collect(Collectors.toList())); - } - return authorities; - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java deleted file mode 100644 index 3c4e6f7b5a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.rolesauthorities; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableAutoConfiguration -@ComponentScan("org.baeldung.rolesauthorities") -public class RolesAuthoritiesApplication extends SpringBootServletInitializer { - public static void main(String[] args) { - System.setProperty("spring.profiles.default", "rolesauthorities"); - SpringApplication.run(RolesAuthoritiesApplication.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java deleted file mode 100644 index c42958457e..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.baeldung.rolesauthorities.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -@EnableWebMvc -public class MvcConfig implements WebMvcConfigurer { - - public MvcConfig() { - super(); - } - - // - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - registry.addViewController("/").setViewName("forward:/home"); - registry.addViewController("/protectedbynothing").setViewName("rolesauthorities/protectedbynothing"); - registry.addViewController("/protectedbyrole").setViewName("rolesauthorities/protectedbyrole"); - registry.addViewController("/protectedbyauthority").setViewName("rolesauthorities/protectedbyauthority"); - registry.addViewController("/login").setViewName("rolesauthorities/login"); - registry.addViewController("/home").setViewName("rolesauthorities/home"); - registry.addViewController("/logout"); - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java deleted file mode 100644 index 7624dd7d39..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.baeldung.rolesauthorities.config; - -import org.baeldung.rolesauthorities.CustomAuthenticationProvider; -import org.baeldung.rolesauthorities.persistence.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; - -@Configuration -@ComponentScan(basePackages = { "org.baeldung.rolesauthorities" }) -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private UserRepository userRepository; - - @Autowired - private UserDetailsService userDetailsService; - - @Autowired - private LogoutSuccessHandler myLogoutSuccessHandler; - - public SecurityConfig() { - super(); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.authenticationProvider(authProvider()); - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring() - .antMatchers("/resources/**"); - } - - - @Override - protected void configure(HttpSecurity http) throws Exception { - - // @formatter:off - http - .csrf().disable() - .authorizeRequests() - .antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll() - .antMatchers("/protectedbyrole").hasRole("USER") - .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE") - .and() - .formLogin() - .loginPage("/login") - .failureUrl("/login?error=true") - .permitAll() - .and() - .logout() - .logoutSuccessHandler(myLogoutSuccessHandler) - .invalidateHttpSession(false) - .logoutSuccessUrl("/logout.html?logSucc=true") - .deleteCookies("JSESSIONID") - .permitAll(); - // @formatter:on - } - - // beans - - @Bean - public DaoAuthenticationProvider authProvider() { - final CustomAuthenticationProvider authProvider - = new CustomAuthenticationProvider(userRepository, userDetailsService); - authProvider.setPasswordEncoder(encoder()); - return authProvider; - } - - @Bean - public PasswordEncoder encoder() { - return new BCryptPasswordEncoder(11); - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java deleted file mode 100644 index ab2cd08610..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.baeldung.rolesauthorities.model; - -import java.util.Collection; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToMany; - -@Entity -public class Privilege { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - private String name; - - @ManyToMany(mappedBy = "privileges") - private Collection roles; - - public Privilege() { - super(); - } - - public Privilege(String name) { - super(); - this.name = name; - } - - // - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Collection getRoles() { - return roles; - } - - public void setRoles(Collection roles) { - this.roles = roles; - } - - @Override - public int hashCode() { - int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Privilege other = (Privilege) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("Privilege [name=").append(name).append("]").append("[id=").append(id).append("]"); - return builder.toString(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java deleted file mode 100644 index ac33e32fcf..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.baeldung.rolesauthorities.model; - -import java.util.Collection; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; - -@Entity -public class Role { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @ManyToMany(mappedBy = "roles") - private Collection users; - - @ManyToMany - @JoinTable(name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id")) - private Collection privileges; - - private String name; - - public Role() { - super(); - } - - public Role(String name) { - super(); - this.name = name; - } - - // - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Collection getUsers() { - return users; - } - - public void setUsers(Collection users) { - this.users = users; - } - - public Collection getPrivileges() { - return privileges; - } - - public void setPrivileges(Collection privileges) { - this.privileges = privileges; - } - - @Override - public int hashCode() { - int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Role role = (Role) obj; - if (!role.equals(role.name)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("Role [name=").append(name).append("]").append("[id=").append(id).append("]"); - return builder.toString(); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java deleted file mode 100644 index dc1096541d..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.baeldung.rolesauthorities.model; - -import java.util.Collection; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; - - -@Entity -@Table(name = "user_account") -public class User { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - private String firstName; - - private String lastName; - - private String email; - - @Column(length = 60) - private String password; - - private boolean enabled; - - private boolean isUsing2FA; - - // - - @ManyToMany(fetch = FetchType.EAGER) - @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) - private Collection roles; - - public User() { - super(); - this.enabled = false; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String username) { - this.email = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Collection getRoles() { - return roles; - } - - public void setRoles(Collection roles) { - this.roles = roles; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isUsing2FA() { - return isUsing2FA; - } - - public void setUsing2FA(boolean isUsing2FA) { - this.isUsing2FA = isUsing2FA; - } - - @Override - public int hashCode() { - int prime = 31; - int result = 1; - result = (prime * result) + ((email == null) ? 0 : email.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - User user = (User) obj; - if (!email.equals(user.email)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("User [id=").append(id).append(", firstName=") - .append(firstName).append(", lastName=").append(lastName).append(", email=").append(email).append(", password=").append(password).append(", enabled=").append(enabled).append(", roles=").append(roles).append("]"); - return builder.toString(); - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java deleted file mode 100644 index 2c508cbd20..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import org.baeldung.rolesauthorities.model.User; - -public interface IUserService { - - User findUserByEmail(String email); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java deleted file mode 100644 index 05d5f2b870..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import org.baeldung.rolesauthorities.model.Privilege; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface PrivilegeRepository extends JpaRepository { - - Privilege findByName(String name); - - void delete(Privilege privilege); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java deleted file mode 100644 index 25e3b3a1f6..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import org.baeldung.rolesauthorities.model.Role; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface RoleRepository extends JpaRepository { - - Role findByName(String name); - - void delete(Role role); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java deleted file mode 100644 index 46dad4f06d..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.baeldung.rolesauthorities.model.Privilege; -import org.baeldung.rolesauthorities.model.Role; -import org.baeldung.rolesauthorities.model.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - - -@Component -public class SetupDataLoader implements ApplicationListener { - - private boolean alreadySetup = false; - - @Autowired - private UserRepository userRepository; - - @Autowired - private RoleRepository roleRepository; - - @Autowired - private PrivilegeRepository privilegeRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Override - @Transactional - public void onApplicationEvent(ContextRefreshedEvent event) { - if (alreadySetup) { - return; - } - - // == create initial privileges - Privilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE"); - Privilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE"); - - // == create initial roles - List adminPrivileges = Arrays.asList(readPrivilege, writePrivilege); - createRoleIfNotFound("ROLE_ADMIN", adminPrivileges); - List rolePrivileges = new ArrayList<>(); - createRoleIfNotFound("ROLE_USER", rolePrivileges); - - Role adminRole = roleRepository.findByName("ROLE_ADMIN"); - User user = new User(); - user.setFirstName("Admin"); - user.setLastName("Admin"); - user.setEmail("admin@test.com"); - user.setPassword(passwordEncoder.encode("admin")); - user.setRoles(Arrays.asList(adminRole)); - user.setEnabled(true); - userRepository.save(user); - - Role basicRole = roleRepository.findByName("ROLE_USER"); - User basicUser = new User(); - basicUser.setFirstName("User"); - basicUser.setLastName("User"); - basicUser.setEmail("user@test.com"); - basicUser.setPassword(passwordEncoder.encode("user")); - basicUser.setRoles(Arrays.asList(basicRole)); - basicUser.setEnabled(true); - userRepository.save(basicUser); - - alreadySetup = true; - } - - @Transactional - private Privilege createPrivilegeIfNotFound(String name) { - Privilege privilege = privilegeRepository.findByName(name); - if (privilege == null) { - privilege = new Privilege(name); - privilegeRepository.save(privilege); - } - return privilege; - } - - @Transactional - private Role createRoleIfNotFound(String name, Collection privileges) { - Role role = roleRepository.findByName(name); - if (role == null) { - role = new Role(name); - role.setPrivileges(privileges); - roleRepository.save(role); - } - return role; - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java deleted file mode 100644 index bca2953153..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import org.baeldung.rolesauthorities.model.User; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserRepository extends JpaRepository { - - User findByEmail(String email); - - void delete(User user); - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java deleted file mode 100644 index 3b16c78898..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import javax.transaction.Transactional; - -import org.baeldung.rolesauthorities.model.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -@Transactional -public class UserService implements IUserService { - - @Autowired - private UserRepository repository; - - public User findUserByEmail(String email) { - return repository.findByEmail(email); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java deleted file mode 100644 index 17c249067c..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.ssl; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@PropertySource("classpath:application-defaults.properties") -public class HttpsEnabledApplication { - - public static void main(String... args) { - SpringApplication application = new SpringApplication(HttpsEnabledApplication.class); - application.setAdditionalProfiles("ssl"); - application.run(args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java deleted file mode 100644 index 92f92d8fc7..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.ssl; - -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests() - .antMatchers("/**") - .permitAll(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java deleted file mode 100644 index 72ad8abb85..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.ssl; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -@Controller -public class WelcomeController { - - @GetMapping("/welcome") - public String welcome() { - return "ssl/welcome"; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java deleted file mode 100644 index 2beda1e557..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.baeldung.voter; - -import java.time.LocalDateTime; -import java.util.Collection; - -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; - -public class MinuteBasedVoter implements AccessDecisionVoter { - @Override - public boolean supports(ConfigAttribute attribute) { - return true; - } - - @Override - public boolean supports(Class clazz) { - return true; - } - - @Override - public int vote(Authentication authentication, Object object, Collection collection) { - return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).filter(r -> "ROLE_USER".equals(r) && LocalDateTime.now().getMinute() % 2 != 0).findAny().map(s -> ACCESS_DENIED).orElseGet(() -> ACCESS_ABSTAIN); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java deleted file mode 100644 index d2078e6115..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.voter; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableAutoConfiguration -@ComponentScan(basePackages = { "org.baeldung.voter" }) -public class VoterApplication { - - public static void main(String[] args) { - SpringApplication.run(VoterApplication.class, args); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java deleted file mode 100644 index 8f41153f06..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.baeldung.voter; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -/** - * Created by ambrusadrianz on 30/09/2016. - */ - -@Configuration -public class VoterMvcConfig implements WebMvcConfigurer { - @Override - public void addViewControllers(ViewControllerRegistry registry) { - registry.addViewController("/").setViewName("private"); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java deleted file mode 100644 index 84ed070e8e..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.baeldung.voter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.vote.AuthenticatedVoter; -import org.springframework.security.access.vote.RoleVoter; -import org.springframework.security.access.vote.UnanimousBased; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.access.expression.WebExpressionVoter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -import java.util.Arrays; -import java.util.List; - -@Configuration -@EnableWebSecurity -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - // @formatter: off - auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("pass")).roles("USER").and().withUser("admin").password(passwordEncoder().encode("pass")).roles("ADMIN"); - // @formatter: on - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter: off - http - // needed so our login could work - .csrf().disable().authorizeRequests().anyRequest().authenticated().accessDecisionManager(accessDecisionManager()).antMatchers("/").hasAnyRole("ROLE_ADMIN", "ROLE_USER").and().formLogin().permitAll().and().logout().permitAll() - .deleteCookies("JSESSIONID").logoutSuccessUrl("/login"); - // @formatter: on - } - - @Bean - public AccessDecisionManager accessDecisionManager() { - // @formatter: off - List> decisionVoters = Arrays.asList(new WebExpressionVoter(), new RoleVoter(), new AuthenticatedVoter(), new MinuteBasedVoter()); - // @formatter: on - return new UnanimousBased(decisionVoters); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java b/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java deleted file mode 100644 index 8041585f42..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.voter; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; - -/** - * Created by ambrusadrianz on 09/10/2016. - */ -// @Configuration -// @ImportResource({ "classpath:spring-security-custom-voter.xml" }) -public class XmlSecurityConfig { - public XmlSecurityConfig() { - super(); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-defaults.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-defaults.properties deleted file mode 100644 index e2032c4a6b..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-defaults.properties +++ /dev/null @@ -1,13 +0,0 @@ -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.database=H2 -spring.jpa.show-sql=false -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect - -#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG - -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-mysql.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-mysql.properties deleted file mode 100644 index 568d0c5ca3..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-mysql.properties +++ /dev/null @@ -1,9 +0,0 @@ -spring.datasource.platform=mysql -spring.datasource.url=jdbc:mysql://localhost:3306/jdbc_authentication -spring.datasource.username=root -spring.datasource.password=pass - -spring.datasource.initialization-mode=always -spring.jpa.hibernate.ddl-auto=none - -spring.profiles.active=mysql diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-postgre.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-postgre.properties deleted file mode 100644 index 69faece45e..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-postgre.properties +++ /dev/null @@ -1,7 +0,0 @@ -spring.datasource.platform=postgre -spring.datasource.url=jdbc:postgresql://localhost:5432/jdbc_authentication -spring.datasource.username=postgres -spring.datasource.password=pass - -spring.datasource.initialization-mode=always -spring.jpa.hibernate.ddl-auto=none diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-ssl.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-ssl.properties deleted file mode 100644 index 090b775d03..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application-ssl.properties +++ /dev/null @@ -1,20 +0,0 @@ - -http.port=8080 - -server.port=8443 - -security.require-ssl=true - -# The format used for the keystore -server.ssl.key-store-type=PKCS12 -# The path to the keystore containing the certificate -server.ssl.key-store=classpath:keystore/baeldung.p12 -# The password used to generate the certificate -server.ssl.key-store-password=password -# The alias mapped to the certificate -server.ssl.key-alias=baeldung - -#trust store location -trust.store=classpath:keystore/baeldung.p12 -#trust store password -trust.store.password=password diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/application.properties deleted file mode 100644 index 3cf12afeb9..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8082 diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-mysql.sql b/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-mysql.sql deleted file mode 100644 index 8214fd8204..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-mysql.sql +++ /dev/null @@ -1,4 +0,0 @@ --- User user@email.com/pass -INSERT INTO bael_users (name, email, password, enabled) values ('user', 'user@email.com', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', 1); - -INSERT INTO authorities (email, authority) values ('user@email.com', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-postgre.sql b/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-postgre.sql deleted file mode 100644 index fcc6b54949..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/data-postgre.sql +++ /dev/null @@ -1,4 +0,0 @@ --- User user/pass -INSERT INTO users (username, password, enabled) values ('user', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', true); - -INSERT INTO authorities (username, authority) values ('user', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/keystore/baeldung.p12 b/spring-security-modules/spring-security-mvc-boot/src/main/resources/keystore/baeldung.p12 deleted file mode 100644 index cd8eb284297009e987aa1a1d6b53c48af587776e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2603 zcmY+EXEYlM8^;r3M9o+w1hFbbqGHbuyEIm+snTk!hO1FpR7GP|aZ6j;auK8UtQAG7 zV$YhT2qmc9Vcsg&`=0l`_uLQ9dCvL$|IhRBhaz(+vH)38WbiCI7!hqAy~_jS08+@{ zK@b_-cZ|DGWH#S_MQko0G8^s~V~@v<{lx#SxVeBV6f)>1iVWICDY0|?A0I!5f`s^3 zu&dJJ6F~Z?bJm7OhKe^z>^=)CfQ|u?L7h6GkAgI65DwJB{KM&_MXKTI9lIqxhN`1} z`A*KRClYJWaEY_s^N|voc6A00ThR7qHjQvZX+gn$-BvCy^h*XXd@(9FFl&uIA(ye3~t$x%OvdtZ6kea z?f2mYKd}#kcfPd2Qj@BWsJYAQV?UWEV$3xr?2MMkh<@aOLyI5fS+HWE`b(`(J^ht} zkR*eWyqT*v5%MaZOvmUzs+mdtjCG$7e zk&q|W%V|!jeWjxuJY*Pp@C-pN0z$3MU$4}90$#HPd)>y0K?<6Y7T0Chq0uke7wbomuc|C+P#-z{m`4c1|1GBI(woGP!Qhl7t_2@B=gTCU}klA|2uD~LA$B|Hf z9?q|vYv$T8RN`JF0)WU?;jGXd*@?42n)lJLP?O%qsJ(!~)+G!#4|R;Q2h*6mO8XIX z_P~j+liPKyQLV85WsE0HQ+2F7!T=w$#*rGM@2eK}v3Xvw^kEK*b_!6)K@Oy{^#nzK zYsydd{?(y@;X^STEU`R(o3B3DQ=gQ{TalEFacTQ$WwZ_3$NLf1A`ue15ske5Gbvrn zMVwpM5 z$^;r{*cZwNsXDeph+W0HFoH3@>rvgs;VhhQP@SeG3Lch{p&iNZS<9O-`k>9`V^$Bvi__Z&f2RwKK4svAZO_QzY-Q+9boQ0)of~0dFq|de&s}-DZ zouW8d&sajPQE^wEim{+NZ&76^e#4I@Eafg)-eAhQByD>`a|b0n*iCC6(-a?G59!K! z%WNH4FA|B~`8ZHpAgsSh=iwt@gM6V;X^Lic=Ze*TrTDT{_smO{wb$xT3!aB9Ix$ zDHJb#IrUW=`ki_aY+ttWxkRR7JPdppxA8pLHc788pN$m`*!udm1)o>{gp13CMePDg z>Tgwoh14K0et;X`2EZNQ1Hc0U0lxt}Q8ND&gw=#V5C?BxcWE^ZbsbGD4K!Lq9j$XL zP=~)u9PGzVH91CSS%84!rTb3;{Fi0f|6^H4*Oa*e3xdCLeiF;!_o?hv z0tk<&E}^>5tfsiw#0xZ84jjfMZW)O9@|xuvB=#S%RSw(YvpJl=fCsPWzeWCMix(mA7RsU@{fe{o=Xy>Pp*}`%+i`nlk|N9x!FxG2)|X4 zEKw@1^=34F&2qQi9j@PN8d^HCdnwkH+SwDtAaoOs>MrPVqq+6GsLWG{iP!raR{296 zn)bo1Ypxj{s&Zq3PJ)r!`Io^PGnnr+kk7{UX+IJgRt#f%T8fU$?%w|Vop*RwEGqa{ z(WG3c0FW|}N4&}s$|j#RGGV2oSE>W{OZ@E-b47trP;YC$ z=vPW$1m1o3sc292)J35Y(%$!P4;0VKD5xumEa}b>FU(NpzSChk7S=$(X973=-bj9{y};Q81=IyKM8_P=YATS4wxXidLc;YHIX!VEoy)KSNh5GdGhbD-AIfz3o9_1@)sB) B#c}`u diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/logback.xml b/spring-security-modules/spring-security-mvc-boot/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/persistence-h2.properties b/spring-security-modules/spring-security-mvc-boot/src/main/resources/persistence-h2.properties deleted file mode 100644 index a4b2af6361..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/persistence-h2.properties +++ /dev/null @@ -1,8 +0,0 @@ -driverClassName=org.h2.Driver -url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1 -username=sa -password= - -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=false -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-mysql.sql b/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-mysql.sql deleted file mode 100644 index bb38c74366..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-mysql.sql +++ /dev/null @@ -1,18 +0,0 @@ -DROP TABLE IF EXISTS authorities; -DROP TABLE IF EXISTS bael_users; - -CREATE TABLE bael_users ( - name VARCHAR(50) NOT NULL, - email VARCHAR(50) NOT NULL, - password VARCHAR(100) NOT NULL, - enabled TINYINT NOT NULL DEFAULT 1, - PRIMARY KEY (email) -); - -CREATE TABLE authorities ( - email VARCHAR(50) NOT NULL, - authority VARCHAR(50) NOT NULL, - FOREIGN KEY (email) REFERENCES bael_users(email) -); - -CREATE UNIQUE INDEX ix_auth_email on authorities (email,authority); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-postgre.sql b/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-postgre.sql deleted file mode 100644 index d78edfb528..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/schema-postgre.sql +++ /dev/null @@ -1,16 +0,0 @@ -DROP TABLE IF EXISTS authorities; -DROP TABLE IF EXISTS users; - -CREATE TABLE users ( - username varchar(50) NOT NULL PRIMARY KEY, - password varchar(100) NOT NULL, - enabled boolean not null DEFAULT true -); - -CREATE TABLE authorities ( - username varchar(50) NOT NULL, - authority varchar(50) NOT NULL, - CONSTRAINT foreign_authorities_users_1 foreign key(username) references users(username) -); - -CREATE UNIQUE INDEX ix_auth_username on authorities (username,authority); \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml b/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml deleted file mode 100644 index 0b334a3694..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml b/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml deleted file mode 100644 index 31796ad134..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml b/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml deleted file mode 100644 index 4cfa6bbf26..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml b/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml deleted file mode 100644 index c026700810..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/403.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/403.html deleted file mode 100644 index 20550768cf..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/403.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - -You do not have permission to view this page. - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/adminPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/adminPage.html deleted file mode 100644 index 13aff9b15a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/adminPage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -Insert title here - - -Welcome admin! Logout - -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/index.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/index.html deleted file mode 100644 index 8e7394ad6a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - -Spring Security Thymeleaf - - - - - -
- Welcome -
- - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/login.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/login.html deleted file mode 100644 index dd6bd04767..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/login.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - -

Login

- -
- - - - - - - - - - - - - - -
User:
Password:
- -
- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html deleted file mode 100644 index 43d0e73233..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - -Insert title here - - - -

Admin login page

-
- - - - - - - - - - - - - -
User:
Password:
- -
- -

Login failed!

- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginUser.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginUser.html deleted file mode 100644 index bf4ddd48bc..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/loginUser.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - -Login - - - -

User login page

- -
- - - - - - - - - - - - -
User:
Password:
- -
-

Login failed!

- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html deleted file mode 100644 index 2119baec66..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - -

Login

- -
- - - - - - - - - - - - - - -
Username:
Password:
- -
- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html deleted file mode 100644 index a5b2eaf3dc..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - -

Login

-

Warning! You are about to access sensible data!

- -
- - - - - - - - - - - - - - -
Username:
Password:
- -
- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html deleted file mode 100644 index 676badb16f..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - -Multiple Http Elements Links - - - -Admin page -
-User page -
-Private user page -
-Guest page - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html deleted file mode 100644 index 3003833562..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -Admin Page - - -Welcome admin! - -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html deleted file mode 100644 index 47a4c9c44a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -Guest Page - - -Welcome guest! - -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html deleted file mode 100644 index 52045ec320..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -Insert title here - - -Welcome user to your private page! Logout - -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html deleted file mode 100644 index f6c2def0b8..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -User Page - - -Welcome user! Logout - -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/private.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/private.html deleted file mode 100644 index 035d84bbbd..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/private.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - Private - - -

Congrats!

- - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html deleted file mode 100644 index 1877464fe5..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - -Insert title here - - - -User page -
-Admin page - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html deleted file mode 100644 index a302721570..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Role vs Granted Authority Example - - - - - - - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html deleted file mode 100644 index eacde18459..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - -Login - - - - - - -
-
-

Login

-

- -
- - - - -

- - - -

- - -
-
-
- - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html deleted file mode 100644 index c62a111ebc..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - -Protected By Authority - - - -
-

Protected By Authority

-
- - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html deleted file mode 100644 index a6cd0666db..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - -Protected By Nothing - - - -
-

Protected By Nothing

-
- - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html deleted file mode 100644 index f4bac55b55..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - -Protected By Role - - - -
-

Protected By Role

-
- - - - diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html deleted file mode 100644 index 93b3577f5c..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html +++ /dev/null @@ -1 +0,0 @@ -

Welcome to Secured Site

\ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/userPage.html b/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/userPage.html deleted file mode 100644 index 894a225871..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/main/resources/templates/userPage.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - -Insert title here - - -Welcome user! Logout -

-Back to links - - \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java deleted file mode 100644 index b2def82c51..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.baeldung.relationships; - -import com.baeldung.AppConfig; -import com.baeldung.data.repositories.TweetRepository; -import com.baeldung.data.repositories.UserRepository; -import com.baeldung.models.AppUser; -import com.baeldung.models.Tweet; -import com.baeldung.security.AppUserPrincipal; -import com.baeldung.util.DummyContentUtil; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.jdbc.JdbcTestUtils; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; - -import javax.servlet.ServletContext; -import java.util.Date; -import java.util.List; - -import static org.springframework.util.Assert.isTrue; - -@RunWith(SpringRunner.class) -@WebAppConfiguration -@ContextConfiguration -@DirtiesContext -public class SpringDataWithSecurityIntegrationTest { - AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); - @Autowired - private ServletContext servletContext; - private static UserRepository userRepository; - private static TweetRepository tweetRepository; - - @Before - public void testInit() { - ctx.register(AppConfig.class); - ctx.setServletContext(servletContext); - ctx.refresh(); - userRepository = ctx.getBean(UserRepository.class); - tweetRepository = ctx.getBean(TweetRepository.class); - List appUsers = (List) userRepository.saveAll(DummyContentUtil.generateDummyUsers()); - tweetRepository.saveAll(DummyContentUtil.generateDummyTweets(appUsers)); - } - - /** - * This is to ensure the tables are dropped in proper order. - * After the Spring Boot 2.2.2 upgrade, DDL statements generated automatically try to drop Tweet table first. - * As a result we get org.h2.jdbc.JdbcSQLSyntaxErrorException because Tweet_Likes table depends on Tweet. - * - * @see - * StackOverflow#59364212 - * - * @see - * StackOverflow#59561551 - * - */ - @After - public void tearDown() { - JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class); - JdbcTestUtils.dropTables(jdbcTemplate, "Tweet_Likes", "Tweet"); - } - - @Test - public void givenAppUser_whenLoginSuccessful_shouldUpdateLastLogin() { - AppUser appUser = userRepository.findByUsername("lionel@messi.com"); - Authentication auth = new UsernamePasswordAuthenticationToken(new AppUserPrincipal(appUser), null, DummyContentUtil.getAuthorities()); - SecurityContextHolder.getContext() - .setAuthentication(auth); - userRepository.updateLastLogin(new Date()); - } - - @Test(expected = InvalidDataAccessApiUsageException.class) - public void givenNoAppUserInSecurityContext_whenUpdateLastLoginAttempted_shouldFail() { - userRepository.updateLastLogin(new Date()); - } - - @Test - public void givenAppUser_whenLoginSuccessful_shouldReadMyPagedTweets() { - AppUser appUser = userRepository.findByUsername("lionel@messi.com"); - Authentication auth = new UsernamePasswordAuthenticationToken(new AppUserPrincipal(appUser), null, DummyContentUtil.getAuthorities()); - SecurityContextHolder.getContext() - .setAuthentication(auth); - Page page = null; - do { - page = tweetRepository.getMyTweetsAndTheOnesILiked(PageRequest.of(page != null ? page.getNumber() + 1 : 0, 5)); - for (Tweet twt : page.getContent()) { - isTrue((twt.getOwner() == appUser.getUsername()) || (twt.getLikes() - .contains(appUser.getUsername())), "I do not have any Tweets"); - } - } while (page.hasNext()); - } - - @Test(expected = InvalidDataAccessApiUsageException.class) - public void givenNoAppUser_whenPaginatedResultsRetrievalAttempted_shouldFail() { - Page page = null; - do { - page = tweetRepository.getMyTweetsAndTheOnesILiked(PageRequest.of(page != null ? page.getNumber() + 1 : 0, 5)); - } while (page != null && page.hasNext()); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 2041249b71..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.custom.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java deleted file mode 100644 index 7aa26ff031..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.baeldung.jdbcauthentication.h2; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = H2JdbcAuthenticationApplication.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java deleted file mode 100644 index 638e9d7919..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.jdbcauthentication.h2.web; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; - -import io.restassured.authentication.FormAuthConfig; -import io.restassured.filter.session.SessionFilter; - -/** - * This Live Test requires the H2JdbcAuthenticationApplication application to be up and running - */ -public class UserControllerLiveTest { - - private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; - - @Test - public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { - SessionFilter filter = new SessionFilter(); - given().auth() - .form("user", "pass", new FormAuthConfig("/login", "username", "password").withCsrfFieldName("_csrf")) - .and() - .filter(filter) - .when() - .get(PRINCIPAL_SVC_URL) - .then() - .statusCode(HttpStatus.OK.value()) - .and() - .body("authorities[0].authority", is("ROLE_USER")) - .body("principal.username", is("user")) - .body("name", is("user")); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java deleted file mode 100644 index 261063cbb6..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.jdbcauthentication.mysql.web; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; - -/** - * This Live Test requires: - * * a MySql instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication - * (e.g. with the following command `docker run -p 3306:3306 --name bael-mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=jdbc_authentication mysql:latest`) - * * the service up and running - * - */ -public class UserControllerLiveTest { - - private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; - - @Test - public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { - given().auth() - .preemptive() - .basic("user@email.com", "pass") - .when() - .get(PRINCIPAL_SVC_URL) - .then() - .statusCode(HttpStatus.OK.value()) - .and() - .body("authorities[0].authority", is("ROLE_USER")) - .body("principal.username", is("user@email.com")) - .body("name", is("user@email.com")); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java deleted file mode 100644 index 82bf6df8db..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.jdbcauthentication.postgre.web; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; - -/** - * This Live Test requires: - * * a PostgreSQL instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication - * (e.g. with the following command `docker run -p 5432:5432 --name bael-postgre -e POSTGRES_PASSWORD=pass -e POSTGRES_DB=jdbc_authentication postgres:latest`) - * * the service up and running - * - */ -public class UserControllerLiveTest { - - private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; - - @Test - public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { - given().auth() - .preemptive() - .basic("user", "pass") - .when() - .get(PRINCIPAL_SVC_URL) - .then() - .statusCode(HttpStatus.OK.value()) - .and() - .body("authorities[0].authority", is("ROLE_USER")) - .body("principal.username", is("user")) - .body("name", is("user")); - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java deleted file mode 100644 index dfcfcad609..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.baeldung.web; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.baeldung.custom.persistence.model.Foo; - -import io.restassured.RestAssured; -import io.restassured.authentication.FormAuthConfig; -import io.restassured.response.Response; -import io.restassured.specification.RequestSpecification; - -import org.junit.Test; -import org.springframework.http.MediaType; - - -public class ApplicationLiveTest { - - @Test - public void givenUserWithReadPrivilegeAndHasPermission_whenGetFooById_thenOK() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/foos/1"); - assertEquals(200, response.getStatusCode()); - assertTrue(response.asString().contains("id")); - } - - @Test - public void givenUserWithNoWritePrivilegeAndHasPermission_whenPostFoo_thenForbidden() { - final Response response = givenAuth("john", "123").contentType(MediaType.APPLICATION_JSON_VALUE).body(new Foo("sample")).post("http://localhost:8082/foos"); - assertEquals(403, response.getStatusCode()); - } - - @Test - public void givenUserWithWritePrivilegeAndHasPermission_whenPostFoo_thenOk() { - final Response response = givenAuth("tom", "111").and().body(new Foo("sample")).and().contentType(MediaType.APPLICATION_JSON_VALUE).post("http://localhost:8082/foos"); - assertEquals(201, response.getStatusCode()); - assertTrue(response.asString().contains("id")); - } - - // - - @Test - public void givenUserMemberInOrganization_whenGetOrganization_thenOK() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/1"); - assertEquals(200, response.getStatusCode()); - assertTrue(response.asString().contains("id")); - } - - @Test - public void givenUserMemberNotInOrganization_whenGetOrganization_thenForbidden() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/2"); - assertEquals(403, response.getStatusCode()); - } - - // - - @Test - public void givenDisabledSecurityExpression_whenGetFooByName_thenError() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/foos?name=sample"); - assertEquals(500, response.getStatusCode()); - assertTrue(response.asString().contains("method hasAuthority() not allowed")); - } - - // - private RequestSpecification givenAuth(String username, String password) { - return RestAssured.given().log().uri().auth().form(username, password, new FormAuthConfig("/login","username","password")); - } -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java deleted file mode 100644 index d16acc729a..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.baeldung.web; - -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.apache.http.HttpHeaders; -import org.baeldung.custom.Application; -import org.baeldung.custom.persistence.model.Foo; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithAnonymousUser; -import org.springframework.security.test.context.support.WithUserDetails; -import org.springframework.test.web.servlet.MockMvc; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@SpringBootTest(classes = { Application.class }) -@AutoConfigureMockMvc -public class CustomUserDetailsServiceIntegrationTest { - - @Autowired - private MockMvc mvc; - - @Test - @WithUserDetails("john") - public void givenUserWithReadPermissions_whenRequestUserInfo_thenRetrieveUserData() throws Exception { - this.mvc.perform(get("/user").with(csrf())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.user.privileges[0].name").value("FOO_READ_PRIVILEGE")) - .andExpect(jsonPath("$.user.organization.name").value("FirstOrg")) - .andExpect(jsonPath("$.user.username").value("john")); - } - - @Test - @WithUserDetails("tom") - public void givenUserWithWritePermissions_whenRequestUserInfo_thenRetrieveUserData() throws Exception { - this.mvc.perform(get("/user").with(csrf())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.user.privileges").isArray()) - .andExpect(jsonPath("$.user.organization.name").value("SecondOrg")) - .andExpect(jsonPath("$.user.username").value("tom")); - } - - @Test - @WithUserDetails("john") - public void givenUserWithReadPermissions_whenRequestFoo_thenRetrieveSampleFoo() throws Exception { - this.mvc.perform(get("/foos/1").with(csrf())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name").value("Sample")); - } - - @Test - @WithAnonymousUser - public void givenAnonymous_whenRequestFoo_thenRetrieveUnauthorized() throws Exception { - this.mvc.perform(get("/foos/1").with(csrf())) - .andExpect(status().isUnauthorized()); - } - - @Test - @WithUserDetails("john") - public void givenUserWithReadPermissions_whenCreateNewFoo_thenForbiddenStatusRetrieved() throws Exception { - this.mvc.perform(post("/foos").with(csrf()) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .content(asJsonString(new Foo()))) - .andExpect(status().isForbidden()); - } - - @Test - @WithUserDetails("tom") - public void givenUserWithWritePermissions_whenCreateNewFoo_thenOkStatusRetrieved() throws Exception { - this.mvc.perform(post("/foos").with(csrf()) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .content(asJsonString(new Foo()))) - .andExpect(status().isCreated()); - } - - private static String asJsonString(final Object obj) throws Exception { - final ObjectMapper mapper = new ObjectMapper(); - final String jsonContent = mapper.writeValueAsString(obj); - return jsonContent; - } - -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java deleted file mode 100644 index fe7883ec94..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.baeldung.web; - -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.SSLContextBuilder; -import org.baeldung.ssl.HttpsEnabledApplication; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestTemplate; - -import javax.net.ssl.SSLContext; -import java.util.Collections; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = HttpsEnabledApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) -@ActiveProfiles("ssl") -public class HttpsApplicationIntegrationTest { - - private static final String WELCOME_URL = "https://localhost:8443/welcome"; - - @Value("${trust.store}") - private Resource trustStore; - - @Value("${trust.store.password}") - private String trustStorePassword; - - @Test - public void whenGETanHTTPSResource_thenCorrectResponse() throws Exception { - ResponseEntity response = restTemplate().getForEntity(WELCOME_URL, String.class, Collections.emptyMap()); - - assertEquals("

Welcome to Secured Site

", response.getBody()); - assertEquals(HttpStatus.OK, response.getStatusCode()); - } - - RestTemplate restTemplate() throws Exception { - SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray()) - .build(); - SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext); - HttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(socketFactory) - .build(); - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); - return new RestTemplate(factory); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java deleted file mode 100644 index e12e2f87b0..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.baeldung.web; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import io.restassured.RestAssured; -import io.restassured.response.Response; - -import org.junit.Test; - - -public class IpLiveTest { - - @Test - public void givenUser_whenGetHomePage_thenOK() { - final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/"); - assertEquals(200, response.getStatusCode()); - assertTrue(response.asString().contains("Welcome")); - } - - @Test - public void givenUserWithWrongIP_whenGetFooById_thenForbidden() { - final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/foos/1"); - assertEquals(403, response.getStatusCode()); - assertTrue(response.asString().contains("Forbidden")); - } - -} \ No newline at end of file diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java deleted file mode 100644 index 9ef09f1f67..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.baeldung.web; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Collections; - -import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class) -public class MultipleAuthProvidersApplicationIntegrationTest { - @Autowired - private TestRestTemplate restTemplate; - - @Test - public void givenMemUsers_whenGetPingWithValidUser_thenOk() { - ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); - - assertThat(result.getStatusCodeValue()).isEqualTo(200); - assertThat(result.getBody()).isEqualTo("OK"); - } - - @Test - public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { - ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); - - assertThat(result.getStatusCodeValue()).isEqualTo(200); - assertThat(result.getBody()).isEqualTo("OK"); - } - - @Test - public void givenAuthProviders_whenGetPingWithNoCred_then401() { - ResponseEntity result = makeRestCallToGetPing(); - - assertThat(result.getStatusCodeValue()).isEqualTo(401); - } - - @Test - public void givenAuthProviders_whenGetPingWithBadCred_then401() { - ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); - - assertThat(result.getStatusCodeValue()).isEqualTo(401); - } - - private ResponseEntity makeRestCallToGetPing(String username, String password) { - return restTemplate.withBasicAuth(username, password) - .getForEntity("/api/ping", String.class, Collections.emptyMap()); - } - - private ResponseEntity makeRestCallToGetPing() { - return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap()); - } -} diff --git a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java b/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java deleted file mode 100644 index 157480c3f1..0000000000 --- a/spring-security-modules/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.baeldung.web; - -import org.baeldung.multipleentrypoints.MultipleEntryPointsApplication; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; - -@RunWith(SpringRunner.class) -@WebAppConfiguration -@SpringBootTest(classes = MultipleEntryPointsApplication.class) -public class MultipleEntryPointsIntegrationTest { - - @Autowired - private WebApplicationContext wac; - - @Autowired - private FilterChainProxy springSecurityFilterChain; - - private MockMvc mockMvc; - - @Before - public void setup() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(springSecurityFilterChain).build(); - } - - @Test - public void whenTestAdminCredentials_thenOk() throws Exception { - mockMvc.perform(get("/admin/myAdminPage")).andExpect(status().isUnauthorized()); - - mockMvc.perform(get("/admin/myAdminPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk()); - - mockMvc.perform(get("/user/myUserPage").with(user("admin").password("adminPass").roles("ADMIN"))).andExpect(status().isForbidden()); - - } - - @Test - public void whenTestUserCredentials_thenOk() throws Exception { - mockMvc.perform(get("/user/general/myUserPage")).andExpect(status().isFound()); - - mockMvc.perform(get("/user/general/myUserPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk()); - - mockMvc.perform(get("/admin/myAdminPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isForbidden()); - } - - @Test - public void givenAnyUser_whenGetGuestPage_thenOk() throws Exception { - mockMvc.perform(get("/guest/myGuestPage")).andExpect(status().isOk()); - - mockMvc.perform(get("/guest/myGuestPage").with(user("user").password("userPass").roles("USER"))).andExpect(status().isOk()); - - mockMvc.perform(get("/guest/myGuestPage").with(httpBasic("admin", "adminPass"))).andExpect(status().isOk()); - } -} From 674a98e5282465de7e175cdb5c0273e5d8ad0c25 Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Tue, 18 Feb 2020 11:13:39 +0200 Subject: [PATCH 28/62] aspectJ dependencies set to 1.9.2 --- jcabi/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jcabi/pom.xml b/jcabi/pom.xml index bf53f74bcd..eb5d2dc4cf 100644 --- a/jcabi/pom.xml +++ b/jcabi/pom.xml @@ -65,10 +65,10 @@ 0.22.6 - 1.9.5 + 1.9.2 0.14.1 - 1.9.1 - 1.9.1 + 1.9.2 + 1.9.2 From 093ace0a278fbf4d57f25d37d8eab176ae943450 Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Tue, 18 Feb 2020 15:32:00 +0200 Subject: [PATCH 29/62] Code moved to libraries-3 module --- jcabi/pom.xml | 74 ------------------- libraries-3/pom.xml | 48 ++++++++++++ .../java/com/baeldung/jcabi/JcabiAspectJ.java | 0 pom.xml | 2 - 4 files changed, 48 insertions(+), 76 deletions(-) delete mode 100644 jcabi/pom.xml rename {jcabi => libraries-3}/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java (100%) diff --git a/jcabi/pom.xml b/jcabi/pom.xml deleted file mode 100644 index eb5d2dc4cf..0000000000 --- a/jcabi/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - 4.0.0 - jcabi - 0.1.0-SNAPSHOT - jcabi - jar - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - - com.jcabi - jcabi-aspects - ${jcabi-aspects.version} - - - - org.aspectj - aspectjrt - ${aspectjrt.version} - runtime - - - - - - jcabi - - - com.jcabi - jcabi-maven-plugin - ${jcabi-maven-plugin.version} - - - - ajc - - - - - - org.aspectj - aspectjtools - ${aspectjtools.version} - - - org.aspectj - aspectjweaver - ${aspectjweaver.version} - - - - - - - - 0.22.6 - 1.9.2 - 0.14.1 - 1.9.2 - 1.9.2 - - - diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 1dbe6b2435..b1795ab7e0 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -74,6 +74,18 @@ ${cache2k.version} pom + + + com.jcabi + jcabi-aspects + ${jcabi-aspects.version} + + + org.aspectj + aspectjrt + ${aspectjrt.version} + runtime + @@ -82,6 +94,36 @@ https://jitpack.io + + + libraries-3 + + + com.jcabi + jcabi-maven-plugin + ${jcabi-maven-plugin.version} + + + + ajc + + + + + + org.aspectj + aspectjtools + ${aspectjtools.version} + + + org.aspectj + aspectjweaver + ${aspectjweaver.version} + + + + + 1.78 @@ -94,5 +136,11 @@ 0.43 2.7.2 1.2.3.Final + + 0.22.6 + 1.9.2 + 0.14.1 + 1.9.2 + 1.9.2 diff --git a/jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java b/libraries-3/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java similarity index 100% rename from jcabi/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java rename to libraries-3/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java diff --git a/pom.xml b/pom.xml index 19f435f1b8..6e6316edd6 100644 --- a/pom.xml +++ b/pom.xml @@ -472,7 +472,6 @@ javax-servlets javaxval jaxb - jcabi jee-7 jee-7-security jee-kotlin @@ -983,7 +982,6 @@ javax-servlets javaxval jaxb - jcabi jee-7 jee-7-security jee-kotlin From a0d37ea022ca8e57a5fd09e620bd5669ece0c819 Mon Sep 17 00:00:00 2001 From: mikr Date: Tue, 18 Feb 2020 15:38:19 +0100 Subject: [PATCH 30/62] Java-633 Standardize packages in spring-mvc-* --- lombok-custom/pom.xml | 28 +++++++++++++++---- spring-mvc-basics-3/pom.xml | 2 +- .../java/com/baeldung/boot/Application.java | 2 +- .../com/baeldung/boot/config/WebConfig.java | 12 ++++---- .../controller/GenericEntityController.java | 8 +++--- .../converter/GenericBigDecimalConverter.java | 2 +- ...tringToAbstractEntityConverterFactory.java | 8 +++--- .../converter/StringToEmployeeConverter.java | 4 +-- .../boot/converter/StringToEnumConverter.java | 4 +-- .../StringToLocalDateTimeConverter.java | 2 +- .../controller/AbstractEntityController.java | 8 +++--- .../StringToEmployeeConverterController.java | 4 +-- .../baeldung/boot/domain/AbstractEntity.java | 2 +- .../java/com/baeldung/boot/domain/Bar.java | 2 +- .../com/baeldung/boot/domain/Employee.java | 2 +- .../java/com/baeldung/boot/domain/Foo.java | 2 +- .../baeldung/boot/domain/GenericEntity.java | 2 +- .../java/com/baeldung/boot/domain/Modes.java | 2 +- .../repository/GenericEntityRepository.java | 4 +-- .../HeaderVersionArgumentResolver.java | 2 +- .../baeldung/boot/web/resolver/Version.java | 2 +- .../CachedBodyHttpServletRequest.java | 2 +- .../CachedBodyServletInputStream.java | 2 +- .../cachedrequest/ContentCachingFilter.java | 2 +- .../cachedrequest/HttpRequestDemoConfig.java | 6 ++-- .../com/baeldung/cachedrequest/Person.java | 2 +- .../cachedrequest/PersonController.java | 2 +- .../PrintRequestContentFilter.java | 2 +- .../SpringBootApplicationIntegrationTest.java | 4 +-- .../SpringBootJPAIntegrationTest.java | 6 ++-- .../SpringBootMailIntegrationTest.java | 2 +- .../CachedBodyHttpServletRequestUnitTest.java | 2 +- .../CachedBodyServletInputStreamUnitTest.java | 2 +- .../ContentCachingFilterUnitTest.java | 2 +- .../PersonControllerIntegrationTest.java | 2 +- .../PrintRequestContentFilterUnitTest.java | 2 +- .../config/StudentControllerConfig.java | 2 +- .../baeldung/controller/config/WebConfig.java | 4 +-- .../controller/PassParametersController.java | 2 +- .../controller/RestAnnotatedController.java | 4 +-- .../controller/controller/RestController.java | 4 +-- .../controller/controller/TestController.java | 2 +- .../baeldung/controller/student/Student.java | 2 +- .../src/main/resources/test-mvc.xml | 2 +- .../src/main/webapp/WEB-INF/web-old.xml | 2 +- .../ControllerAnnotationIntegrationTest.java | 6 ++-- .../controller/ControllerIntegrationTest.java | 4 +-- ...ssParametersControllerIntegrationTest.java | 4 +-- ...rticleViewerControllerIntegrationTest.java | 2 +- ...ollerWithOptionalParamIntegrationTest.java | 2 +- ...rWithRequiredAttributeIntegrationTest.java | 2 +- ...icleViewerWithMapParamIntegrationTest.java | 2 +- ...WithTwoSeparateMethodsIntegrationTest.java | 2 +- .../src/test/resources/test-mvc.xml | 2 +- .../java/org/baeldung/SpringContextTest.java | 2 +- .../listbindingexample/SpringContextTest.java | 2 +- .../sessionattrs/SpringContextTest.java | 2 +- .../java/org/baeldung/SpringContextTest.java | 2 +- .../org/baeldung/servlet/WebInitializer.java | 6 ++-- .../org/baeldung/spring/WebFlowConfig.java | 2 +- .../org/baeldung/spring/WebMvcConfig.java | 2 +- .../java/org/baeldung/SpringContextTest.java | 6 ++-- .../java/org/baeldung/SpringContextTest.java | 2 +- 63 files changed, 119 insertions(+), 101 deletions(-) diff --git a/lombok-custom/pom.xml b/lombok-custom/pom.xml index 1455a4f6c6..75c3f9d407 100644 --- a/lombok-custom/pom.xml +++ b/lombok-custom/pom.xml @@ -36,12 +36,12 @@ - default-tools.jar + default-profile - - java.vendor - Oracle Corporation - + true + + ${java.home}/../lib/tools.jar + @@ -53,6 +53,24 @@ + + mac-profile + + false + + ${java.home}/../Classes/classes.jar + + + + + com.sun + tools + ${java.version} + system + ${java.home}/../Classes/classes.jar + + + diff --git a/spring-mvc-basics-3/pom.xml b/spring-mvc-basics-3/pom.xml index 48b1e51dd3..1dea8f9e93 100644 --- a/spring-mvc-basics-3/pom.xml +++ b/spring-mvc-basics-3/pom.xml @@ -138,7 +138,7 @@ - org.baeldung.boot.Application + com.baeldung.boot.Application 3.1.1 3.3.7-1 2.2 diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/Application.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/Application.java index c1b6558b26..cb0d0c1532 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/Application.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/Application.java @@ -1,4 +1,4 @@ -package org.baeldung.boot; +package com.baeldung.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/config/WebConfig.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/config/WebConfig.java index 6373553837..44a5e823f7 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/config/WebConfig.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/config/WebConfig.java @@ -1,12 +1,12 @@ -package org.baeldung.boot.config; +package com.baeldung.boot.config; import java.util.List; -import org.baeldung.boot.converter.GenericBigDecimalConverter; -import org.baeldung.boot.converter.StringToAbstractEntityConverterFactory; -import org.baeldung.boot.converter.StringToEmployeeConverter; -import org.baeldung.boot.converter.StringToEnumConverter; -import org.baeldung.boot.web.resolver.HeaderVersionArgumentResolver; +import com.baeldung.boot.converter.GenericBigDecimalConverter; +import com.baeldung.boot.converter.StringToAbstractEntityConverterFactory; +import com.baeldung.boot.converter.StringToEmployeeConverter; +import com.baeldung.boot.converter.StringToEnumConverter; +import com.baeldung.boot.web.resolver.HeaderVersionArgumentResolver; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.method.support.HandlerMethodArgumentResolver; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/controller/GenericEntityController.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/controller/GenericEntityController.java index 17457f4c20..39fd5af318 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/controller/GenericEntityController.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/controller/GenericEntityController.java @@ -1,8 +1,8 @@ -package org.baeldung.boot.controller; +package com.baeldung.boot.controller; -import org.baeldung.boot.domain.GenericEntity; -import org.baeldung.boot.domain.Modes; -import org.baeldung.boot.web.resolver.Version; +import com.baeldung.boot.domain.GenericEntity; +import com.baeldung.boot.domain.Modes; +import com.baeldung.boot.web.resolver.Version; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java index f756a25f67..0040327e00 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.converter; +package com.baeldung.boot.converter; import com.google.common.collect.ImmutableSet; import org.springframework.core.convert.TypeDescriptor; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToAbstractEntityConverterFactory.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToAbstractEntityConverterFactory.java index 9e7fd8f858..bfeb03f748 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToAbstractEntityConverterFactory.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToAbstractEntityConverterFactory.java @@ -1,8 +1,8 @@ -package org.baeldung.boot.converter; +package com.baeldung.boot.converter; -import org.baeldung.boot.domain.AbstractEntity; -import org.baeldung.boot.domain.Bar; -import org.baeldung.boot.domain.Foo; +import com.baeldung.boot.domain.AbstractEntity; +import com.baeldung.boot.domain.Bar; +import com.baeldung.boot.domain.Foo; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java index e00d0ad312..678ae49195 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.converter; +package com.baeldung.boot.converter; -import org.baeldung.boot.domain.Employee; +import com.baeldung.boot.domain.Employee; import org.springframework.core.convert.converter.Converter; public class StringToEmployeeConverter implements Converter { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEnumConverter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEnumConverter.java index 498b44abec..320c26cba0 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEnumConverter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToEnumConverter.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.converter; +package com.baeldung.boot.converter; -import org.baeldung.boot.domain.Modes; +import com.baeldung.boot.domain.Modes; import org.springframework.core.convert.converter.Converter; public class StringToEnumConverter implements Converter { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToLocalDateTimeConverter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToLocalDateTimeConverter.java index 8a08b438f2..8d9b85f57a 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToLocalDateTimeConverter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/StringToLocalDateTimeConverter.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.converter; +package com.baeldung.boot.converter; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/AbstractEntityController.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/AbstractEntityController.java index d3c012ba31..ac5bebcdeb 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/AbstractEntityController.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/AbstractEntityController.java @@ -1,8 +1,8 @@ -package org.baeldung.boot.converter.controller; +package com.baeldung.boot.converter.controller; -import org.baeldung.boot.domain.Bar; -import org.baeldung.boot.domain.Foo; -import org.baeldung.boot.domain.Modes; +import com.baeldung.boot.domain.Bar; +import com.baeldung.boot.domain.Foo; +import com.baeldung.boot.domain.Modes; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java index 762d237156..ed118f9cdb 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.converter.controller; +package com.baeldung.boot.converter.controller; -import org.baeldung.boot.domain.Employee; +import com.baeldung.boot.domain.Employee; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/AbstractEntity.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/AbstractEntity.java index 30e0d1e5fe..08953928cb 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/AbstractEntity.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/AbstractEntity.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; public abstract class AbstractEntity { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Bar.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Bar.java index 724f5e4bca..063ed3db63 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Bar.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Bar.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; public class Bar extends AbstractEntity { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Employee.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Employee.java index 8242e53200..a96fc5d051 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Employee.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Employee.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Foo.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Foo.java index a2ff354e59..c6637f6162 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Foo.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Foo.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric; public class Foo extends AbstractEntity { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/GenericEntity.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/GenericEntity.java index f1c936e432..a2a676200a 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/GenericEntity.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/GenericEntity.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Modes.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Modes.java index dcba064e8c..7717294996 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Modes.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/domain/Modes.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.domain; +package com.baeldung.boot.domain; public enum Modes { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/repository/GenericEntityRepository.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/repository/GenericEntityRepository.java index d897e17afe..5abe7ea6b1 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/repository/GenericEntityRepository.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/repository/GenericEntityRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.repository; +package com.baeldung.boot.repository; -import org.baeldung.boot.domain.GenericEntity; +import com.baeldung.boot.domain.GenericEntity; import org.springframework.data.jpa.repository.JpaRepository; public interface GenericEntityRepository extends JpaRepository { diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java index b3a0dba7e8..de10fa5098 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.web.resolver; +package com.baeldung.boot.web.resolver; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/Version.java b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/Version.java index f69d40510e..84dabe2b47 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/Version.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/boot/web/resolver/Version.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.web.resolver; +package com.baeldung.boot.web.resolver; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequest.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequest.java index b6d4905653..89acbe79a4 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequest.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.BufferedReader; import java.io.ByteArrayInputStream; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyServletInputStream.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyServletInputStream.java index a18de30788..4d44b23ee9 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyServletInputStream.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/CachedBodyServletInputStream.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/ContentCachingFilter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/ContentCachingFilter.java index e3f3b7a060..ba3901077b 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/ContentCachingFilter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/ContentCachingFilter.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/HttpRequestDemoConfig.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/HttpRequestDemoConfig.java index 9194bcf27c..9516ff861e 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/HttpRequestDemoConfig.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/HttpRequestDemoConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -6,12 +6,12 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * To initialize the WebApplication, Please see - * {@link org.baeldung.spring.config.MainWebAppInitializer} + * {@link com.baeldung.spring.config.MainWebAppInitializer} */ @EnableWebMvc @Configuration -@ComponentScan(basePackages = "org.baeldung.cachedrequest") +@ComponentScan(basePackages = "com.baeldung.cachedrequest") public class HttpRequestDemoConfig implements WebMvcConfigurer { } \ No newline at end of file diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/Person.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/Person.java index 594b6f2360..d7ac4c66a3 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/Person.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/Person.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; public class Person { private String firstName; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PersonController.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PersonController.java index 6f241b3fb3..3c505f4754 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PersonController.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PersonController.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PrintRequestContentFilter.java b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PrintRequestContentFilter.java index 55455f590f..9c4c589a5d 100644 --- a/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PrintRequestContentFilter.java +++ b/spring-mvc-basics-3/src/main/java/com/baeldung/cachedrequest/PrintRequestContentFilter.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootApplicationIntegrationTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootApplicationIntegrationTest.java index bccca58aea..d2b4c1aff9 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootApplicationIntegrationTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootApplicationIntegrationTest.java @@ -1,7 +1,7 @@ package com.baeldung; -import org.baeldung.boot.Application; -import org.baeldung.boot.domain.Modes; +import com.baeldung.boot.Application; +import com.baeldung.boot.domain.Modes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java index c283529435..6ebc34973e 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java @@ -1,8 +1,8 @@ package com.baeldung; -import org.baeldung.boot.Application; -import org.baeldung.boot.domain.GenericEntity; -import org.baeldung.boot.repository.GenericEntityRepository; +import com.baeldung.boot.Application; +import com.baeldung.boot.domain.GenericEntity; +import com.baeldung.boot.repository.GenericEntityRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootMailIntegrationTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootMailIntegrationTest.java index 1a2a4e22d9..1349e7e9e0 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootMailIntegrationTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/SpringBootMailIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung; -import org.baeldung.boot.Application; +import com.baeldung.boot.Application; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java index 1fe9dd4c82..1ff0093b4b 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyHttpServletRequestUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.BufferedReader; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java index d7000d91ee..af025f632e 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/CachedBodyServletInputStreamUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/ContentCachingFilterUnitTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/ContentCachingFilterUnitTest.java index 057f1ac627..ec0f8948c2 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/ContentCachingFilterUnitTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/ContentCachingFilterUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.IOException; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PersonControllerIntegrationTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PersonControllerIntegrationTest.java index 046a310cc0..9212ceb886 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PersonControllerIntegrationTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PersonControllerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; diff --git a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java index ca2d5c600b..3d2acabe6b 100644 --- a/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java +++ b/spring-mvc-basics-3/src/test/java/com/baeldung/cachedrequest/PrintRequestContentFilterUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.cachedrequest; +package com.baeldung.cachedrequest; import java.io.IOException; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/StudentControllerConfig.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/StudentControllerConfig.java index 218418ecc8..b84094132d 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/StudentControllerConfig.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/StudentControllerConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.controller.config; +package com.baeldung.controller.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/WebConfig.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/WebConfig.java index 018c530f18..6e79ac0aad 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/WebConfig.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/config/WebConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.controller.config; +package com.baeldung.controller.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -11,7 +11,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc -@ComponentScan(basePackages = { "org.baeldung.controller.controller", "com.baeldung.controller", "org.baeldung.controller.config" }) +@ComponentScan(basePackages = { "com.baeldung.controller.controller", "com.baeldung.controller", "com.baeldung.controller.config" }) public class WebConfig implements WebMvcConfigurer { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/PassParametersController.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/PassParametersController.java index c282ae6a62..d8330333cb 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/PassParametersController.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/PassParametersController.java @@ -1,4 +1,4 @@ -package org.baeldung.controller.controller; +package com.baeldung.controller.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestAnnotatedController.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestAnnotatedController.java index 48981fd012..f41d45caff 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestAnnotatedController.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestAnnotatedController.java @@ -1,6 +1,6 @@ -package org.baeldung.controller.controller; +package com.baeldung.controller.controller; -import org.baeldung.controller.student.Student; +import com.baeldung.controller.student.Student; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestController.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestController.java index 4e5d1d9e17..a529faeed3 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestController.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/RestController.java @@ -1,6 +1,6 @@ -package org.baeldung.controller.controller; +package com.baeldung.controller.controller; -import org.baeldung.controller.student.Student; +import com.baeldung.controller.student.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/TestController.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/TestController.java index 12ae4e0ab1..cf275ffc0f 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/TestController.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/controller/TestController.java @@ -2,7 +2,7 @@ /** * @author Prashant Dutta */ -package org.baeldung.controller.controller; +package com.baeldung.controller.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/student/Student.java b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/student/Student.java index 5f49e5ceb9..8a82dd5553 100644 --- a/spring-mvc-basics-4/src/main/java/com/baeldung/controller/student/Student.java +++ b/spring-mvc-basics-4/src/main/java/com/baeldung/controller/student/Student.java @@ -1,4 +1,4 @@ -package org.baeldung.controller.student; +package com.baeldung.controller.student; public class Student { private String name; diff --git a/spring-mvc-basics-4/src/main/resources/test-mvc.xml b/spring-mvc-basics-4/src/main/resources/test-mvc.xml index 8013170379..44c300dfc6 100644 --- a/spring-mvc-basics-4/src/main/resources/test-mvc.xml +++ b/spring-mvc-basics-4/src/main/resources/test-mvc.xml @@ -10,7 +10,7 @@ http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> - + diff --git a/spring-mvc-basics-4/src/main/webapp/WEB-INF/web-old.xml b/spring-mvc-basics-4/src/main/webapp/WEB-INF/web-old.xml index 03322279e2..1344362d19 100644 --- a/spring-mvc-basics-4/src/main/webapp/WEB-INF/web-old.xml +++ b/spring-mvc-basics-4/src/main/webapp/WEB-INF/web-old.xml @@ -29,7 +29,7 @@ --> diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerAnnotationIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerAnnotationIntegrationTest.java index e32d9f7aca..f378357548 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerAnnotationIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerAnnotationIntegrationTest.java @@ -1,8 +1,8 @@ -package org.baeldung.controller; +package com.baeldung.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import org.baeldung.controller.config.WebConfig; -import org.baeldung.controller.student.Student; +import com.baeldung.controller.config.WebConfig; +import com.baeldung.controller.student.Student; import org.junit.Assert; import org.junit.Before; import org.junit.Test; diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerIntegrationTest.java index 8e8a021530..7e5cf1532e 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/ControllerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.controller; +package com.baeldung.controller; import org.junit.Assert; import org.junit.Before; @@ -14,7 +14,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; -import org.baeldung.controller.student.Student; +import com.baeldung.controller.student.Student; import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/PassParametersControllerIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/PassParametersControllerIntegrationTest.java index 21084f44ce..aa8148c1ef 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/controller/PassParametersControllerIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/controller/PassParametersControllerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.controller; +package com.baeldung.controller; import org.junit.Assert; import org.junit.Before; @@ -15,7 +15,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; /** - * This is the test class for {@link org.baeldung.controller.controller.PassParametersController} class. + * This is the test class for {@link com.baeldung.controller.controller.PassParametersController} class. * 09/09/2017 * * @author Ahmet Cetin diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerIntegrationTest.java index 2fb3569fc1..173ac165c3 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.baeldung.controller.config.WebConfig; +import com.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java index c7b568b68e..1fadfb7038 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.baeldung.controller.config.WebConfig; +import com.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java index 760d94af17..00d620ef9a 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.baeldung.controller.config.WebConfig; +import com.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java index fca6bba5fd..f7fff714a9 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.baeldung.controller.config.WebConfig; +import com.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration diff --git a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java index 5d2733ec92..b4e4c9ade5 100644 --- a/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java +++ b/spring-mvc-basics-4/src/test/java/com/baeldung/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.baeldung.controller.config.WebConfig; +import com.baeldung.controller.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration diff --git a/spring-mvc-basics-4/src/test/resources/test-mvc.xml b/spring-mvc-basics-4/src/test/resources/test-mvc.xml index 15f950ed4f..f1aa8e9504 100644 --- a/spring-mvc-basics-4/src/test/resources/test-mvc.xml +++ b/spring-mvc-basics-4/src/test/resources/test-mvc.xml @@ -10,7 +10,7 @@ http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> - + diff --git a/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextTest.java b/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextTest.java index e35fc8c86c..b7e09685b9 100644 --- a/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import com.baeldung.springmvcforms.configuration.ApplicationConfiguration; diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java index 751df882f9..12bb470f1b 100644 --- a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java +++ b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung.listbindingexample; +package com.baeldung.listbindingexample; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java index 0b308319b1..a00c44206a 100644 --- a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java +++ b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung.sessionattrs; +package com.baeldung.sessionattrs; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java b/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java index 22a4486aa7..a27cacba53 100644 --- a/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/servlet/WebInitializer.java b/spring-mvc-webflow/src/main/java/org/baeldung/servlet/WebInitializer.java index 2f52cad804..fc0adb558d 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/servlet/WebInitializer.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/servlet/WebInitializer.java @@ -1,9 +1,9 @@ -package org.baeldung.servlet; +package com.baeldung.servlet; import javax.servlet.ServletRegistration.Dynamic; -import org.baeldung.spring.WebFlowConfig; -import org.baeldung.spring.WebMvcConfig; +import com.baeldung.spring.WebFlowConfig; +import com.baeldung.spring.WebMvcConfig; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebFlowConfig.java b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebFlowConfig.java index 3d2de2a014..d42996bbaf 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebFlowConfig.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebFlowConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.spring; +package com.baeldung.spring; import java.util.Collections; diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java index 46bf322f1d..acaa11638d 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.spring; +package com.baeldung.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; diff --git a/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextTest.java b/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextTest.java index 122dc18bad..d58ddae6b8 100644 --- a/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextTest.java @@ -1,7 +1,7 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.WebFlowConfig; -import org.baeldung.spring.WebMvcConfig; +import com.baeldung.spring.WebFlowConfig; +import com.baeldung.spring.WebMvcConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java b/spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java index 27dcb83bd4..62e34859ee 100644 --- a/spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From caa9f15d1b3ea2fef33ab581603bd4747c0a7be0 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:11:00 +0800 Subject: [PATCH 31/62] Update README.md --- core-kotlin-modules/core-kotlin/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-kotlin-modules/core-kotlin/README.md b/core-kotlin-modules/core-kotlin/README.md index ae595bf18d..d5b57a28b4 100644 --- a/core-kotlin-modules/core-kotlin/README.md +++ b/core-kotlin-modules/core-kotlin/README.md @@ -13,4 +13,5 @@ This module contains articles about Kotlin core features. - [Implementing a Binary Tree in Kotlin](https://www.baeldung.com/kotlin-binary-tree) - [JUnit 5 for Kotlin Developers](https://www.baeldung.com/junit-5-kotlin) - [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class) +- [Fuel HTTP Library with Kotlin](https://www.baeldung.com/kotlin-fuel) - [[More --> ]](/core-kotlin-modules/core-kotlin-2) From da97440b5bd6b1f0a09520ad24e6e5b020bada96 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:12:51 +0800 Subject: [PATCH 32/62] Update README.md --- core-kotlin-modules/core-kotlin/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-kotlin-modules/core-kotlin/README.md b/core-kotlin-modules/core-kotlin/README.md index d5b57a28b4..9d90fad340 100644 --- a/core-kotlin-modules/core-kotlin/README.md +++ b/core-kotlin-modules/core-kotlin/README.md @@ -14,4 +14,5 @@ This module contains articles about Kotlin core features. - [JUnit 5 for Kotlin Developers](https://www.baeldung.com/junit-5-kotlin) - [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class) - [Fuel HTTP Library with Kotlin](https://www.baeldung.com/kotlin-fuel) +- [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant) - [[More --> ]](/core-kotlin-modules/core-kotlin-2) From 5b3522b7180d5593be606b8644ecacadb8bf6c3f Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:14:43 +0800 Subject: [PATCH 33/62] Update README.md --- core-kotlin-modules/core-kotlin/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-kotlin-modules/core-kotlin/README.md b/core-kotlin-modules/core-kotlin/README.md index 9d90fad340..90caccf5c8 100644 --- a/core-kotlin-modules/core-kotlin/README.md +++ b/core-kotlin-modules/core-kotlin/README.md @@ -15,4 +15,5 @@ This module contains articles about Kotlin core features. - [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class) - [Fuel HTTP Library with Kotlin](https://www.baeldung.com/kotlin-fuel) - [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant) +- [Dependency Injection for Kotlin with Injekt](https://www.baeldung.com/kotlin-dependency-injection-with-injekt) - [[More --> ]](/core-kotlin-modules/core-kotlin-2) From d7686b199c5b1111cf11c720da9636bd33c8527b Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:21:05 +0800 Subject: [PATCH 34/62] Update README.md --- core-kotlin-modules/core-kotlin-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-kotlin-modules/core-kotlin-2/README.md b/core-kotlin-modules/core-kotlin-2/README.md index 3e607eb61b..d6d6b2f706 100644 --- a/core-kotlin-modules/core-kotlin-2/README.md +++ b/core-kotlin-modules/core-kotlin-2/README.md @@ -5,4 +5,5 @@ This module contains articles about Kotlin core features. ### Relevant articles: - [Working with Dates in Kotlin](https://www.baeldung.com/kotlin-dates) - [Kotlin Ternary Conditional Operator](https://www.baeldung.com/kotlin-ternary-operator) +- [Sequences in Kotlin](https://www.baeldung.com/kotlin/sequences) - [[<-- Prev]](/core-kotlin-modules/core-kotlin) From b30112554ace7f98eafde9698f0b8e6ca6e0cb36 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:33:53 +0800 Subject: [PATCH 35/62] Update README.md --- core-java-modules/core-java/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java/README.md b/core-java-modules/core-java/README.md index 80a48226e6..033d8032bf 100644 --- a/core-java-modules/core-java/README.md +++ b/core-java-modules/core-java/README.md @@ -11,7 +11,7 @@ - [Introduction to Java Serialization](http://www.baeldung.com/java-serialization) - [Guide to UUID in Java](http://www.baeldung.com/java-uuid) - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) -- [Quick Guide to Java Stack](http://www.baeldung.com/java-stack) +- [Quick Guide to the Java Stack](http://www.baeldung.com/java-stack) - [Compiling Java *.class Files with javac](http://www.baeldung.com/javac) - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [Guide to the Externalizable Interface in Java](http://www.baeldung.com/java-externalizable) From a73581fbafe4d95b188080bb975e8842edf97bae Mon Sep 17 00:00:00 2001 From: Kamlesh Kumar Date: Fri, 21 Feb 2020 09:16:22 +0530 Subject: [PATCH 36/62] BAEL-3459 updated cache2k example and test cases (#8732) --- .../com/baeldung/cache2k/ProductHelper.java | 23 ++++++++----------- .../cache2k/ProductHelperUsingLoader.java | 19 +++++++-------- .../ProductHelperWithEventListener.java | 19 +++++++-------- .../cache2k/ProductHelperWithExpiry.java | 23 ++++++++----------- .../cache2k/ProductHelperUnitTest.java | 9 ++++---- .../ProductHelperUsingLoaderUnitTest.java | 10 +++++--- ...roductHelperWithEventListenerUnitTest.java | 3 +-- .../ProductHelperWithExpiryUnitTest.java | 12 ++++++---- 8 files changed, 55 insertions(+), 63 deletions(-) diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java index dc984e5f0b..cc646c9e17 100644 --- a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java +++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelper.java @@ -4,38 +4,33 @@ import java.util.Objects; import org.cache2k.Cache; import org.cache2k.Cache2kBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ProductHelper { - final Logger LOGGER = LoggerFactory.getLogger(ProductHelper.class); - private Cache cachedDiscounts; + private int cacheMissCount = 0; + public ProductHelper() { cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class) .name("discount") .eternal(true) .entryCapacity(100) .build(); - - initDiscountCache("Sports", 20); - } - - public void initDiscountCache(String productType, Integer value) { - cachedDiscounts.put(productType, value); } public Integer getDiscount(String productType) { Integer discount = cachedDiscounts.get(productType); if (Objects.isNull(discount)) { - LOGGER.info("Discount for {} not found.", productType); - discount = 0; - } else { - LOGGER.info("Discount for {} found.", productType); + cacheMissCount++; + discount = "Sports".equalsIgnoreCase(productType) ? 20 : 10; + cachedDiscounts.put(productType, discount); } return discount; } + public int getCacheMissCount() { + return cacheMissCount; + } + } diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java index 787a78cd36..7b2ac4caa1 100644 --- a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java +++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperUsingLoader.java @@ -1,6 +1,5 @@ package com.baeldung.cache2k; -import java.util.Objects; import java.util.concurrent.TimeUnit; import org.cache2k.Cache; @@ -14,28 +13,26 @@ public class ProductHelperUsingLoader { private Cache cachedDiscounts; + private int cacheMissCount = 0; + public ProductHelperUsingLoader() { cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class) .name("discount-loader") - .eternal(false) .expireAfterWrite(10, TimeUnit.MILLISECONDS) .entryCapacity(100) .loader((key) -> { - LOGGER.info("Calculating discount for {}.", key); + cacheMissCount++; return "Sports".equalsIgnoreCase(key) ? 20 : 10; }) .build(); } public Integer getDiscount(String productType) { - Integer discount = cachedDiscounts.get(productType); - if (Objects.isNull(discount)) { - LOGGER.info("Discount for {} not found.", productType); - discount = 0; - } else { - LOGGER.info("Discount for {} found.", productType); - } - return discount; + return cachedDiscounts.get(productType); + } + + public int getCacheMissCount() { + return cacheMissCount; } } diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java index 5b9eb28c68..90c6ee3adf 100644 --- a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java +++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithEventListener.java @@ -1,6 +1,5 @@ package com.baeldung.cache2k; -import java.util.Objects; import java.util.concurrent.TimeUnit; import org.cache2k.Cache; @@ -16,14 +15,15 @@ public class ProductHelperWithEventListener { private Cache cachedDiscounts; + private int cacheMissCount = 0; + public ProductHelperWithEventListener() { cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class) .name("discount-listener") - .eternal(false) .expireAfterWrite(10, TimeUnit.MILLISECONDS) .entryCapacity(100) .loader((key) -> { - LOGGER.info("Calculating discount for {}.", key); + cacheMissCount++; return "Sports".equalsIgnoreCase(key) ? 20 : 10; }) .addListener(new CacheEntryCreatedListener() { @@ -36,14 +36,11 @@ public class ProductHelperWithEventListener { } public Integer getDiscount(String productType) { - Integer discount = cachedDiscounts.get(productType); - if (Objects.isNull(discount)) { - LOGGER.info("Discount for {} not found.", productType); - discount = 0; - } else { - LOGGER.info("Discount for {} found.", productType); - } - return discount; + return cachedDiscounts.get(productType); + } + + public int getCacheMissCount() { + return cacheMissCount; } } diff --git a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java index b0bf8f90de..22b656fead 100644 --- a/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java +++ b/libraries-3/src/main/java/com/baeldung/cache2k/ProductHelperWithExpiry.java @@ -5,39 +5,34 @@ import java.util.concurrent.TimeUnit; import org.cache2k.Cache; import org.cache2k.Cache2kBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ProductHelperWithExpiry { - final Logger LOGGER = LoggerFactory.getLogger(ProductHelperWithExpiry.class); - private Cache cachedDiscounts; + private int cacheMissCount = 0; + public ProductHelperWithExpiry() { cachedDiscounts = Cache2kBuilder.of(String.class, Integer.class) .name("discount-expiry") - .eternal(false) .expireAfterWrite(5, TimeUnit.MILLISECONDS) .entryCapacity(100) .build(); - initDiscountCache("Sports", 20); - } - - public void initDiscountCache(String productType, Integer value) { - cachedDiscounts.put(productType, value); } public Integer getDiscount(String productType) { Integer discount = cachedDiscounts.get(productType); if (Objects.isNull(discount)) { - LOGGER.info("Discount for {} not found.", productType); - discount = 0; - } else { - LOGGER.info("Discount for {} found.", productType); + cacheMissCount++; + discount = "Sports".equalsIgnoreCase(productType) ? 20 : 10; + cachedDiscounts.put(productType, discount); } return discount; } + public int getCacheMissCount() { + return cacheMissCount; + } + } diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java index 69da2591dd..e9b495279a 100644 --- a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java +++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUnitTest.java @@ -6,12 +6,13 @@ import org.junit.Test; public class ProductHelperUnitTest { - ProductHelper productHelper = new ProductHelper(); - @Test - public void whenInvokedGetDiscount_thenGetItFromCache() { + public void whenInvokedGetDiscountTwice_thenGetItFromCache() { + ProductHelper productHelper = new ProductHelper(); + assertTrue(productHelper.getCacheMissCount() == 0); assertTrue(productHelper.getDiscount("Sports") == 20); - assertTrue(productHelper.getDiscount("Electronics") == 0); + assertTrue(productHelper.getDiscount("Sports") == 20); + assertTrue(productHelper.getCacheMissCount() == 1); } } diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java index 2656e75cab..3ad77aa2de 100644 --- a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java +++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperUsingLoaderUnitTest.java @@ -6,12 +6,16 @@ import org.junit.Test; public class ProductHelperUsingLoaderUnitTest { - ProductHelperUsingLoader productHelper = new ProductHelperUsingLoader(); - @Test - public void whenInvokedGetDiscount_thenPopulateCache() { + public void whenInvokedGetDiscount_thenPopulateCacheUsingLoader() { + ProductHelperUsingLoader productHelper = new ProductHelperUsingLoader(); + assertTrue(productHelper.getCacheMissCount() == 0); + assertTrue(productHelper.getDiscount("Sports") == 20); + assertTrue(productHelper.getCacheMissCount() == 1); + assertTrue(productHelper.getDiscount("Electronics") == 10); + assertTrue(productHelper.getCacheMissCount() == 2); } } diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java index 7bf08232f4..9aeb9f0552 100644 --- a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java +++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithEventListenerUnitTest.java @@ -6,10 +6,9 @@ import org.junit.Test; public class ProductHelperWithEventListenerUnitTest { - ProductHelperWithEventListener productHelper = new ProductHelperWithEventListener(); - @Test public void whenEntryAddedInCache_thenEventListenerCalled() { + ProductHelperWithEventListener productHelper = new ProductHelperWithEventListener(); assertTrue(productHelper.getDiscount("Sports") == 20); } diff --git a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java index 65feba2c70..a3303ca0aa 100644 --- a/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java +++ b/libraries-3/src/test/java/com/baeldung/cache2k/ProductHelperWithExpiryUnitTest.java @@ -6,13 +6,17 @@ import org.junit.Test; public class ProductHelperWithExpiryUnitTest { - ProductHelperWithExpiry productHelper = new ProductHelperWithExpiry(); - @Test - public void whenInvokedGetDiscountForExpiredProduct_thenNoDiscount() throws InterruptedException { + public void whenInvokedGetDiscountAfterExpiration_thenDiscountCalculatedAgain() throws InterruptedException { + ProductHelperWithExpiry productHelper = new ProductHelperWithExpiry(); + assertTrue(productHelper.getCacheMissCount() == 0); assertTrue(productHelper.getDiscount("Sports") == 20); + assertTrue(productHelper.getCacheMissCount() == 1); + Thread.sleep(20); - assertTrue(productHelper.getDiscount("Sports") == 0); + + assertTrue(productHelper.getDiscount("Sports") == 20); + assertTrue(productHelper.getCacheMissCount() == 2); } } From b609d50214d05a528cbad3bcd234a33af7c7792a Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 21 Feb 2020 20:07:58 +0000 Subject: [PATCH 37/62] Examples for Moshi Json (#8753) * Examples for Moshi Json * Renamed Moshi tests to BDD style * Updated some indents * Minor code tweak to prefer ternary over if/else --- libraries-3/pom.xml | 12 +- .../moshi/AlternativeAdapterUnitTest.java | 105 ++++++++++++++ .../com/baeldung/moshi/ArrayUnitTest.java | 36 +++++ .../moshi/ComplexAdapterUnitTest.java | 94 +++++++++++++ .../com/baeldung/moshi/DefaultUnitTest.java | 68 +++++++++ .../com/baeldung/moshi/PrimitiveUnitTest.java | 77 +++++++++++ .../com/baeldung/moshi/RenameUnitTest.java | 68 +++++++++ .../baeldung/moshi/SimpleAdapterUnitTest.java | 129 ++++++++++++++++++ .../com/baeldung/moshi/TransientUnitTest.java | 66 +++++++++ 9 files changed, 654 insertions(+), 1 deletion(-) create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 5dccebd196..4bb1a4fba1 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -73,6 +73,16 @@ ${cache2k.version} pom + + com.squareup.moshi + moshi + ${moshi.version} + + + com.squareup.moshi + moshi-adapters + ${moshi.version} + com.jcabi @@ -135,7 +145,7 @@ 0.43 2.7.2 1.2.3.Final - + 1.9.2 0.22.6 1.9.2 0.14.1 diff --git a/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java new file mode 100644 index 0000000000..63d80bfe58 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.time.Instant; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonQualifier; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class AlternativeAdapterUnitTest { + @Test + public void whenSerializing_thenAlternativeAdapterUsed() { + Moshi moshi = new Moshi.Builder() + .add(new EpochMillisAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = jsonAdapter.toJson(new Post("Introduction to Moshi Json", "Baeldung", Instant.now())); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenAlternativeAdapterUsed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new EpochMillisAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung\",\"posted\":1582095269204,\"title\":\"Introduction to Moshi Json\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + + } + + public static class Post { + String title; + String author; + @EpochMillis Instant posted; + + public Post() { + } + + public Post(String title, String author, Instant posted) { + this.title = title; + this.author = author; + this.posted = posted; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public Instant getPosted() { + return posted; + } + + public void setPosted(Instant posted) { + this.posted = posted; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("posted", posted) + .toString(); + } + } + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) + @JsonQualifier + public @interface EpochMillis { + } + + public static class EpochMillisAdapter { + @ToJson + public Long toJson(@EpochMillis Instant input) { + return input.toEpochMilli(); + } + @FromJson + @EpochMillis + public Instant fromJson(Long input) { + return Instant.ofEpochMilli(input); + } + + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java new file mode 100644 index 0000000000..83bb2bb128 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; +import org.junit.Test; + +public class ArrayUnitTest { + @Test + public void whenSerializingList_thenJsonArrayProduced() { + Moshi moshi = new Moshi.Builder() + .build(); + Type type = Types.newParameterizedType(List.class, String.class); + JsonAdapter> jsonAdapter = moshi.adapter(type); + + String json = jsonAdapter.toJson(Arrays.asList("One", "Two", "Three")); + System.out.println(json); + } + + @Test + public void whenDeserializingJsonArray_thenListProduced() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + Type type = Types.newParameterizedType(List.class, String.class); + JsonAdapter> jsonAdapter = moshi.adapter(type); + + String json = "[\"One\",\"Two\",\"Three\"]"; + List result = jsonAdapter.fromJson(json); + System.out.println(result); + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java new file mode 100644 index 0000000000..f0f8e9a95d --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.junit.Test; + +public class ComplexAdapterUnitTest { + @Test + public void whenSerializing_thenCorrectJsonProduced() { + Moshi moshi = new Moshi.Builder() + .add(new JsonDateTimeAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(ZonedDateTime.class); + + String json = jsonAdapter.toJson(ZonedDateTime.now()); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenCorrectJsonConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new JsonDateTimeAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(ZonedDateTime.class); + + String json = "{\"date\":\"2020-02-17\",\"time\":\"07:53:27.064\",\"timezone\":\"Europe/London\"}"; + ZonedDateTime now = jsonAdapter.fromJson(json); + System.out.println(now); + + } + + public static class JsonDateTimeAdapter { + @ToJson + public JsonDateTime toJson(ZonedDateTime input) { + String date = input.toLocalDate().toString(); + String time = input.toLocalTime().toString(); + String timezone = input.getZone().toString(); + return new JsonDateTime(date, time, timezone); + } + @FromJson + public ZonedDateTime fromJson(JsonDateTime input) { + LocalDate date = LocalDate.parse(input.getDate()); + LocalTime time = LocalTime.parse(input.getTime()); + ZoneId timezone = ZoneId.of(input.getTimezone()); + return ZonedDateTime.of(date, time, timezone); + } + } + public static class JsonDateTime { + private String date; + private String time; + private String timezone; + + public JsonDateTime() { + } + + public JsonDateTime(String date, String time, String timezone) { + this.date = date; + this.time = time; + this.timezone = timezone; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java new file mode 100644 index 0000000000..0b4ecc23a5 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.time.Instant; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class DefaultUnitTest { + + @Test + public void whenDeserializing_thenFieldsGetDefaultValues() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + private String author; + private String posted; + + public Post() { + posted = Instant.now().toString(); + } + + public Post(String title, String author, String posted) { + this.title = title; + this.author = author; + this.posted = posted; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getPosted() { + return posted; + } + + public void setPosted(String posted) { + this.posted = posted; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("posted", posted) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java new file mode 100644 index 0000000000..e26e93ba8c --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class PrimitiveUnitTest { + @Test + public void whenSerializing_thenCorrectJsonProduced() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung", "This is my post"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenCorrectJsonConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung\",\"text\":\"This is my post\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + + public static class Post { + private String title; + private String author; + private String text; + + public Post() { + } + + public Post(String title, String author, String text) { + this.title = title; + this.author = author; + this.text = text; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("text", text) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java new file mode 100644 index 0000000000..2118538a19 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.Json; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.jupiter.api.Test; + +public class RenameUnitTest { + + @Test + public void whenSerializing_thenFieldsGetRenamed() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenSerializing_thenRenamedFieldsGetConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"authored_by\":\"Baeldung\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + @Json(name = "authored_by") + private String author; + + public Post() { + } + + public Post(String title, String author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java new file mode 100644 index 0000000000..e0be2f8a66 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java @@ -0,0 +1,129 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class SimpleAdapterUnitTest { + @Test + public void whenSerializing_thenAdapterUsed() { + Moshi moshi = new Moshi.Builder() + .add(new AuthorAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", new Author("Baeldung", "baeldung@example.com"), "This is my post"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenAdapterUsed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new AuthorAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung \",\"text\":\"This is my post\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class AuthorAdapter { + private Pattern pattern = Pattern.compile("^(.*) <(.*)>$"); + @ToJson + public String toJson(Author author) { + return author.name + " <" + author.email + ">"; + } + + @FromJson + public Author fromJson(String author) { + Matcher matcher = pattern.matcher(author); + return matcher.find() ? new Author(matcher.group(1), matcher.group(2)) : null; + } + } + + public static class Author { + private String name; + private String email; + + public Author() { + } + + public Author(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("name", name).append("email", email).toString(); + } + } + public static class Post { + private String title; + private Author author; + private String text; + + public Post() { + } + + public Post(String title, Author author, String text) { + this.title = title; + this.author = author; + this.text = text; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("text", text) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java new file mode 100644 index 0000000000..2554e937b3 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java @@ -0,0 +1,66 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.jupiter.api.Test; + +public class TransientUnitTest { + + @Test + public void whenSerializing_thenTransientFieldIgnored() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenTransientFieldIgnored() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"authored_by\":\"Baeldung\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + private transient String author; + + public Post() { + } + + public Post(String title, String author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).toString(); + } + } +} From 03e3b5c046e1223088693fcd22b353fd0f5c635d Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:10:55 +0100 Subject: [PATCH 38/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-archaius --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spring-cloud/spring-cloud-archaius/basic-config/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) rename spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/SpringContextTest.java index 7674713ff8..3b32f2d9f4 100644 --- a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/SpringContextTest.java index a03bd8c23b..21bb7f87a4 100644 --- a/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From c28dd10fa762850d2ad2d9b74bd3cba48df6f49b Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:15:18 +0100 Subject: [PATCH 39/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-kubernetes --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/{org => com}/baeldung/SpringContextTest.java (94%) rename spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) rename spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/com/baeldung/SpringContextTest.java similarity index 94% rename from spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/com/baeldung/SpringContextTest.java index af59614f7c..8539e2af45 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/client-service/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java index af393cb697..837c24264c 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java index 17cb5a5f39..1bf977a606 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From ac44d74f33f0d6c790a22a29aaabe80b9ac96d56 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:20:16 +0100 Subject: [PATCH 40/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-bootstrap --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../test/java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../test/java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../test/java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../test/java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename spring-cloud/spring-cloud-bootstrap/config/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) rename spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (96%) rename spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (96%) rename spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (96%) rename spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (96%) rename spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-bootstrap/config/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-bootstrap/config/src/test/java/com/baeldung/SpringContextTest.java index 98ae3e4895..35691c7aad 100644 --- a/spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-bootstrap/config/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/com/baeldung/SpringContextLiveTest.java index e4e2e95e04..2e7b52ac68 100644 --- a/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/SpringContextLiveTest.java index e0342cf82c..f5c005b11f 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java index 2e437aa3f7..c5bbc74d95 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java index e2921f0308..fbd13720d2 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/com/baeldung/SpringContextTest.java index 76b7539b6b..71e67df191 100644 --- a/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From 505ed38593436b3510dab38639e7e8025ba9a0e7 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:25:02 +0100 Subject: [PATCH 41/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-zookeeper --- spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml | 6 ++++++ .../src/test/{ => java/com}/baeldung/SpringContextTest.java | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) rename spring-cloud/spring-cloud-zookeeper/Greeting/src/test/{ => java/com}/baeldung/SpringContextTest.java (81%) diff --git a/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml index b0ee448e87..fd524a1a4a 100644 --- a/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml @@ -56,6 +56,12 @@ spring-cloud-starter-feign ${spring-cloud-starter-feign.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + org.hamcrest hamcrest-core diff --git a/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/java/com/baeldung/SpringContextTest.java similarity index 81% rename from spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-zookeeper/Greeting/src/test/java/com/baeldung/SpringContextTest.java index b45e7b9889..f7325e425f 100644 --- a/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/java/com/baeldung/SpringContextTest.java @@ -1,12 +1,11 @@ -package org.baeldung; +package com.baeldung; +import com.baeldung.spring.cloud.greeting.GreetingApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.spring.cloud.ribbon.client.ServerLocationApp; - @RunWith(SpringRunner.class) @SpringBootTest(classes = GreetingApplication.class) public class SpringContextTest { From 8c709e9f8c5bbdf2daca7e67f420d6a9245090ed Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:29:23 +0100 Subject: [PATCH 42/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-contract --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) rename spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/SpringContextTest.java index e9098b1467..b491597d0e 100644 --- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/SpringContextTest.java index 7d77cbbd7a..9542ddabb9 100644 --- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From f8e227d0cf2d142891aad158c08e90d3736439c7 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:35:49 +0100 Subject: [PATCH 43/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-rest --- .../java/{org => com}/baeldung/BooksApiApplication.java | 2 +- .../src/main/java/{org => com}/baeldung/SessionConfig.java | 2 +- .../baeldung/persistence/dao/BookRepository.java | 4 ++-- .../java/{org => com}/baeldung/persistence/model/Book.java | 2 +- .../java/{org => com}/baeldung/BooksApiIntegrationTest.java | 2 +- .../test/java/{org => com}/baeldung/RestApiLiveTest.java | 6 ++++-- .../test/java/{org => com}/baeldung/SessionLiveTest.java | 5 ++++- .../java/{org => com}/baeldung/SpringContextLiveTest.java | 3 ++- .../baeldung/SpringCloudRestConfigApplication.java | 2 +- .../test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/main/java/com}/baeldung/SessionConfig.java | 2 +- .../baeldung/SpringCloudRestServerApplication.java | 2 +- .../baeldung/SpringCloudRestServerIntegrationTest.java | 2 +- .../java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../{org => com}/baeldung/BookReviewsApiApplication.java | 2 +- .../src/main/java/com}/baeldung/SessionConfig.java | 2 +- .../baeldung/persistence/dao/BookReviewRepository.java | 4 ++-- .../{org => com}/baeldung/persistence/model/BookReview.java | 2 +- .../baeldung/BookReviewsApiIntegrationTest.java | 2 +- .../test/java/{org => com}/baeldung/RestApiLiveTest.java | 6 ++++-- .../java/{org => com}/baeldung/SpringContextLiveTest.java | 3 ++- 21 files changed, 34 insertions(+), 25 deletions(-) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/{org => com}/baeldung/BooksApiApplication.java (94%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/{org => com}/baeldung/SessionConfig.java (93%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/{org => com}/baeldung/persistence/dao/BookRepository.java (86%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/{org => com}/baeldung/persistence/model/Book.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/{org => com}/baeldung/BooksApiIntegrationTest.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/{org => com}/baeldung/RestApiLiveTest.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/{org => com}/baeldung/SessionLiveTest.java (95%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (89%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/{org => com}/baeldung/SpringCloudRestConfigApplication.java (95%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/{org => com}/baeldung/SpringContextTest.java (94%) rename spring-cloud/spring-cloud-rest/{spring-cloud-rest-reviews-api/src/main/java/org => spring-cloud-rest-discovery-server/src/main/java/com}/baeldung/SessionConfig.java (93%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/{org => com}/baeldung/SpringCloudRestServerApplication.java (95%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/{org => com}/baeldung/SpringCloudRestServerIntegrationTest.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (96%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/{org => com}/baeldung/BookReviewsApiApplication.java (94%) rename spring-cloud/spring-cloud-rest/{spring-cloud-rest-discovery-server/src/main/java/org => spring-cloud-rest-reviews-api/src/main/java/com}/baeldung/SessionConfig.java (93%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/{org => com}/baeldung/persistence/dao/BookReviewRepository.java (85%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/{org => com}/baeldung/persistence/model/BookReview.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/{org => com}/baeldung/BookReviewsApiIntegrationTest.java (98%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/{org => com}/baeldung/RestApiLiveTest.java (97%) rename spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (88%) diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/BooksApiApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/BooksApiApplication.java similarity index 94% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/BooksApiApplication.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/BooksApiApplication.java index 3a843ba3fb..abcbabe737 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/BooksApiApplication.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/BooksApiApplication.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/SessionConfig.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/SessionConfig.java similarity index 93% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/SessionConfig.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/SessionConfig.java index bd1c0013ca..6c984fb6d5 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/SessionConfig.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/SessionConfig.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/dao/BookRepository.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/dao/BookRepository.java similarity index 86% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/dao/BookRepository.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/dao/BookRepository.java index 1b0c32218f..434d4332f7 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/dao/BookRepository.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/dao/BookRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package com.baeldung.persistence.dao; -import org.baeldung.persistence.model.Book; +import com.baeldung.persistence.model.Book; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/model/Book.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/model/Book.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/model/Book.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/model/Book.java index ad5630ea33..26fe3625ec 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/org/baeldung/persistence/model/Book.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/java/com/baeldung/persistence/model/Book.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/BooksApiIntegrationTest.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/BooksApiIntegrationTest.java index 15056e110c..2a90b668cb 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/BooksApiIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/RestApiLiveTest.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/RestApiLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/RestApiLiveTest.java index 830ec96e08..4184b3aef7 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/RestApiLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/RestApiLiveTest.java @@ -1,14 +1,16 @@ -package org.baeldung; +package com.baeldung; import static io.restassured.RestAssured.preemptive; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; + +import com.baeldung.BooksApiApplication; import io.restassured.RestAssured; import io.restassured.response.Response; -import org.baeldung.persistence.model.Book; +import com.baeldung.persistence.model.Book; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SessionLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SessionLiveTest.java similarity index 95% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SessionLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SessionLiveTest.java index 3e5fa4f046..9869a650b4 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SessionLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SessionLiveTest.java @@ -1,7 +1,10 @@ -package org.baeldung; +package com.baeldung; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; + +import com.baeldung.BooksApiApplication; +import com.baeldung.SessionConfig; import io.restassured.RestAssured; import io.restassured.response.Response; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 89% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SpringContextLiveTest.java index eb56c16c6a..783c2f99c0 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,5 +1,6 @@ -package org.baeldung; +package com.baeldung; +import com.baeldung.BooksApiApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/com/baeldung/SpringCloudRestConfigApplication.java similarity index 95% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/com/baeldung/SpringCloudRestConfigApplication.java index 90c6fe3ec9..d49a21f4ed 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/java/com/baeldung/SpringCloudRestConfigApplication.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/com/baeldung/SpringContextTest.java similarity index 94% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/com/baeldung/SpringContextTest.java index 1b4083e7a6..1548d6a95e 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/SessionConfig.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SessionConfig.java similarity index 93% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/SessionConfig.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SessionConfig.java index bd1c0013ca..6c984fb6d5 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/SessionConfig.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SessionConfig.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SpringCloudRestServerApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SpringCloudRestServerApplication.java similarity index 95% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SpringCloudRestServerApplication.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SpringCloudRestServerApplication.java index 2845ccf961..1cc0f2982c 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SpringCloudRestServerApplication.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/com/baeldung/SpringCloudRestServerApplication.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringCloudRestServerIntegrationTest.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringCloudRestServerIntegrationTest.java index 14597d5c2f..1ee895b6b1 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringCloudRestServerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringContextLiveTest.java index 01266a3bda..92acd482cd 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/BookReviewsApiApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/BookReviewsApiApplication.java similarity index 94% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/BookReviewsApiApplication.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/BookReviewsApiApplication.java index f3b05e95b1..707c97cb69 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/BookReviewsApiApplication.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/BookReviewsApiApplication.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SessionConfig.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/SessionConfig.java similarity index 93% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SessionConfig.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/SessionConfig.java index bd1c0013ca..6c984fb6d5 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/java/org/baeldung/SessionConfig.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/SessionConfig.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/dao/BookReviewRepository.java similarity index 85% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/dao/BookReviewRepository.java index 2107786d62..1f29b66867 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/dao/BookReviewRepository.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/dao/BookReviewRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package com.baeldung.persistence.dao; -import org.baeldung.persistence.model.BookReview; +import com.baeldung.persistence.model.BookReview; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/model/BookReview.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/model/BookReview.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/model/BookReview.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/model/BookReview.java index d8d6aa4fef..4b6ff7f32b 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/org/baeldung/persistence/model/BookReview.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/java/com/baeldung/persistence/model/BookReview.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/BookReviewsApiIntegrationTest.java similarity index 98% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/BookReviewsApiIntegrationTest.java index c63b4ebb08..7d7867f9ac 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/BookReviewsApiIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/RestApiLiveTest.java similarity index 97% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/RestApiLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/RestApiLiveTest.java index 91f76d386a..88f845adcc 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/RestApiLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/RestApiLiveTest.java @@ -1,14 +1,16 @@ -package org.baeldung; +package com.baeldung; import static io.restassured.RestAssured.preemptive; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; + +import com.baeldung.BookReviewsApiApplication; import io.restassured.RestAssured; import io.restassured.response.Response; -import org.baeldung.persistence.model.BookReview; +import com.baeldung.persistence.model.BookReview; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 88% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/SpringContextLiveTest.java index 070abd246f..6bb75ed1eb 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,5 +1,6 @@ -package org.baeldung; +package com.baeldung; +import com.baeldung.BookReviewsApiApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; From da2183885386bd054add16f902a67cfc7d38ba71 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:36:57 +0100 Subject: [PATCH 44/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-ribbon-client --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-cloud/spring-cloud-ribbon-client/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/SpringContextTest.java index 23dbcf8ff6..949718e627 100644 --- a/spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-ribbon-client/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From 9a5df17832473bbcff0fec39a1e1248bd51199cf Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:38:21 +0100 Subject: [PATCH 45/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-stream --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/SpringContextTest.java index 0f3b8de901..c74013f1a6 100644 --- a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From a6c263105b7a33c57ca897d3c0a0ea4944448f95 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:40:27 +0100 Subject: [PATCH 46/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-vault --- .../baeldung/spring/cloud/vaultsample/AccountRepo.java | 4 ++-- .../baeldung/spring/cloud/vaultsample/AccountResource.java | 4 ++-- .../baeldung/spring/cloud/vaultsample/SecretResource.java | 2 +- .../spring/cloud/vaultsample/VaultSampleApplication.java | 2 +- .../baeldung/spring/cloud/vaultsample/domain/Account.java | 2 +- .../spring/cloud/vaultsample/SpringContextLiveTest.java | 3 ++- .../cloud/vaultsample/VaultSampleApplicationLiveTest.java | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) rename spring-cloud/spring-cloud-vault/src/main/java/{org => com}/baeldung/spring/cloud/vaultsample/AccountRepo.java (64%) rename spring-cloud/spring-cloud-vault/src/main/java/{org => com}/baeldung/spring/cloud/vaultsample/AccountResource.java (88%) rename spring-cloud/spring-cloud-vault/src/main/java/{org => com}/baeldung/spring/cloud/vaultsample/SecretResource.java (95%) rename spring-cloud/spring-cloud-vault/src/main/java/{org => com}/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java (86%) rename spring-cloud/spring-cloud-vault/src/main/java/{org => com}/baeldung/spring/cloud/vaultsample/domain/Account.java (98%) rename spring-cloud/spring-cloud-vault/src/test/java/{org => com}/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java (83%) rename spring-cloud/spring-cloud-vault/src/test/java/{org => com}/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java (96%) diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountRepo.java similarity index 64% rename from spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java rename to spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountRepo.java index 318cc84957..700334946d 100644 --- a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java +++ b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountRepo.java @@ -1,6 +1,6 @@ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; -import org.baeldung.spring.cloud.vaultsample.domain.Account; +import com.baeldung.spring.cloud.vaultsample.domain.Account; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountResource.java similarity index 88% rename from spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java rename to spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountResource.java index 8fcaa9e2aa..34147d3719 100644 --- a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java +++ b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/AccountResource.java @@ -1,6 +1,6 @@ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; -import org.baeldung.spring.cloud.vaultsample.domain.Account; +import com.baeldung.spring.cloud.vaultsample.domain.Account; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/SecretResource.java similarity index 95% rename from spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java rename to spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/SecretResource.java index c4579da045..9f51a4512f 100644 --- a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java +++ b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/SecretResource.java @@ -1,7 +1,7 @@ /** * */ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java similarity index 86% rename from spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java rename to spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java index 81ece1ca4c..450aa41f7a 100644 --- a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java +++ b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/domain/Account.java similarity index 98% rename from spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java rename to spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/domain/Account.java index df4778831b..577b108cfd 100644 --- a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java +++ b/spring-cloud/spring-cloud-vault/src/main/java/com/baeldung/spring/cloud/vaultsample/domain/Account.java @@ -1,7 +1,7 @@ /** * */ -package org.baeldung.spring.cloud.vaultsample.domain; +package com.baeldung.spring.cloud.vaultsample.domain; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java b/spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java similarity index 83% rename from spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java index 82fe3d7a4a..0cf88fe712 100644 --- a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java @@ -1,5 +1,6 @@ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; +import com.baeldung.spring.cloud.vaultsample.VaultSampleApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java b/spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java similarity index 96% rename from spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java rename to spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java index 7a9c5ba11a..22f7f8e168 100644 --- a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java +++ b/spring-cloud/spring-cloud-vault/src/test/java/com/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud.vaultsample; +package com.baeldung.spring.cloud.vaultsample; import static org.junit.Assert.assertEquals; From 34b4d4294625c5e8b151dbef663eaed4befcf87d Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:42:08 +0100 Subject: [PATCH 47/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-task --- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/{org => com}/baeldung/SpringContextTest.java (97%) rename spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/{org => com}/baeldung/SpringContextTest.java (95%) diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/com/baeldung/SpringContextTest.java similarity index 97% rename from spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/com/baeldung/SpringContextTest.java index 3dd350b571..32224bf91b 100644 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringContextTest.java similarity index 95% rename from spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringContextTest.java index 51f0926429..35c36bbb82 100644 --- a/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From 0fe1d68f50dba34dd2485da1e4f4d2dbee66e64f Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:43:54 +0100 Subject: [PATCH 48/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: updating pom.xml groups --- spring-cloud/spring-cloud-consul/pom.xml | 2 +- spring-cloud/spring-cloud-rest/pom.xml | 2 +- .../spring-cloud-rest/spring-cloud-rest-books-api/pom.xml | 2 +- .../spring-cloud-rest/spring-cloud-rest-config-server/pom.xml | 2 +- .../spring-cloud-rest-discovery-server/pom.xml | 2 +- .../spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml | 2 +- spring-cloud/spring-cloud-stream/pom.xml | 2 +- .../spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml | 2 +- spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml | 2 +- spring-cloud/spring-cloud-vault/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spring-cloud/spring-cloud-consul/pom.xml b/spring-cloud/spring-cloud-consul/pom.xml index b1f6acd9fe..f7f5f84c56 100644 --- a/spring-cloud/spring-cloud-consul/pom.xml +++ b/spring-cloud/spring-cloud-consul/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-consul spring-cloud-consul jar diff --git a/spring-cloud/spring-cloud-rest/pom.xml b/spring-cloud/spring-cloud-rest/pom.xml index 8677b742de..1136fca020 100644 --- a/spring-cloud/spring-cloud-rest/pom.xml +++ b/spring-cloud/spring-cloud-rest/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-rest 1.0.0-SNAPSHOT spring-cloud-rest diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml index b34e325eb8..042f7657ab 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-rest-books-api 0.0.1-SNAPSHOT spring-cloud-rest-books-api diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml index b3bb6fafdc..5fb9364752 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-rest-config-server 0.0.1-SNAPSHOT spring-cloud-rest-config-server diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml index aec51ca38a..5e35a7c0f5 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-rest-discovery-server 0.0.1-SNAPSHOT spring-cloud-rest-discovery-server diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml index 161b996496..7503418ad2 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-rest-reviews-api 0.0.1-SNAPSHOT spring-cloud-rest-reviews-api diff --git a/spring-cloud/spring-cloud-stream/pom.xml b/spring-cloud/spring-cloud-stream/pom.xml index df17b778da..ebaaab0801 100644 --- a/spring-cloud/spring-cloud-stream/pom.xml +++ b/spring-cloud/spring-cloud-stream/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung + com.baeldung spring-cloud-stream spring-cloud-stream pom diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml index 4273bd8701..4aa42f03d7 100644 --- a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml @@ -8,7 +8,7 @@ Simple Spring Cloud Stream - org.baeldung + com.baeldung spring-cloud-stream 1.0.0-SNAPSHOT .. diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml index be920bb93d..fd10322efb 100644 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.baeldung.cloud + com.baeldung.cloud springcloudtaskbatch springcloudtaskbatch diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml index cbb32ac937..dbdbcb2c50 100644 --- a/spring-cloud/spring-cloud-vault/pom.xml +++ b/spring-cloud/spring-cloud-vault/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung.spring.cloud + com.baeldung.spring.cloud spring-cloud-vault spring-cloud-vault jar From 9b9c6f1cc4b688f9c026602f4fdeca870cc35ab0 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 10:51:16 +0100 Subject: [PATCH 49/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-bus --- .../test/java/{org => com}/baeldung/SpringContextLiveTest.java | 2 +- .../src/test/java/{org => com}/baeldung/SpringContextTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spring-cloud-bus/spring-cloud-config-client/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (98%) rename spring-cloud-bus/spring-cloud-config-server/src/test/java/{org => com}/baeldung/SpringContextTest.java (94%) diff --git a/spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 98% rename from spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringContextLiveTest.java index a401d41e1e..de1f96a168 100644 --- a/spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringContextTest.java similarity index 94% rename from spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringContextTest.java index 19ca53c4a7..0770db220c 100644 --- a/spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringContextTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.junit.Test; import org.junit.runner.RunWith; From 148359bece1922bbaa8ef63d0e64271d0fade05a Mon Sep 17 00:00:00 2001 From: dupirefr Date: Sat, 22 Feb 2020 11:00:55 +0100 Subject: [PATCH 50/62] [JAVA-632] Standardizing packages from org.baeldung to com.baeldung: spring-cloud-data-flow --- spring-cloud-data-flow/batch-job/pom.xml | 2 +- .../spring/cloud/BatchJobApplication.java | 2 +- .../spring/cloud/JobConfiguration.java | 78 +++++++++---------- .../baeldung/SpringContextTest.java | 4 +- .../BatchJobApplicationIntegrationTest.java | 2 +- .../cloud/DataFlowServerApplication.java | 2 +- .../baeldung/SpringContextTest.java | 4 +- ...aFlowServerApplicationIntegrationTest.java | 2 +- .../cloud/DataFlowShellApplication.java | 2 +- .../baeldung/SpringContextLiveTest.java | 4 +- .../spring/cloud/LogSinkApplication.java | 2 +- .../baeldung/SpringContextTest.java | 4 +- .../cloud/TimeProcessorApplication.java | 2 +- .../baeldung/SpringContextTest.java | 4 +- .../spring/cloud/TimeSourceApplication.java | 2 +- .../baeldung/SpringContextTest.java | 4 +- 16 files changed, 60 insertions(+), 60 deletions(-) rename spring-cloud-data-flow/batch-job/src/main/java/{org => com}/baeldung/spring/cloud/BatchJobApplication.java (91%) rename spring-cloud-data-flow/batch-job/src/main/java/{org => com}/baeldung/spring/cloud/JobConfiguration.java (95%) rename spring-cloud-data-flow/batch-job/src/test/java/{org => com}/baeldung/SpringContextTest.java (86%) rename spring-cloud-data-flow/batch-job/src/test/java/{org => com}/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java (92%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/{org => com}/baeldung/spring/cloud/DataFlowServerApplication.java (92%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/{org => com}/baeldung/SpringContextTest.java (82%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/{org => com}/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java (97%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/{org => com}/baeldung/spring/cloud/DataFlowShellApplication.java (91%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/{org => com}/baeldung/SpringContextLiveTest.java (87%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/{org => com}/baeldung/spring/cloud/LogSinkApplication.java (95%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/{org => com}/baeldung/SpringContextTest.java (82%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/{org => com}/baeldung/spring/cloud/TimeProcessorApplication.java (96%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/{org => com}/baeldung/SpringContextTest.java (81%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/{org => com}/baeldung/spring/cloud/TimeSourceApplication.java (96%) rename spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/{org => com}/baeldung/SpringContextTest.java (81%) diff --git a/spring-cloud-data-flow/batch-job/pom.xml b/spring-cloud-data-flow/batch-job/pom.xml index 1ed0017bc0..e11df0df8e 100644 --- a/spring-cloud-data-flow/batch-job/pom.xml +++ b/spring-cloud-data-flow/batch-job/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - org.baeldung.spring.cloud + com.baeldung.spring.cloud batch-job 0.0.1-SNAPSHOT batch-job diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java b/spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/BatchJobApplication.java similarity index 91% rename from spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java rename to spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/BatchJobApplication.java index 30f6ff6897..6eea25f16f 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/BatchJobApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java b/spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/JobConfiguration.java similarity index 95% rename from spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java rename to spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/JobConfiguration.java index 7ce867b60a..ba30e54446 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/com/baeldung/spring/cloud/JobConfiguration.java @@ -1,39 +1,39 @@ -package org.baeldung.spring.cloud; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.Job; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; -import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; -import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; -import org.springframework.batch.core.scope.context.ChunkContext; -import org.springframework.batch.core.step.tasklet.Tasklet; -import org.springframework.batch.repeat.RepeatStatus; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableBatchProcessing -public class JobConfiguration { - - private static final Log logger = LogFactory.getLog(JobConfiguration.class); - - @Autowired - public JobBuilderFactory jobBuilderFactory; - - @Autowired - public StepBuilderFactory stepBuilderFactory; - - @Bean - public Job job() { - return jobBuilderFactory.get("job").start(stepBuilderFactory.get("jobStep1").tasklet(new Tasklet() { - @Override - public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { - logger.info("Job was run"); - return RepeatStatus.FINISHED; - } - }).build()).build(); - } -} +package com.baeldung.spring.cloud; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableBatchProcessing +public class JobConfiguration { + + private static final Log logger = LogFactory.getLog(JobConfiguration.class); + + @Autowired + public JobBuilderFactory jobBuilderFactory; + + @Autowired + public StepBuilderFactory stepBuilderFactory; + + @Bean + public Job job() { + return jobBuilderFactory.get("job").start(stepBuilderFactory.get("jobStep1").tasklet(new Tasklet() { + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + logger.info("Job was run"); + return RepeatStatus.FINISHED; + } + }).build()).build(); + } +} diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/SpringContextTest.java similarity index 86% rename from spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/SpringContextTest.java index 3ac11452d3..0684c32c08 100644 --- a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/SpringContextTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.JobConfiguration; +import com.baeldung.spring.cloud.JobConfiguration; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java similarity index 92% rename from spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java rename to spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java index 1f77351acc..0209a0ba5c 100644 --- a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/batch-job/src/test/java/com/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/com/baeldung/spring/cloud/DataFlowServerApplication.java similarity index 92% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/com/baeldung/spring/cloud/DataFlowServerApplication.java index 227c10b620..4d742b95c6 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/com/baeldung/spring/cloud/DataFlowServerApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/SpringContextTest.java similarity index 82% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/SpringContextTest.java index 83cb8067cf..d5b01c8b9c 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/SpringContextTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.DataFlowServerApplication; +import com.baeldung.spring.cloud.DataFlowServerApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java similarity index 97% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java index 9eba12fc12..68f0db60eb 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/com/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/com/baeldung/spring/cloud/DataFlowShellApplication.java similarity index 91% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/com/baeldung/spring/cloud/DataFlowShellApplication.java index 36c421f5bf..82335e792c 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/com/baeldung/spring/cloud/DataFlowShellApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 87% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/com/baeldung/SpringContextLiveTest.java index 1784eb772a..d899af69a3 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.DataFlowShellApplication; +import com.baeldung.spring.cloud.DataFlowShellApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/com/baeldung/spring/cloud/LogSinkApplication.java similarity index 95% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/com/baeldung/spring/cloud/LogSinkApplication.java index a2b9968539..b7fa0a8c85 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/com/baeldung/spring/cloud/LogSinkApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/com/baeldung/SpringContextTest.java similarity index 82% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/com/baeldung/SpringContextTest.java index 42903189d3..844ab5f499 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/com/baeldung/SpringContextTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.LogSinkApplication; +import com.baeldung.spring.cloud.LogSinkApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/com/baeldung/spring/cloud/TimeProcessorApplication.java similarity index 96% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/com/baeldung/spring/cloud/TimeProcessorApplication.java index 7a2763d436..161fd0ef23 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/com/baeldung/spring/cloud/TimeProcessorApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import java.text.DateFormat; import java.text.SimpleDateFormat; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/com/baeldung/SpringContextTest.java similarity index 81% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/com/baeldung/SpringContextTest.java index d090e626d2..dc863bad07 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/com/baeldung/SpringContextTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.TimeProcessorApplication; +import com.baeldung.spring.cloud.TimeProcessorApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/com/baeldung/spring/cloud/TimeSourceApplication.java similarity index 96% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/com/baeldung/spring/cloud/TimeSourceApplication.java index 5bce39ebe0..e731b36e8a 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/com/baeldung/spring/cloud/TimeSourceApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.spring.cloud; import java.util.Date; diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/com/baeldung/SpringContextTest.java similarity index 81% rename from spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/com/baeldung/SpringContextTest.java index e19b88de90..a850707827 100644 --- a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/com/baeldung/SpringContextTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.spring.cloud.TimeSourceApplication; +import com.baeldung.spring.cloud.TimeSourceApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; From 9da978ec652a363a239c051ad20b5e5ce7cff829 Mon Sep 17 00:00:00 2001 From: Shubhra Srivastava Date: Sat, 22 Feb 2020 15:50:14 +0530 Subject: [PATCH 51/62] BAEL-3298 Spring batch retry job (#8690) * BAEL-3298 Spring batch retry job * BAEL-3298 Adding tests and refactoring * BAEL-3298 Some more refactoring * Review comments * Some refactoring * Refactoring RetryItemProcessor * Minor refactoring in test class * BAEL-3298 Some more refactoring * BAEL-3298 Using @MockBean * BAEL-3298 minor update * BAEL-3298 Updating names of testcases * updating id to 9999 * Updating id to 9999 * Updating id to 9999 --- .../src/main/java/org/baeldung/batch/App.java | 4 + .../batch/SpringBatchRetryConfig.java | 117 ++++++++++++++++++ .../org/baeldung/batch/model/Transaction.java | 20 ++- .../batch/service/RetryItemProcessor.java | 42 +++++++ .../src/main/resources/input/recordRetry.csv | 3 + .../src/main/resources/spring-batch-intro.xml | 15 +++ .../SpringBatchRetryIntegrationTest.java | 90 ++++++++++++++ .../output/batchRetry/retryOutput.xml | 1 + spring-batch/xml/retryOutput.xml | 1 + 9 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 spring-batch/src/main/java/org/baeldung/batch/SpringBatchRetryConfig.java create mode 100644 spring-batch/src/main/java/org/baeldung/batch/service/RetryItemProcessor.java create mode 100644 spring-batch/src/main/resources/input/recordRetry.csv create mode 100644 spring-batch/src/test/java/org/baeldung/batch/SpringBatchRetryIntegrationTest.java create mode 100644 spring-batch/src/test/resources/output/batchRetry/retryOutput.xml create mode 100644 spring-batch/xml/retryOutput.xml diff --git a/spring-batch/src/main/java/org/baeldung/batch/App.java b/spring-batch/src/main/java/org/baeldung/batch/App.java index 91b99ba571..764ef72a35 100644 --- a/spring-batch/src/main/java/org/baeldung/batch/App.java +++ b/spring-batch/src/main/java/org/baeldung/batch/App.java @@ -18,6 +18,8 @@ public class App { final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(SpringConfig.class); context.register(SpringBatchConfig.class); + context.register(SpringBatchRetryConfig.class); + context.refresh(); // Spring xml config @@ -26,6 +28,8 @@ public class App { runJob(context, "firstBatchJob"); runJob(context, "skippingBatchJob"); runJob(context, "skipPolicyBatchJob"); + runJob(context, "retryBatchJob"); + } private static void runJob(AnnotationConfigApplicationContext context, String batchJobName) { diff --git a/spring-batch/src/main/java/org/baeldung/batch/SpringBatchRetryConfig.java b/spring-batch/src/main/java/org/baeldung/batch/SpringBatchRetryConfig.java new file mode 100644 index 0000000000..56088f194b --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batch/SpringBatchRetryConfig.java @@ -0,0 +1,117 @@ +package org.baeldung.batch; + +import org.apache.http.client.config.RequestConfig; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.baeldung.batch.model.Transaction; +import org.baeldung.batch.service.RecordFieldSetMapper; +import org.baeldung.batch.service.RetryItemProcessor; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.mapping.DefaultLineMapper; +import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; +import org.springframework.batch.item.xml.StaxEventItemWriter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.dao.DeadlockLoserDataAccessException; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +import java.text.ParseException; + +@Configuration +@EnableBatchProcessing +public class SpringBatchRetryConfig { + + private static final String[] tokens = { "username", "userid", "transactiondate", "amount" }; + private static final int TWO_SECONDS = 2000; + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @Value("input/recordRetry.csv") + private Resource inputCsv; + + @Value("file:xml/retryOutput.xml") + private Resource outputXml; + + public ItemReader itemReader(Resource inputData) throws ParseException { + DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(); + tokenizer.setNames(tokens); + DefaultLineMapper lineMapper = new DefaultLineMapper<>(); + lineMapper.setLineTokenizer(tokenizer); + lineMapper.setFieldSetMapper(new RecordFieldSetMapper()); + FlatFileItemReader reader = new FlatFileItemReader<>(); + reader.setResource(inputData); + reader.setLinesToSkip(1); + reader.setLineMapper(lineMapper); + return reader; + } + + @Bean + public CloseableHttpClient closeableHttpClient() { + final RequestConfig config = RequestConfig.custom() + .setConnectTimeout(TWO_SECONDS) + .build(); + return HttpClientBuilder.create().setDefaultRequestConfig(config).build(); + } + + @Bean + public ItemProcessor retryItemProcessor() { + return new RetryItemProcessor(); + } + + @Bean + public ItemWriter itemWriter(Marshaller marshaller) { + StaxEventItemWriter itemWriter = new StaxEventItemWriter<>(); + itemWriter.setMarshaller(marshaller); + itemWriter.setRootTagName("transactionRecord"); + itemWriter.setResource(outputXml); + return itemWriter; + } + + @Bean + public Marshaller marshaller() { + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound(Transaction.class); + return marshaller; + } + + @Bean + public Step retryStep(@Qualifier("retryItemProcessor") ItemProcessor processor, + ItemWriter writer) throws ParseException { + return stepBuilderFactory.get("retryStep") + .chunk(10) + .reader(itemReader(inputCsv)) + .processor(processor) + .writer(writer) + .faultTolerant() + .retryLimit(3) + .retry(ConnectTimeoutException.class) + .retry(DeadlockLoserDataAccessException.class) + .build(); + } + + @Bean(name = "retryBatchJob") + public Job retryJob(@Qualifier("retryStep") Step retryStep) { + return jobBuilderFactory + .get("retryBatchJob") + .start(retryStep) + .build(); + } +} diff --git a/spring-batch/src/main/java/org/baeldung/batch/model/Transaction.java b/spring-batch/src/main/java/org/baeldung/batch/model/Transaction.java index 0ce3a413ab..f34462eadd 100644 --- a/spring-batch/src/main/java/org/baeldung/batch/model/Transaction.java +++ b/spring-batch/src/main/java/org/baeldung/batch/model/Transaction.java @@ -9,6 +9,8 @@ import javax.xml.bind.annotation.XmlRootElement; public class Transaction { private String username; private int userId; + private int age; + private String postCode; private Date transactionDate; private double amount; @@ -46,9 +48,25 @@ public class Transaction { this.amount = amount; } + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getPostCode() { + return postCode; + } + + public void setPostCode(String postCode) { + this.postCode = postCode; + } + @Override public String toString() { - return "Transaction [username=" + username + ", userId=" + userId + ", transactionDate=" + transactionDate + ", amount=" + amount + "]"; + return "Transaction [username=" + username + ", userId=" + userId + ", age=" + age + ", postCode=" + postCode + ", transactionDate=" + transactionDate + ", amount=" + amount + "]"; } } diff --git a/spring-batch/src/main/java/org/baeldung/batch/service/RetryItemProcessor.java b/spring-batch/src/main/java/org/baeldung/batch/service/RetryItemProcessor.java new file mode 100644 index 0000000000..d4e82452a7 --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batch/service/RetryItemProcessor.java @@ -0,0 +1,42 @@ +package org.baeldung.batch.service; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.baeldung.batch.model.Transaction; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; + +public class RetryItemProcessor implements ItemProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger(RetryItemProcessor.class); + + @Autowired + private CloseableHttpClient closeableHttpClient; + + @Override + public Transaction process(Transaction transaction) throws IOException, JSONException { + LOGGER.info("Attempting to process user with id={}", transaction.getUserId()); + HttpResponse response = fetchMoreUserDetails(transaction.getUserId()); + + //parse user's age and postCode from response and update transaction + String result = EntityUtils.toString(response.getEntity()); + JSONObject userObject = new JSONObject(result); + transaction.setAge(Integer.parseInt(userObject.getString("age"))); + transaction.setPostCode(userObject.getString("postCode")); + + return transaction; + } + + private HttpResponse fetchMoreUserDetails(int id) throws IOException { + final HttpGet request = new HttpGet("http://www.baeldung.com:81/user/" + id); + return closeableHttpClient.execute(request); + } +} diff --git a/spring-batch/src/main/resources/input/recordRetry.csv b/spring-batch/src/main/resources/input/recordRetry.csv new file mode 100644 index 0000000000..1b1e3e1ac9 --- /dev/null +++ b/spring-batch/src/main/resources/input/recordRetry.csv @@ -0,0 +1,3 @@ +username, user_id, transaction_date, transaction_amount +sammy, 1234, 31/10/2015, 10000 +john, 9999, 3/12/2015, 12321 diff --git a/spring-batch/src/main/resources/spring-batch-intro.xml b/spring-batch/src/main/resources/spring-batch-intro.xml index 0f76dd50ff..908b8aa2e1 100644 --- a/spring-batch/src/main/resources/spring-batch-intro.xml +++ b/spring-batch/src/main/resources/spring-batch-intro.xml @@ -54,4 +54,19 @@ + + + + + + + + + + + + + diff --git a/spring-batch/src/test/java/org/baeldung/batch/SpringBatchRetryIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/batch/SpringBatchRetryIntegrationTest.java new file mode 100644 index 0000000000..293c97ac5d --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/batch/SpringBatchRetryIntegrationTest.java @@ -0,0 +1,90 @@ +package org.baeldung.batch; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.springframework.batch.core.ExitStatus; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobInstance; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.test.AssertFile; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.context.SpringBatchTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.core.io.FileSystemResource; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@RunWith(SpringRunner.class) +@SpringBatchTest +@EnableAutoConfiguration +@ContextConfiguration(classes = { SpringBatchRetryConfig.class }) +public class SpringBatchRetryIntegrationTest { + + private static final String TEST_OUTPUT = "xml/retryOutput.xml"; + private static final String EXPECTED_OUTPUT = "src/test/resources/output/batchRetry/retryOutput.xml"; + + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; + + @MockBean + private CloseableHttpClient closeableHttpClient; + + @Mock + private CloseableHttpResponse httpResponse; + + @Test + public void whenEndpointAlwaysFail_thenJobFails() throws Exception { + when(closeableHttpClient.execute(any())) + .thenThrow(new ConnectTimeoutException("Endpoint is down")); + + JobExecution jobExecution = jobLauncherTestUtils.launchJob(defaultJobParameters()); + JobInstance actualJobInstance = jobExecution.getJobInstance(); + ExitStatus actualJobExitStatus = jobExecution.getExitStatus(); + + assertThat(actualJobInstance.getJobName(), is("retryBatchJob")); + assertThat(actualJobExitStatus.getExitCode(), is("FAILED")); + assertThat(actualJobExitStatus.getExitDescription(), containsString("org.apache.http.conn.ConnectTimeoutException")); + } + + @Test + public void whenEndpointFailsTwicePasses3rdTime_thenSuccess() throws Exception { + FileSystemResource expectedResult = new FileSystemResource(EXPECTED_OUTPUT); + FileSystemResource actualResult = new FileSystemResource(TEST_OUTPUT); + + //fails for first two calls and passes third time onwards + when(httpResponse.getEntity()) + .thenReturn(new StringEntity("{ \"age\":10, \"postCode\":\"430222\" }")); + when(closeableHttpClient.execute(any())) + .thenThrow(new ConnectTimeoutException("Timeout count 1")) + .thenThrow(new ConnectTimeoutException("Timeout count 2")) + .thenReturn(httpResponse); + + JobExecution jobExecution = jobLauncherTestUtils.launchJob(defaultJobParameters()); + JobInstance actualJobInstance = jobExecution.getJobInstance(); + ExitStatus actualJobExitStatus = jobExecution.getExitStatus(); + + assertThat(actualJobInstance.getJobName(), is("retryBatchJob")); + assertThat(actualJobExitStatus.getExitCode(), is("COMPLETED")); + AssertFile.assertFileEquals(expectedResult, actualResult); + } + + private JobParameters defaultJobParameters() { + JobParametersBuilder paramsBuilder = new JobParametersBuilder(); + paramsBuilder.addString("jobID", String.valueOf(System.currentTimeMillis())); + return paramsBuilder.toJobParameters(); + } +} diff --git a/spring-batch/src/test/resources/output/batchRetry/retryOutput.xml b/spring-batch/src/test/resources/output/batchRetry/retryOutput.xml new file mode 100644 index 0000000000..0de35670f4 --- /dev/null +++ b/spring-batch/src/test/resources/output/batchRetry/retryOutput.xml @@ -0,0 +1 @@ +1010000.04302222015-10-31T00:00:00+05:301234sammy1012321.04302222015-12-03T00:00:00+05:309999john diff --git a/spring-batch/xml/retryOutput.xml b/spring-batch/xml/retryOutput.xml new file mode 100644 index 0000000000..0de35670f4 --- /dev/null +++ b/spring-batch/xml/retryOutput.xml @@ -0,0 +1 @@ +1010000.04302222015-10-31T00:00:00+05:301234sammy1012321.04302222015-12-03T00:00:00+05:309999john From 80b7fed6e1077aca76fd7a0248906d6b792dfcd2 Mon Sep 17 00:00:00 2001 From: Mona Mohamadinia Date: Sat, 22 Feb 2020 14:16:52 +0330 Subject: [PATCH 52/62] Bael 3850: EnabledForJRERange and DisabledForJRERange JUnit Annotations (#8724) * Upgraded to Jupiter 5.6.0 Also removed some deprecated stuff! * Added a new test * Resotre Delete Tests --- testing-modules/junit5-annotations/pom.xml | 4 +- .../ConditionalAnnotationsUnitTest.java | 43 +++++++++++++------ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/testing-modules/junit5-annotations/pom.xml b/testing-modules/junit5-annotations/pom.xml index 080844c30b..d0fba4d21b 100644 --- a/testing-modules/junit5-annotations/pom.xml +++ b/testing-modules/junit5-annotations/pom.xml @@ -49,8 +49,8 @@ - 5.4.2 - 1.4.2 + 5.6.0 + 1.6.0 2.8.2 diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java index ddceb78cac..ba840a1c33 100644 --- a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java +++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/conditional/ConditionalAnnotationsUnitTest.java @@ -10,6 +10,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class ConditionalAnnotationsUnitTest { + @Test @EnabledOnOs({OS.WINDOWS, OS.MAC}) public void shouldRunBothWindowsAndMac() { @@ -28,6 +29,18 @@ public class ConditionalAnnotationsUnitTest { System.out.println("runs with java 10 and 11"); } + @Test + @EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13) + public void shouldOnlyRunOnJava8UntilJava13() { + System.out.println("runs with Java 8, 9, 10, 11, 12 and 13!"); + } + + @Test + @DisabledForJreRange(min = JRE.JAVA_14, max = JRE.JAVA_15) + public void shouldNotBeRunOnJava14AndJava15() { + System.out.println("Shouldn't be run on Java 14 and 15."); + } + @Test @DisabledOnJre(JRE.OTHER) public void thisTestOnlyRunsWithUpToDateJREs() { @@ -58,36 +71,38 @@ public class ConditionalAnnotationsUnitTest { System.out.println("will not run if environment variable LC_TIME is UTF-8"); } + // Commented codes are going to work prior JUnit 5.5 + @Test - @EnabledIf("'FR' == systemProperty.get('user.country')") + // @EnabledIf("'FR' == systemProperty.get('user.country')") public void onlyFrenchPeopleWillRunThisMethod() { System.out.println("will run only if user.country is FR"); } @Test - @DisabledIf("java.lang.System.getProperty('os.name').toLowerCase().contains('mac')") + // @DisabledIf("java.lang.System.getProperty('os.name').toLowerCase().contains('mac')") public void shouldNotRunOnMacOS() { System.out.println("will not run if our os.name is mac"); } @Test - @EnabledIf(value = { - "load('nashorn:mozilla_compat.js')", - "importPackage(java.time)", - "", - "var thisMonth = LocalDate.now().getMonth().name()", - "var february = Month.FEBRUARY.name()", - "thisMonth.equals(february)" + /*@EnabledIf(value = { + "load('nashorn:mozilla_compat.js')", + "importPackage(java.time)", + "", + "var thisMonth = LocalDate.now().getMonth().name()", + "var february = Month.FEBRUARY.name()", + "thisMonth.equals(february)" }, - engine = "nashorn", - reason = "Self-fulfilling: {result}") + engine = "nashorn", + reason = "Self-fulfilling: {result}")*/ public void onlyRunsInFebruary() { System.out.println("this test only runs in February"); } @Test - @DisabledIf("systemEnvironment.get('XPC_SERVICE_NAME') != null " + - "&& systemEnvironment.get('XPC_SERVICE_NAME').contains('intellij')") + /*@DisabledIf("systemEnvironment.get('XPC_SERVICE_NAME') != null " + + "&& systemEnvironment.get('XPC_SERVICE_NAME').contains('intellij')")*/ public void notValidForIntelliJ() { System.out.println("this test will run if our ide is INTELLIJ"); } @@ -107,7 +122,7 @@ public class ConditionalAnnotationsUnitTest { @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) - @DisabledIf("Math.random() >= 0.5") + // @DisabledIf("Math.random() >= 0.5") @interface CoinToss { } From f96fa40ac2c75fbc39ef72e280a161c66e821bb9 Mon Sep 17 00:00:00 2001 From: mikr Date: Sat, 22 Feb 2020 20:08:14 +0100 Subject: [PATCH 53/62] Java-125 Move Spring Boot Parent to Spring Boot Modules --- pom.xml | 2 -- spring-boot-modules/pom.xml | 1 + .../spring-boot-parent}/README.md | 0 .../spring-boot-parent}/pom.xml | 2 +- .../spring-boot-parent}/spring-boot-with-custom-parent/pom.xml | 0 .../customparent/SpringBootStarterCustomParentApplication.java | 0 .../spring-boot-parent}/spring-boot-with-starter-parent/pom.xml | 0 .../starterparent/SpringBootStarterParentApplication.java | 0 8 files changed, 2 insertions(+), 3 deletions(-) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/README.md (100%) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/pom.xml (93%) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/spring-boot-with-custom-parent/pom.xml (100%) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java (100%) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/spring-boot-with-starter-parent/pom.xml (100%) rename {spring-boot-parent => spring-boot-modules/spring-boot-parent}/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java (100%) diff --git a/pom.xml b/pom.xml index ca5331b287..bfc2d27e1e 100644 --- a/pom.xml +++ b/pom.xml @@ -639,7 +639,6 @@ spring-batch spring-bom spring-boot-modules - spring-boot-parent spring-boot-rest spring-caching @@ -1141,7 +1140,6 @@ spring-batch spring-bom spring-boot-modules - spring-boot-parent spring-boot-rest spring-caching diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 4c6560e5fd..1b11d51366 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -43,6 +43,7 @@ spring-boot-mvc-2 spring-boot-mvc-birt spring-boot-nashorn + spring-boot-parent spring-boot-performance spring-boot-properties spring-boot-property-exp diff --git a/spring-boot-parent/README.md b/spring-boot-modules/spring-boot-parent/README.md similarity index 100% rename from spring-boot-parent/README.md rename to spring-boot-modules/spring-boot-parent/README.md diff --git a/spring-boot-parent/pom.xml b/spring-boot-modules/spring-boot-parent/pom.xml similarity index 93% rename from spring-boot-parent/pom.xml rename to spring-boot-modules/spring-boot-parent/pom.xml index 7ce5bdc428..9ac654c1d5 100644 --- a/spring-boot-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/pom.xml @@ -13,7 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - .. + ../../parent-boot-2 diff --git a/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml similarity index 100% rename from spring-boot-parent/spring-boot-with-custom-parent/pom.xml rename to spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml diff --git a/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java similarity index 100% rename from spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java rename to spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java diff --git a/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml similarity index 100% rename from spring-boot-parent/spring-boot-with-starter-parent/pom.xml rename to spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml diff --git a/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java similarity index 100% rename from spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java rename to spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java From 3e8be17de201212dabcb901c9f7e164881a92f5c Mon Sep 17 00:00:00 2001 From: kwoyke Date: Sun, 23 Feb 2020 07:25:35 +0100 Subject: [PATCH 54/62] BAEL-3819: Set returned content type to application/json (#8759) * BAEL-3819: Set returned content type to application/json * BAEL-3819: Add json and xml /content endpoints --- .../ExamplePostController.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/requestresponsebody/ExamplePostController.java b/spring-boot-rest/src/main/java/com/baeldung/requestresponsebody/ExamplePostController.java index 90211b11a3..ac1d28bb72 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/requestresponsebody/ExamplePostController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/requestresponsebody/ExamplePostController.java @@ -1,11 +1,11 @@ package com.baeldung.requestresponsebody; import com.baeldung.services.ExampleService; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @@ -34,4 +34,18 @@ public class ExamplePostController { log.debug("POST received - serializing LoginForm: " + loginForm.getPassword() + " " + loginForm.getUsername()); return new ResponseTransfer("Thanks For Posting!!!"); } + + @PostMapping(value = "/content", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public ResponseTransfer postResponseJsonContent(@RequestBody LoginForm loginForm) { + log.debug("POST received - serializing LoginForm: " + loginForm.getPassword() + " " + loginForm.getUsername()); + return new ResponseTransfer("JSON Content!"); + } + + @PostMapping(value = "/content", produces = MediaType.APPLICATION_XML_VALUE) + @ResponseBody + public ResponseTransfer postResponseXmlContent(@RequestBody LoginForm loginForm) { + log.debug("POST received - serializing LoginForm: " + loginForm.getPassword() + " " + loginForm.getUsername()); + return new ResponseTransfer("XML Content!"); + } } \ No newline at end of file From e673011d6b1b228bfa9e63dbbe0fdb87b855e46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Dupire?= Date: Sun, 23 Feb 2020 17:53:12 +0100 Subject: [PATCH 55/62] [BAEL-3488] Timer Class (#8769) * [BAEL-3488] Moving code to core-java where the original article code was located * [BAEL-3488] Moved original code under timer package --- .../src/main/java/com/baeldung/timer/DatabaseMigrationTask.java | 0 .../src/main/java/com/baeldung/timer/NewsletterTask.java | 0 .../java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java | 0 .../com/baeldung/{ => timer}/JavaTimerLongRunningUnitTest.java | 2 +- .../test/java/com/baeldung/timer/NewsletterTaskUnitTest.java | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename core-java-modules/{core-java-date-operations-2 => core-java}/src/main/java/com/baeldung/timer/DatabaseMigrationTask.java (100%) rename core-java-modules/{core-java-date-operations-2 => core-java}/src/main/java/com/baeldung/timer/NewsletterTask.java (100%) rename core-java-modules/{core-java-date-operations-2 => core-java}/src/test/java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java (100%) rename core-java-modules/core-java/src/test/java/com/baeldung/{ => timer}/JavaTimerLongRunningUnitTest.java (99%) rename core-java-modules/{core-java-date-operations-2 => core-java}/src/test/java/com/baeldung/timer/NewsletterTaskUnitTest.java (100%) diff --git a/core-java-modules/core-java-date-operations-2/src/main/java/com/baeldung/timer/DatabaseMigrationTask.java b/core-java-modules/core-java/src/main/java/com/baeldung/timer/DatabaseMigrationTask.java similarity index 100% rename from core-java-modules/core-java-date-operations-2/src/main/java/com/baeldung/timer/DatabaseMigrationTask.java rename to core-java-modules/core-java/src/main/java/com/baeldung/timer/DatabaseMigrationTask.java diff --git a/core-java-modules/core-java-date-operations-2/src/main/java/com/baeldung/timer/NewsletterTask.java b/core-java-modules/core-java/src/main/java/com/baeldung/timer/NewsletterTask.java similarity index 100% rename from core-java-modules/core-java-date-operations-2/src/main/java/com/baeldung/timer/NewsletterTask.java rename to core-java-modules/core-java/src/main/java/com/baeldung/timer/NewsletterTask.java diff --git a/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java similarity index 100% rename from core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java rename to core-java-modules/core-java/src/test/java/com/baeldung/timer/DatabaseMigrationTaskUnitTest.java diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/JavaTimerLongRunningUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/timer/JavaTimerLongRunningUnitTest.java similarity index 99% rename from core-java-modules/core-java/src/test/java/com/baeldung/JavaTimerLongRunningUnitTest.java rename to core-java-modules/core-java/src/test/java/com/baeldung/timer/JavaTimerLongRunningUnitTest.java index 7063bafb1d..62afcd2f73 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/JavaTimerLongRunningUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/timer/JavaTimerLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.timer; import org.junit.Test; import org.slf4j.Logger; diff --git a/core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/timer/NewsletterTaskUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/timer/NewsletterTaskUnitTest.java similarity index 100% rename from core-java-modules/core-java-date-operations-2/src/test/java/com/baeldung/timer/NewsletterTaskUnitTest.java rename to core-java-modules/core-java/src/test/java/com/baeldung/timer/NewsletterTaskUnitTest.java From f9d902c07bfa00e88a5f94479993092590ccd54e Mon Sep 17 00:00:00 2001 From: vatsalgosar Date: Mon, 24 Feb 2020 00:35:16 +0530 Subject: [PATCH 56/62] BAEL 3617 (#8510) * BAEL-3617 - @ApiParam and @ApiModelProperty examples * file formatted --- .../swagger2boot/config/Swagger2Config.java | 11 +++--- .../controller/UserController.java | 39 +++++++++++++++++++ .../com/baeldung/swagger2boot/model/User.java | 28 +++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java create mode 100644 spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java index a0048eb505..6f3557d597 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java @@ -16,11 +16,12 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; public class Swagger2Config { @Bean public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() - .apis(RequestHandlerSelectors.basePackage("com.baeldung.swagger2boot.controller")) - .paths(PathSelectors.regex("/.*")) - .build() - .apiInfo(apiEndPointsInfo()); + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + .apiInfo(apiEndPointsInfo()); } private ApiInfo apiEndPointsInfo() { diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java new file mode 100644 index 0000000000..d8102a8407 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java @@ -0,0 +1,39 @@ +package com.baeldung.swagger2boot.controller; + +import com.baeldung.swagger2boot.model.Foo; +import com.baeldung.swagger2boot.model.User; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import javax.websocket.server.PathParam; + +import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; + +@Controller +public class UserController { + + public UserController() { + super(); + } //@formatter:off + + @RequestMapping(method = RequestMethod.POST, value = "/createUser", produces = "application/json; charset=UTF-8") + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + @ApiOperation(value = "Create user", + notes = "This method creates a new user") + public User createUser(@ApiParam( + name = "firstName", + type = "String", + value = "First Name of the user", + example = "Vatsal", + required = true) @RequestParam String firstName) { //@formatter:on + User user = new User(firstName); + return user; + } +} diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java new file mode 100644 index 0000000000..d4a6479f4e --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java @@ -0,0 +1,28 @@ +package com.baeldung.swagger2boot.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel +public class User { + + @ApiModelProperty(value = "first name of the user", name = "firstName", dataType = "String", example = "Vatsal") + String firstName; + + public User() { + super(); + } + + public User(final String firstName) { + super(); + this.firstName = firstName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } +} From d6cdbe793a75f5ad18c0e2b57f849d0c0de00bd1 Mon Sep 17 00:00:00 2001 From: mikr Date: Mon, 24 Feb 2020 09:22:14 +0100 Subject: [PATCH 57/62] Java-125 Move Spring Boot Parent to Spring Boot Modules --- spring-boot-modules/spring-boot-parent/pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-boot-modules/spring-boot-parent/pom.xml b/spring-boot-modules/spring-boot-parent/pom.xml index 9ac654c1d5..cf0a6702ea 100644 --- a/spring-boot-modules/spring-boot-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/pom.xml @@ -10,10 +10,9 @@ spring-boot-parent - com.baeldung - parent-modules + com.baeldung.spring-boot-modules + spring-boot-modules 1.0.0-SNAPSHOT - ../../parent-boot-2 From 53b58ab36b90d4c144f441267b61650da0ccf694 Mon Sep 17 00:00:00 2001 From: Macieg Date: Mon, 24 Feb 2020 16:13:22 +0100 Subject: [PATCH 58/62] SCALA-36 (#8764) --- ...HigherOrderFunctionsExamplesUnitTest.scala | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 core-scala/src/test/scala/com/baeldung/scala/HigherOrderFunctionsExamplesUnitTest.scala diff --git a/core-scala/src/test/scala/com/baeldung/scala/HigherOrderFunctionsExamplesUnitTest.scala b/core-scala/src/test/scala/com/baeldung/scala/HigherOrderFunctionsExamplesUnitTest.scala new file mode 100644 index 0000000000..cb43266a48 --- /dev/null +++ b/core-scala/src/test/scala/com/baeldung/scala/HigherOrderFunctionsExamplesUnitTest.scala @@ -0,0 +1,82 @@ +package com.baeldung.scala + +import org.junit.Assert.assertEquals +import org.junit.Test + + +class HigherOrderFunctionsExamplesUnitTest { + + @Test + def whenCallingMapWithAnonymousFunction_thenTransformationIsApplied() = { + val expected = Seq("sir Alex Ferguson", "sir Bobby Charlton", "sir Frank Lampard") + + val names = Seq("Alex Ferguson", "Bobby Charlton", "Frank Lampard") + val sirNames = names.map(name => "sir " + name) + + assertEquals(expected, sirNames) + } + + @Test + def whenCallingMapWithDefined_thenTransformationIsApplied() = { + val expected = Seq("sir Alex Ferguson", "sir Bobby Charlton", "sir Frank Lampard") + + val names = Seq("Alex Ferguson", "Bobby Charlton", "Frank Lampard") + + def prefixWithSir(name: String) = "sir " + name + val sirNames = names.map(prefixWithSir) + + assertEquals(expected, sirNames) + } + + @Test + def whenCallingFilter_thenUnecessaryElementsAreRemoved() = { + val expected = Seq("John O'Shea", "John Hartson") + + val names = Seq("John O'Shea", "Aiden McGeady", "John Hartson") + val johns = names.filter(name => name.matches("^John .*")) + + assertEquals(expected, johns) + } + + @Test + def whenCallingReduce_thenProperSumIsCalculated() = { + val expected = 2750 + + val earnings = Seq(1000, 1300, 450) + val sumEarnings = earnings.reduce((acc, x) => acc + x) + + assertEquals(expected, sumEarnings) + } + + @Test + def whenCallingFold_thenNumberOfWordsShouldBeCalculated() = { + val expected = 6 + + val strings = Seq("bunch of words", "just me", "it") + val sumEarnings = strings.foldLeft(0)((acc, x) => acc + x.split(" ").size) + + assertEquals(expected, sumEarnings) + } + + @Test + def whenCallingOwnHigherOrderFunction_thenProperFunctionIsReturned() = { + def mathOperation(name: String): (Int, Int) => Int = (x: Int, y: Int) => { + name match { + case "addition" => x + y + case "multiplication" => x * y + case "division" => x/y + case "subtraction" => x - y + } + } + + def add: (Int, Int) => Int = mathOperation("addition") + def mul: (Int, Int) => Int = mathOperation("multiplication") + def div: (Int, Int) => Int = mathOperation("division") + def sub: (Int, Int) => Int = mathOperation("subtraction") + + assertEquals(15, add(10, 5)) + assertEquals(50, mul(10, 5)) + assertEquals(2, div(10, 5)) + assertEquals(5, sub(10, 5)) + } +} \ No newline at end of file From 59623b094e05ff3112e8e5f761c84cfdbffd9563 Mon Sep 17 00:00:00 2001 From: gmconte <3528114+gmconte@users.noreply.github.com> Date: Mon, 24 Feb 2020 19:12:40 +0000 Subject: [PATCH 59/62] BAEL-3353: Asynchronous HTTP Programming with Play Framework (#8349) * project creation and added ws library * BAEL-3353: pushing code for article * BAEL-3353: changing test names * BAEL-3353: removed unused imports * BAEL-3353: applied review changes and fixed unit test bug * BAEL-3353: added more examples to PR * BAEL-3353: updated test following feedback * BAEL-3353: add new unit test for large data download * BAEL-3353: fixed PR following feedback --- .../controllers/$model__Camel$Controller.java | 43 ++++ .../app/controllers/$model__Camel$Data.java | 37 +++ .../app/views/$model__camel$/form.scala.html | 12 + .../async-http/.g8/form/default.properties | 2 + .../.g8/form/generated-test/README.md | 1 + .../$model__Camel$ControllerTest.java | 50 ++++ play-framework/async-http/.gitignore | 8 + .../app/controllers/HomeController.java | 38 +++ .../async-http/app/views/index.scala.html | 5 + .../async-http/app/views/main.scala.html | 24 ++ play-framework/async-http/build.sbt | 12 + .../async-http/conf/application.conf | 11 + play-framework/async-http/conf/logback.xml | 36 +++ play-framework/async-http/conf/routes | 10 + .../async-http/project/build.properties | 1 + play-framework/async-http/project/plugins.sbt | 7 + .../async-http/public/images/favicon.png | Bin 0 -> 687 bytes .../async-http/public/javascripts/main.js | 0 .../async-http/public/stylesheets/main.css | 0 .../test/controllers/HomeControllerTest.java | 232 ++++++++++++++++++ 20 files changed, 529 insertions(+) create mode 100644 play-framework/async-http/.g8/form/app/controllers/$model__Camel$Controller.java create mode 100644 play-framework/async-http/.g8/form/app/controllers/$model__Camel$Data.java create mode 100644 play-framework/async-http/.g8/form/app/views/$model__camel$/form.scala.html create mode 100644 play-framework/async-http/.g8/form/default.properties create mode 100644 play-framework/async-http/.g8/form/generated-test/README.md create mode 100644 play-framework/async-http/.g8/form/generated-test/controllers/$model__Camel$ControllerTest.java create mode 100644 play-framework/async-http/.gitignore create mode 100644 play-framework/async-http/app/controllers/HomeController.java create mode 100644 play-framework/async-http/app/views/index.scala.html create mode 100644 play-framework/async-http/app/views/main.scala.html create mode 100644 play-framework/async-http/build.sbt create mode 100644 play-framework/async-http/conf/application.conf create mode 100644 play-framework/async-http/conf/logback.xml create mode 100644 play-framework/async-http/conf/routes create mode 100644 play-framework/async-http/project/build.properties create mode 100644 play-framework/async-http/project/plugins.sbt create mode 100644 play-framework/async-http/public/images/favicon.png create mode 100644 play-framework/async-http/public/javascripts/main.js create mode 100644 play-framework/async-http/public/stylesheets/main.css create mode 100644 play-framework/async-http/test/controllers/HomeControllerTest.java diff --git a/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Controller.java b/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Controller.java new file mode 100644 index 0000000000..1ac4fe547d --- /dev/null +++ b/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Controller.java @@ -0,0 +1,43 @@ +package controllers; + +import play.data.Form; +import play.data.FormFactory; +import play.mvc.Controller; +import play.mvc.Result; + +import javax.inject.Inject; + +// Add the following to conf/routes +/* +GET /$model;format="camel"$ controllers.$model;format="Camel"$Controller.$model;format="camel"$Get +POST /$model;format="camel"$ controllers.$model;format="Camel"$Controller.$model;format="camel"$Post +*/ + +/** + * $model;format="Camel"$ form controller for Play Java + */ +public class $model;format="Camel"$Controller extends Controller { + + private final Form<$model;format="Camel"$Data> $model;format="camel"$Form; + + @Inject + public $model;format="Camel"$Controller(FormFactory formFactory) { + this.$model;format="camel"$Form = formFactory.form($model;format="Camel"$Data.class); + } + + public Result $model;format="camel"$Get() { + return ok(views.html.$model;format="camel"$.form.render($model;format="camel"$Form)); + } + + public Result $model;format="camel"$Post() { + Form<$model;format="Camel"$Data> boundForm = $model;format="camel"$Form.bindFromRequest(); + if (boundForm.hasErrors()) { + return badRequest(views.html.$model;format="camel"$.form.render(boundForm)); + } else { + $model;format="Camel"$Data $model;format="camel"$ = boundForm.get(); + flash("success", "$model;format="Camel"$ " + $model;format="camel"$); + return redirect(routes.$model;format="Camel"$Controller.$model;format="camel"$Get()); + } + } + +} diff --git a/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Data.java b/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Data.java new file mode 100644 index 0000000000..50dc06f478 --- /dev/null +++ b/play-framework/async-http/.g8/form/app/controllers/$model__Camel$Data.java @@ -0,0 +1,37 @@ +package controllers; + +import play.data.validation.Constraints; + +public class $model;format="Camel"$Data { + + @Constraints.Required + private String name; + + @Constraints.Required + private Integer age; + + public $model;format="Camel"$Data() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public String toString() { + return String.format("$model;format="Camel"$Data(%s, %s)", name, age); + } + +} diff --git a/play-framework/async-http/.g8/form/app/views/$model__camel$/form.scala.html b/play-framework/async-http/.g8/form/app/views/$model__camel$/form.scala.html new file mode 100644 index 0000000000..7bf9fd5427 --- /dev/null +++ b/play-framework/async-http/.g8/form/app/views/$model__camel$/form.scala.html @@ -0,0 +1,12 @@ +@($model;format="camel"$Form: Form[$model;format="Camel"$Data]) + +

$model;format="camel"$ form

+ +@flash.getOrDefault("success", "") + +@helper.form(action = routes.$model;format="Camel"$Controller.$model;format="camel"$Post()) { + @helper.CSRF.formField + @helper.inputText($model;format="camel"$Form("name")) + @helper.inputText($model;format="camel"$Form("age")) + +} diff --git a/play-framework/async-http/.g8/form/default.properties b/play-framework/async-http/.g8/form/default.properties new file mode 100644 index 0000000000..32090f30cb --- /dev/null +++ b/play-framework/async-http/.g8/form/default.properties @@ -0,0 +1,2 @@ +description = Generates a Controller with form handling +model = user diff --git a/play-framework/async-http/.g8/form/generated-test/README.md b/play-framework/async-http/.g8/form/generated-test/README.md new file mode 100644 index 0000000000..db01c87f30 --- /dev/null +++ b/play-framework/async-http/.g8/form/generated-test/README.md @@ -0,0 +1 @@ +Temporary file until g8-scaffold will generate "test" directory diff --git a/play-framework/async-http/.g8/form/generated-test/controllers/$model__Camel$ControllerTest.java b/play-framework/async-http/.g8/form/generated-test/controllers/$model__Camel$ControllerTest.java new file mode 100644 index 0000000000..7cdb87068b --- /dev/null +++ b/play-framework/async-http/.g8/form/generated-test/controllers/$model__Camel$ControllerTest.java @@ -0,0 +1,50 @@ +package controllers; + +import org.junit.Test; +import play.Application; +import play.filters.csrf.*; +import play.inject.guice.GuiceApplicationBuilder; +import play.mvc.*; +import play.test.WithApplication; + +import java.util.HashMap; + +import static org.junit.Assert.assertEquals; +import static play.mvc.Http.RequestBuilder; +import static play.mvc.Http.Status.OK; +import static play.test.Helpers.*; +import static play.api.test.CSRFTokenHelper.*; + +public class $model;format="Camel"$ControllerTest extends WithApplication { + + @Override + protected Application provideApplication() { + return new GuiceApplicationBuilder().build(); + } + + @Test + public void test$model;format="Camel"$Get() { + RequestBuilder request = new RequestBuilder() + .method(GET) + .uri("/$model;format="camel"$"); + + Result result = route(app, request); + assertEquals(OK, result.status()); + } + + @Test + public void test$model;format="Camel"$Post() { + HashMap formData = new HashMap<>(); + formData.put("name", "play"); + formData.put("age", "4"); + RequestBuilder request = addCSRFToken(new RequestBuilder() + .header(Http.HeaderNames.HOST, "localhost") + .method(POST) + .bodyForm(formData) + .uri("/$model;format="camel"$")); + + Result result = route(app, request); + assertEquals(SEE_OTHER, result.status()); + } + +} diff --git a/play-framework/async-http/.gitignore b/play-framework/async-http/.gitignore new file mode 100644 index 0000000000..eb372fc719 --- /dev/null +++ b/play-framework/async-http/.gitignore @@ -0,0 +1,8 @@ +logs +target +/.idea +/.idea_modules +/.classpath +/.project +/.settings +/RUNNING_PID diff --git a/play-framework/async-http/app/controllers/HomeController.java b/play-framework/async-http/app/controllers/HomeController.java new file mode 100644 index 0000000000..5c791dcd22 --- /dev/null +++ b/play-framework/async-http/app/controllers/HomeController.java @@ -0,0 +1,38 @@ +package controllers; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableMap; +import java.util.Collections; +import java.util.Map; +import play.mvc.Controller; +import play.mvc.Http; +import play.mvc.Result; + +/** + * This controller contains an action to handle HTTP requests to the application's home page. + */ +public class HomeController extends Controller { + + /** + * An action that renders an HTML page with a welcome message. The configuration in the + * routes file means that this method will be called when the application receives + * a + * GET request with a path of /. + */ + public Result index(Http.Request request) throws JsonProcessingException { + return ok(printStats(request)); + } + + private String printStats(Http.Request request) throws JsonProcessingException { + Map stringMap = request.body() + .asFormUrlEncoded(); + Map map = ImmutableMap.of( + "Result", "ok", + "GetParams", request.queryString(), + "PostParams", stringMap == null ? Collections.emptyMap() : stringMap, + "Headers", request.getHeaders().toMap() + ); + return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(map); + } +} diff --git a/play-framework/async-http/app/views/index.scala.html b/play-framework/async-http/app/views/index.scala.html new file mode 100644 index 0000000000..68d37fb1d4 --- /dev/null +++ b/play-framework/async-http/app/views/index.scala.html @@ -0,0 +1,5 @@ +@() + +@main("Welcome to Play") { +

Welcome to Play!

+} diff --git a/play-framework/async-http/app/views/main.scala.html b/play-framework/async-http/app/views/main.scala.html new file mode 100644 index 0000000000..c5f755f236 --- /dev/null +++ b/play-framework/async-http/app/views/main.scala.html @@ -0,0 +1,24 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + + + + + @* Here's where we render the page title `String`. *@ + @title + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + + + diff --git a/play-framework/async-http/build.sbt b/play-framework/async-http/build.sbt new file mode 100644 index 0000000000..eea47ffe88 --- /dev/null +++ b/play-framework/async-http/build.sbt @@ -0,0 +1,12 @@ +name := """async""" +organization := "com.example" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayJava) + +scalaVersion := "2.13.1" + +// comment out the original line +libraryDependencies += guice +libraryDependencies += javaWs diff --git a/play-framework/async-http/conf/application.conf b/play-framework/async-http/conf/application.conf new file mode 100644 index 0000000000..492f37fed7 --- /dev/null +++ b/play-framework/async-http/conf/application.conf @@ -0,0 +1,11 @@ +# This is the main configuration file for the application. +# https://www.playframework.com/documentation/latest/ConfigFile +play.ws.followRedirects=false +play.ws.useragent=MyPlayApplication +play.ws.compressionEnabled=true +# time to wait for the connection to be established +play.ws.timeout.connection=30.seconds +# time to wait for data after the connection is open +play.ws.timeout.idle=30.seconds +# max time available to complete the request +play.ws.timeout.request=300.seconds diff --git a/play-framework/async-http/conf/logback.xml b/play-framework/async-http/conf/logback.xml new file mode 100644 index 0000000000..55441d39e2 --- /dev/null +++ b/play-framework/async-http/conf/logback.xml @@ -0,0 +1,36 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + diff --git a/play-framework/async-http/conf/routes b/play-framework/async-http/conf/routes new file mode 100644 index 0000000000..4f5162a8e7 --- /dev/null +++ b/play-framework/async-http/conf/routes @@ -0,0 +1,10 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# ~~~~ + +# An example controller showing a sample home page +GET / controllers.HomeController.index(request: Request) +POST / controllers.HomeController.index(request: Request) + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/play-framework/async-http/project/build.properties b/play-framework/async-http/project/build.properties new file mode 100644 index 0000000000..6adcdc753f --- /dev/null +++ b/play-framework/async-http/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.3.3 diff --git a/play-framework/async-http/project/plugins.sbt b/play-framework/async-http/project/plugins.sbt new file mode 100644 index 0000000000..1c8c62a0d5 --- /dev/null +++ b/play-framework/async-http/project/plugins.sbt @@ -0,0 +1,7 @@ +// The Play plugin +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3") + +// Defines scaffolding (found under .g8 folder) +// http://www.foundweekends.org/giter8/scaffolding.html +// sbt "g8Scaffold form" +addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.11.0") diff --git a/play-framework/async-http/public/images/favicon.png b/play-framework/async-http/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d92d2ae47434d9a61c90bc205e099b673b9dd5 GIT binary patch literal 687 zcmV;g0#N;lP)ezT{T_ZJ?}AL z5NC{NW(ESID=>(O3&Eg8 zmA9J&6c`h4_f6L;=bU>_H8aNG`kfvCj9zomNt)?O;rzWqZs0LEt%1WB218%1fo9uB zsW^yhBR7C(mqN%GEK9&msg0~ zWY?#bf4q8G-~2KttQZ($odJvy&_-~f?9*ThK@fwR$U^1)p*8=_+^3BXx0$i1BC8XC zr21u6D5nVK&^!dOAw&|1E;qC3uFNj3*Jj#&%Oje@0D-nhfmM*o%^5f}-pxQ07(95H z3|LoV>V19w#rLgmRmtVy9!T3M3FUE3><0T8&b3yEsWcLW`0(=1+qsqc(k(ymBLK0h zK!6(6$7MX~M`-QA2$wk7n(7hhkJ}4Rwi-Vd(_ZFX1Yk7TXuB0IJYpo@kLb2G8m)E{ z`9v=!hi}fOytKckfN^C@6+Z*+MVI9-W_p@_3yyR#UYc0FTpD}i#k>c!wYCS)4v@E$ zchZCo=zV@)`v^$;V18ixdjFMY#q^2$wEX%{f(XD8POnsn$bpbClpC@hPxjzyO>pY|*pF3UU2tYcCN?rUk{Sskej70Mmu9vPwMYhO1m{AxAt(zqDT|0jP7FaX=6 V`?~}E4H^Id002ovPDHLkV1hC)G==~G literal 0 HcmV?d00001 diff --git a/play-framework/async-http/public/javascripts/main.js b/play-framework/async-http/public/javascripts/main.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/play-framework/async-http/public/stylesheets/main.css b/play-framework/async-http/public/stylesheets/main.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/play-framework/async-http/test/controllers/HomeControllerTest.java b/play-framework/async-http/test/controllers/HomeControllerTest.java new file mode 100644 index 0000000000..a232dbfde0 --- /dev/null +++ b/play-framework/async-http/test/controllers/HomeControllerTest.java @@ -0,0 +1,232 @@ +package controllers; + +import static java.time.temporal.ChronoUnit.SECONDS; +import static org.junit.Assert.assertEquals; +import static play.mvc.Http.Status.SERVICE_UNAVAILABLE; + +import akka.Done; +import akka.actor.ActorSystem; +import akka.stream.ActorMaterializer; +import akka.stream.javadsl.Sink; +import akka.util.ByteString; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.OptionalInt; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import play.Application; +import play.inject.guice.GuiceApplicationBuilder; +import play.libs.concurrent.Futures; +import play.libs.ws.WSClient; +import play.libs.ws.WSResponse; +import play.libs.ws.ahc.AhcCurlRequestLogger; +import play.mvc.Result; +import play.mvc.Results; +import play.test.WithServer; + +public class HomeControllerTest extends WithServer { + + private final Logger log = LoggerFactory.getLogger(HomeControllerTest.class); + private String url; + private int port; + + @Override + protected Application provideApplication() { + return new GuiceApplicationBuilder().build(); + } + + @Before + public void setup() { + OptionalInt optHttpsPort = testServer.getRunningHttpsPort(); + if (optHttpsPort.isPresent()) { + port = optHttpsPort.getAsInt(); + url = "https://localhost:" + port; + } else { + port = testServer.getRunningHttpPort() + .getAsInt(); + url = "http://localhost:" + port; + } + } + + @Test + public void givenASingleGetRequestWhenResponseThenBlockWithCompletableAndLog() + throws Exception { + WSClient ws = play.test.WSTestClient.newClient(port); + WSResponse wsResponse = ws.url(url) + .setRequestFilter(new AhcCurlRequestLogger()) + .addHeader("key", "value") + .addQueryParameter("num", "" + 1) + .get() + .toCompletableFuture() + .get(); + + log.debug("Thread#" + Thread.currentThread() + .getId() + " Request complete: Response code = " + + wsResponse.getStatus() + + " | Response: " + wsResponse.getBody() + " | Current Time:" + + System.currentTimeMillis()); + assert (HttpStatus.SC_OK == wsResponse.getStatus()); + } + + @Test + public void givenASingleGetRequestWhenResponseThenLog() throws Exception { + CountDownLatch latch = new CountDownLatch(1); + WSClient ws = play.test.WSTestClient.newClient(port); + ws.url(url) + .setRequestFilter(new AhcCurlRequestLogger()) + .addHeader("key", "value") + .addQueryParameter("num", "" + 1) + .get() + .thenAccept(r -> { + log.debug("Thread#" + Thread.currentThread() + .getId() + " Request complete: Response code = " + + r.getStatus() + + " | Response: " + r.getBody() + " | Current Time:" + System.currentTimeMillis()); + latch.countDown(); + }); + + log.debug( + "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis()); + latch.await(5, TimeUnit.SECONDS ); + assertEquals(0, latch.getCount()); + log.debug("All requests have been completed. Exiting test."); + } + + @Test + public void givenASinglePostRequestWhenResponseThenLog() throws Exception { + CountDownLatch latch = new CountDownLatch(1); + WSClient ws = play.test.WSTestClient.newClient(port); + ws.url(url) + .setContentType("application/x-www-form-urlencoded") + .post("key1=value1&key2=value2") + .thenAccept(r -> { + log.debug("Thread#" + Thread.currentThread() + .getId() + " Request complete: Response code = " + + r.getStatus() + + " | Response: " + r.getBody() + " | Current Time:" + System.currentTimeMillis()); + latch.countDown(); + }); + + log.debug( + "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis()); + latch.await(5, TimeUnit.SECONDS ); + assertEquals(0, latch.getCount()); + log.debug("All requests have been completed. Exiting test."); + } + + @Test + public void givenMultipleRequestsWhenResponseThenLog() throws Exception { + CountDownLatch latch = new CountDownLatch(100); + WSClient ws = play.test.WSTestClient.newClient(port); + IntStream.range(0, 100) + .parallel() + .forEach(num -> + ws.url(url) + .setRequestFilter(new AhcCurlRequestLogger()) + .addHeader("key", "value") + .addQueryParameter("num", "" + num) + .get() + .thenAccept(r -> { + log.debug( + "Thread#" + num + " Request complete: Response code = " + r.getStatus() + + " | Response: " + r.getBody() + " | Current Time:" + + System.currentTimeMillis()); + latch.countDown(); + }) + ); + + log.debug( + "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis()); + latch.await(5, TimeUnit.SECONDS ); + assertEquals(0, latch.getCount()); + log.debug("All requests have been completed. Exiting test."); + } + + @Test + public void givenLongResponseWhenTimeoutThenHandle() throws Exception { + CountDownLatch latch = new CountDownLatch(1); + WSClient ws = play.test.WSTestClient.newClient(port); + Futures futures = app.injector() + .instanceOf(Futures.class); + CompletionStage f = futures.timeout( + ws.url(url) + .setRequestTimeout(Duration.of(1, SECONDS)) + .get() + .thenApply(result -> { + try { + Thread.sleep(2000L); + return Results.ok(); + } catch (InterruptedException e) { + return Results.status( + SERVICE_UNAVAILABLE); + } + }), 1L, TimeUnit.SECONDS + ); + CompletionStage res = f.handleAsync((result, e) -> { + if (e != null) { + log.error("Exception thrown", e); + latch.countDown(); + return e.getCause(); + } else { + return result; + } + }); + res.thenAccept(result -> assertEquals(TimeoutException.class, result)); + + log.debug( + "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis()); + latch.await(5, TimeUnit.SECONDS ); + assertEquals(0, latch.getCount()); + log.debug("All requests have been completed. Exiting test."); + } + + @Test + public void givenMultigigabyteResponseConsumeWithStreams() throws Exception { + CountDownLatch latch = new CountDownLatch(1); + final ActorSystem system = ActorSystem.create(); + final ActorMaterializer materializer = ActorMaterializer.create(system); + final Path path = Files.createTempFile("tmp_", ".out"); + + WSClient ws = play.test.WSTestClient.newClient(port); + log.info("Starting test server on url: " + url); + ws.url(url) + .stream() + .thenAccept( + response -> { + try { + OutputStream outputStream = java.nio.file.Files.newOutputStream(path); + Sink> outputWriter = + Sink.foreach(bytes -> { + log.info("Reponse: " + bytes.utf8String()); + outputStream.write(bytes.toArray()); + }); + + response.getBodyAsSource() + .runWith(outputWriter, materializer); + + } catch (IOException e) { + log.error("An error happened while opening the output stream", e); + } + }) + .whenComplete((value, error) -> latch.countDown()); + + log.debug( + "Waiting for requests to be completed. Current Time: " + System.currentTimeMillis()); + latch.await(5, TimeUnit.SECONDS ); + assertEquals(0, latch.getCount()); + log.debug("All requests have been completed. Exiting test."); + } +} From 0df2b1bb4b8daf2e99630fa6635182434d684aaf Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Tue, 25 Feb 2020 05:10:42 +0100 Subject: [PATCH 60/62] BAEL-3491 - Check for null before calling parse in the Double.parseDouble (#8752) * BAEL-3491 - Check for null before calling parse in the Double.parseDouble * BAEL-3491 - Check for null before calling parse in the Double.parseDouble - Return to indentation with spaces. --- java-numbers-3/pom.xml | 26 ++- .../StringToDoubleParserUnitTest.java | 149 ++++++++++++++++++ 2 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 java-numbers-3/src/test/java/com/baeldung/parsedouble/StringToDoubleParserUnitTest.java diff --git a/java-numbers-3/pom.xml b/java-numbers-3/pom.xml index bf5fe9b0e7..495618885a 100644 --- a/java-numbers-3/pom.xml +++ b/java-numbers-3/pom.xml @@ -12,15 +12,32 @@ 0.0.1-SNAPSHOT ../parent-java - + - + it.unimi.dsi dsiutils ${dsiutils.version} + + io.vavr + vavr + ${vavr.version} + + + org.apache.commons + commons-lang3 + ${commons.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + - + java-numbers-3 @@ -33,6 +50,9 @@ 2.6.0 + 0.10.2 + 3.9 + 3.6.1 diff --git a/java-numbers-3/src/test/java/com/baeldung/parsedouble/StringToDoubleParserUnitTest.java b/java-numbers-3/src/test/java/com/baeldung/parsedouble/StringToDoubleParserUnitTest.java new file mode 100644 index 0000000000..b3dec3d14f --- /dev/null +++ b/java-numbers-3/src/test/java/com/baeldung/parsedouble/StringToDoubleParserUnitTest.java @@ -0,0 +1,149 @@ +package com.baeldung.parsedouble; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.apache.commons.lang3.math.NumberUtils; +import org.junit.Test; + +import com.google.common.base.MoreObjects; +import com.google.common.primitives.Doubles; + +import io.vavr.control.Try; + +public class StringToDoubleParserUnitTest { + + @Test + public void givenNullValue_whenParseStringToDouble_thenDefaultNaNValueIsReturned() { + assertThat(parseStringToDouble(null)).isNaN(); + } + + @Test + public void givenEmptyStringValue_whenParseStringToDouble_thenDefaultNaNValueIsReturned() { + assertThat(parseStringToDouble("")).isNaN(); + } + + @Test + public void givenStringValue_whenParseStringToDouble_thenDoubleValueIsReturned() { + assertThat(parseStringToDouble("1")).isEqualTo(1.0d); + } + + @Test + public void givenStringValue_whenParseStringToDoubleWithDefault_thenDoubleValueIsReturned() { + assertThat(parseStringToDouble("1", 2.0d)).isEqualTo(1.0d); + } + + @Test + public void givenEmptyStringValue_whenParseStringToDoubleWithDefault_thenDefaultValueIsReturned() { + assertThat(parseStringToDouble("", 1.0d)).isEqualTo(1.0d); + } + + @Test + public void givenNullValue_whenParseStringToDoubleWithDefault_thenDefaultValueIsReturned() { + assertThat(parseStringToDouble(null, 1.0d)).isEqualTo(1.0d); + } + + @Test + public void givenStringValue_whenParseStringToOptionalDouble_thenOptionalValueIsReturned() { + assertThat(parseStringToOptionalDouble("1")).isEqualTo(Optional.of(1.0d)); + } + + @Test + public void givenNullValue_whenParseStringToOptionalDouble_thenOptionalValueIsEmpty() { + assertThat(parseStringToOptionalDouble(null)).isEqualTo(Optional.empty()); + } + + @Test + public void givenEmptyStringValue_whenParseStringToOptionalDouble_thenOptionalValueIsEmpty() { + assertThat(parseStringToOptionalDouble("")).isEqualTo(Optional.empty()); + } + + @Test + public void givenEmptyStringValue_whenParseStringToOptionalDouble_thenDefaulOptionalValueIsReturned() { + assertThat(parseStringToOptionalDouble("").orElse(1.0d)).isEqualTo(1.0d); + } + + @Test + public void givenNullValue_whenParseStringToOptionalDouble_thenDefaulOptionalValueIsReturned() { + assertThat(parseStringToOptionalDouble(null).orElse(1.0d)).isEqualTo(1.0d); + } + + @Test + public void givenStringValue_whenTryStringToDouble_thenDoubleValueIsReturned() { + assertThat(tryStringToDouble("1", 2.0d)).isEqualTo(1.0d); + } + + @Test + public void givenNullValue_whenTryStringToDoubleWithDefault_thenDoubleValueIsReturned() { + assertThat(tryStringToDouble(null, 2.0d)).isEqualTo(2.0d); + } + + @Test + public void givenEmptyStringValue_whenTryStringToDoubleWithDefault_thenDoubleValueIsReturned() { + assertThat(tryStringToDouble("", 2.0d)).isEqualTo(2.0d); + } + + @Test + public void givenTwoStringValues_whenTryParseFirstNonNull_thenDoubleValueIsReturned() { + assertThat(Doubles.tryParse(MoreObjects.firstNonNull("1.0", "2.0"))).isEqualTo(1.0d); + } + + @Test + public void givenNullStringValue_whenTryParseFirstNonNull_thenSecondDoubleValueIsReturned() { + assertThat(Doubles.tryParse(MoreObjects.firstNonNull(null, "2.0"))).isEqualTo(2.0d); + } + + @Test + public void givenEmptyStringValue_whenTryParseFirstNonNull_thenNullIsReturned() { + assertThat(Doubles.tryParse(MoreObjects.firstNonNull("", "2.0"))).isEqualTo(null); + } + + @Test + public void givenStringValue_whenToDouble_thenDoubleValueIsReturned() { + assertThat(NumberUtils.toDouble("1.0")).isEqualTo(1.0d); + } + + @Test + public void givenNullValue_whenToDouble_thenLibraryDefaultDoubleValueIsReturned() { + String nullString = null; + assertThat(NumberUtils.toDouble(nullString)).isEqualTo(0.0d); + } + + @Test + public void givenEmptyStringValue_whenToDouble_thenLibraryDefaultDoubleValueIsReturned() { + assertThat(NumberUtils.toDouble("")).isEqualTo(0.0d); + } + + @Test + public void givenEmptyStringValue_whenToDoubleWithDefault_thenDoubleValueIsReturned() { + assertThat(NumberUtils.toDouble("", 2.0d)).isEqualTo(2.0d); + } + + @Test + public void givenNullValue_whenToDoubleWithDefault_thenDoubleValueIsReturned() { + String nullString = null; + assertThat(NumberUtils.toDouble(nullString, 2.0d)).isEqualTo(2.0d); + } + + @Test + public void givenStringValue_whenToDoubleWithDefault_thenDoubleValueIsReturned() { + assertThat(NumberUtils.toDouble("1.0", 2.0d)).isEqualTo(1.0d); + } + + private static Optional parseStringToOptionalDouble(String value) { + return value == null || value.isEmpty() ? Optional.empty() : Optional.of(Double.valueOf(value)); + } + + private static double parseStringToDouble(String value) { + return value == null || value.isEmpty() ? Double.NaN : Double.parseDouble(value); + } + + private static double parseStringToDouble(String value, double defaultValue) { + return value == null || value.isEmpty() ? defaultValue : Double.parseDouble(value); + } + + private static double tryStringToDouble(String value, double defaultValue) { + return Try.of(() -> Double.parseDouble(value)).getOrElse(defaultValue); + } +} From 8073a286b0385f64e504ed55e260b08ee5e01858 Mon Sep 17 00:00:00 2001 From: Mathieu Fortin Date: Tue, 25 Feb 2020 20:24:42 -0500 Subject: [PATCH 61/62] BAEL-3337 main code + live tests (#8777) --- .../ExponentialBackoffApp.java | 11 ++ ...servableRejectAndDontRequeueRecoverer.java | 21 +++ .../RabbitConfiguration.java | 162 ++++++++++++++++++ .../exponentialbackoff/RetryQueues.java | 34 ++++ .../RetryQueuesInterceptor.java | 109 ++++++++++++ .../ExponentialBackoffLiveTest.java | 58 +++++++ .../src/test/resources/logback-test.xml | 6 + 7 files changed, 401 insertions(+) create mode 100644 spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffApp.java create mode 100644 spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ObservableRejectAndDontRequeueRecoverer.java create mode 100644 spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RabbitConfiguration.java create mode 100644 spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueues.java create mode 100644 spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueuesInterceptor.java create mode 100644 spring-amqp/src/test/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffLiveTest.java create mode 100644 spring-amqp/src/test/resources/logback-test.xml diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffApp.java b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffApp.java new file mode 100644 index 0000000000..182880cc7e --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffApp.java @@ -0,0 +1,11 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ExponentialBackoffApp { + public static void main(String[] args) { + SpringApplication.run(ExponentialBackoffApp.class, args); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ObservableRejectAndDontRequeueRecoverer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ObservableRejectAndDontRequeueRecoverer.java new file mode 100644 index 0000000000..700f7ab725 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/ObservableRejectAndDontRequeueRecoverer.java @@ -0,0 +1,21 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer; + +public class ObservableRejectAndDontRequeueRecoverer extends RejectAndDontRequeueRecoverer { + private Runnable observer; + + @Override + public void recover(Message message, Throwable cause) { + if(observer != null) { + observer.run(); + } + + super.recover(message, cause); + } + + void setObserver(Runnable observer){ + this.observer = observer; + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RabbitConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RabbitConfiguration.java new file mode 100644 index 0000000000..2335ecbf58 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RabbitConfiguration.java @@ -0,0 +1,162 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import org.aopalliance.aop.Advice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.AmqpAdmin; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.core.MessageProperties; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.amqp.rabbit.annotation.EnableRabbit; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder; +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitAdmin; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.retry.interceptor.RetryOperationsInterceptor; + +import com.rabbitmq.client.Channel; + +@EnableRabbit +@Configuration +public class RabbitConfiguration { + + private static Logger logger = LoggerFactory.getLogger(RabbitConfiguration.class); + + @Bean + public ConnectionFactory connectionFactory() { + return new CachingConnectionFactory("localhost"); + } + + @Bean + public AmqpAdmin amqpAdmin() { + return new RabbitAdmin(connectionFactory()); + } + + @Bean + public RabbitTemplate rabbitTemplate() { + return new RabbitTemplate(connectionFactory()); + } + + @Bean + public Queue blockingQueue() { + return QueueBuilder.nonDurable("blocking-queue") + .build(); + } + + @Bean + public Queue nonBlockingQueue() { + return QueueBuilder.nonDurable("non-blocking-queue") + .build(); + } + + @Bean + public Queue retryWaitEndedQueue() { + return QueueBuilder.nonDurable("retry-wait-ended-queue") + .build(); + } + + @Bean + public Queue retryQueue1() { + return QueueBuilder.nonDurable("retry-queue-1") + .deadLetterExchange("") + .deadLetterRoutingKey("retry-wait-ended-queue") + .build(); + } + + @Bean + public Queue retryQueue2() { + return QueueBuilder.nonDurable("retry-queue-2") + .deadLetterExchange("") + .deadLetterRoutingKey("retry-wait-ended-queue") + .build(); + } + + @Bean + public Queue retryQueue3() { + return QueueBuilder.nonDurable("retry-queue-3") + .deadLetterExchange("") + .deadLetterRoutingKey("retry-wait-ended-queue") + .build(); + } + + @Bean + public RetryQueues retryQueues() { + return new RetryQueues(1000, 3.0, 10000, retryQueue1(), retryQueue2(), retryQueue3()); + } + + @Bean + public ObservableRejectAndDontRequeueRecoverer observableRecoverer() { + return new ObservableRejectAndDontRequeueRecoverer(); + } + + @Bean + public RetryOperationsInterceptor retryInterceptor() { + return RetryInterceptorBuilder.stateless() + .backOffOptions(1000, 3.0, 10000) + .maxAttempts(5) + .recoverer(observableRecoverer()) + .build(); + } + + @Bean + public RetryQueuesInterceptor retryQueuesInterceptor(RabbitTemplate rabbitTemplate, RetryQueues retryQueues) { + return new RetryQueuesInterceptor(rabbitTemplate, retryQueues); + } + + @Bean + public SimpleRabbitListenerContainerFactory defaultContainerFactory(ConnectionFactory connectionFactory) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + factory.setConnectionFactory(connectionFactory); + + return factory; + } + + @Bean + public SimpleRabbitListenerContainerFactory retryContainerFactory(ConnectionFactory connectionFactory, RetryOperationsInterceptor retryInterceptor) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + factory.setConnectionFactory(connectionFactory); + + Advice[] adviceChain = { retryInterceptor }; + factory.setAdviceChain(adviceChain); + + return factory; + } + + @Bean + public SimpleRabbitListenerContainerFactory retryQueuesContainerFactory(ConnectionFactory connectionFactory, RetryQueuesInterceptor retryInterceptor) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + factory.setConnectionFactory(connectionFactory); + + Advice[] adviceChain = { retryInterceptor }; + factory.setAdviceChain(adviceChain); + + return factory; + } + + @RabbitListener(queues = "blocking-queue", containerFactory = "retryContainerFactory") + public void consumeBlocking(String payload) throws Exception { + logger.info("Processing message from blocking-queue: {}", payload); + + throw new Exception("exception occured!"); + } + + @RabbitListener(queues = "non-blocking-queue", containerFactory = "retryQueuesContainerFactory", ackMode = "MANUAL") + public void consumeNonBlocking(String payload) throws Exception { + logger.info("Processing message from non-blocking-queue: {}", payload); + + throw new Exception("Error occured!"); + } + + @RabbitListener(queues = "retry-wait-ended-queue", containerFactory = "defaultContainerFactory") + public void consumeRetryWaitEndedMessage(String payload, Message message, Channel channel) throws Exception { + MessageProperties props = message.getMessageProperties(); + + rabbitTemplate().convertAndSend(props.getHeader("x-original-exchange"), props.getHeader("x-original-routing-key"), message); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueues.java b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueues.java new file mode 100644 index 0000000000..f52415b3e6 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueues.java @@ -0,0 +1,34 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import org.springframework.amqp.core.Queue; + +public class RetryQueues { + private Queue[] queues; + private long initialInterval; + private double factor; + private long maxWait; + + public RetryQueues(long initialInterval, double factor, long maxWait, Queue... queues) { + this.queues = queues; + this.initialInterval = initialInterval; + this.factor = factor; + this.maxWait = maxWait; + } + + public boolean retriesExhausted(int retry) { + return retry >= queues.length; + } + + public String getQueueName(int retry) { + return queues[retry].getName(); + } + + public long getTimeToWait(int retry) { + double time = initialInterval * Math.pow(factor, (double) retry); + if (time > maxWait) { + return maxWait; + } + + return (long) time; + } +} \ No newline at end of file diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueuesInterceptor.java b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueuesInterceptor.java new file mode 100644 index 0000000000..f09a71df7c --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/exponentialbackoff/RetryQueuesInterceptor.java @@ -0,0 +1,109 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import com.rabbitmq.client.Channel; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.core.MessageProperties; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +public class RetryQueuesInterceptor implements MethodInterceptor { + + private RabbitTemplate rabbitTemplate; + + private RetryQueues retryQueues; + + private Runnable observer; + + public RetryQueuesInterceptor(RabbitTemplate rabbitTemplate, RetryQueues retryQueues) { + this.rabbitTemplate = rabbitTemplate; + this.retryQueues = retryQueues; + } + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + return tryConsume(invocation, this::ack, (mac, e) -> { + try { + int retryCount = tryGetRetryCountOrFail(mac, e); + sendToNextRetryQueue(mac, retryCount); + } catch (Throwable t) { + if (observer != null) { + observer.run(); + } + + throw new RuntimeException(t); + } + }); + } + + void setObserver(Runnable observer) { + this.observer = observer; + } + + private Object tryConsume(MethodInvocation invocation, Consumer successHandler, BiConsumer errorHandler) throws Throwable { + MessageAndChannel mac = new MessageAndChannel((Message) invocation.getArguments()[1], (Channel) invocation.getArguments()[0]); + Object ret = null; + try { + ret = invocation.proceed(); + successHandler.accept(mac); + } catch (Throwable e) { + errorHandler.accept(mac, e); + } + return ret; + } + + private void ack(MessageAndChannel mac) { + try { + mac.channel.basicAck(mac.message.getMessageProperties() + .getDeliveryTag(), false); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private int tryGetRetryCountOrFail(MessageAndChannel mac, Throwable originalError) throws Throwable { + MessageProperties props = mac.message.getMessageProperties(); + + String xRetriedCountHeader = (String) props.getHeader("x-retried-count"); + final int xRetriedCount = xRetriedCountHeader == null ? 0 : Integer.valueOf(xRetriedCountHeader); + + if (retryQueues.retriesExhausted(xRetriedCount)) { + mac.channel.basicReject(props.getDeliveryTag(), false); + + throw originalError; + } + + return xRetriedCount; + } + + private void sendToNextRetryQueue(MessageAndChannel mac, int retryCount) throws Exception { + String retryQueueName = retryQueues.getQueueName(retryCount); + + rabbitTemplate.convertAndSend(retryQueueName, mac.message, m -> { + MessageProperties props = m.getMessageProperties(); + props.setExpiration(String.valueOf(retryQueues.getTimeToWait(retryCount))); + props.setHeader("x-retried-count", String.valueOf(retryCount + 1)); + props.setHeader("x-original-exchange", props.getReceivedExchange()); + props.setHeader("x-original-routing-key", props.getReceivedRoutingKey()); + + return m; + }); + + mac.channel.basicReject(mac.message.getMessageProperties() + .getDeliveryTag(), false); + } + + private class MessageAndChannel { + private Message message; + private Channel channel; + + private MessageAndChannel(Message message, Channel channel) { + this.message = message; + this.channel = channel; + } + } +} \ No newline at end of file diff --git a/spring-amqp/src/test/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffLiveTest.java b/spring-amqp/src/test/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffLiveTest.java new file mode 100644 index 0000000000..04bd463a72 --- /dev/null +++ b/spring-amqp/src/test/java/com/baeldung/springamqp/exponentialbackoff/ExponentialBackoffLiveTest.java @@ -0,0 +1,58 @@ +package com.baeldung.springamqp.exponentialbackoff; + +import java.util.concurrent.CountDownLatch; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * This live test requires: + * + * - A running RabbitMQ instance on localhost (e.g. docker run -p 5672:5672 -p 15672:15672 --name rabbit rabbitmq:3-management) + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { RabbitConfiguration.class }) +public class ExponentialBackoffLiveTest { + + @Autowired + private RabbitTemplate rabbitTemplate; + + @Autowired + private ObservableRejectAndDontRequeueRecoverer observableRecoverer; + + @Autowired + private RetryQueuesInterceptor retryQueues; + + @Test + public void whenSendToBlockingQueue_thenAllMessagesProcessed() throws Exception { + int nb = 2; + + CountDownLatch latch = new CountDownLatch(nb); + observableRecoverer.setObserver(() -> latch.countDown()); + + for (int i = 1; i <= nb; i++) { + rabbitTemplate.convertAndSend("blocking-queue", "blocking message " + i); + } + + latch.await(); + } + + @Test + public void whenSendToNonBlockingQueue_thenAllMessageProcessed() throws Exception { + int nb = 2; + + CountDownLatch latch = new CountDownLatch(nb); + retryQueues.setObserver(() -> latch.countDown()); + + for (int i = 1; i <= nb; i++) { + rabbitTemplate.convertAndSend("non-blocking-queue", "non-blocking message " + i); + } + + latch.await(); + } +} diff --git a/spring-amqp/src/test/resources/logback-test.xml b/spring-amqp/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..7eba9aea8b --- /dev/null +++ b/spring-amqp/src/test/resources/logback-test.xml @@ -0,0 +1,6 @@ + + + + + From 2db083ad630e75fc204c2b7b18793197e8b883c3 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Tue, 25 Feb 2020 19:46:20 -0600 Subject: [PATCH 62/62] SCALA-38: move to new package and update README (#8773) * BAEL-3336 BAEL-3058 add links * BAEL-3319: add link * BAEL-3284: add link * BAEL-3198: add link to article * BAEL-3479: add link to article * BAEL-3485: add article link * SCALA-38: move to new package and add link back to article * SCALA-38: add imports back into unit test --- core-scala/README.md | 1 + .../scala/com/baeldung/scala/{ => regex}/RegexUnitTest.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename core-scala/src/test/scala/com/baeldung/scala/{ => regex}/RegexUnitTest.scala (98%) diff --git a/core-scala/README.md b/core-scala/README.md index e6fc75d59e..13929ff721 100644 --- a/core-scala/README.md +++ b/core-scala/README.md @@ -5,3 +5,4 @@ This module contains articles about Scala's core features ### Relevant Articles: - [Introduction to Scala](https://www.baeldung.com/scala-intro) +- [Regular Expressions in Scala](https://www.baeldung.com/scala/regular-expressions) diff --git a/core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala b/core-scala/src/test/scala/com/baeldung/scala/regex/RegexUnitTest.scala similarity index 98% rename from core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala rename to core-scala/src/test/scala/com/baeldung/scala/regex/RegexUnitTest.scala index 94263d620a..27ed9e1172 100644 --- a/core-scala/src/test/scala/com/baeldung/scala/RegexUnitTest.scala +++ b/core-scala/src/test/scala/com/baeldung/scala/regex/RegexUnitTest.scala @@ -1,4 +1,4 @@ -package com.baeldung.scala +package com.baeldung.scala.regex import org.junit.Test import org.junit.Assert.assertEquals