diff --git a/axon/pom.xml b/axon/pom.xml index 32f12f8c43..ae199d27f9 100644 --- a/axon/pom.xml +++ b/axon/pom.xml @@ -71,7 +71,7 @@ - 4.5.17 + 4.6.0 \ No newline at end of file diff --git a/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java b/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java index 9901f725fd..64058d5eca 100644 --- a/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java +++ b/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java @@ -92,6 +92,11 @@ public class OrderRestEndpoint { return orderQueryService.findAllOrders(); } + @GetMapping(path = "/all-orders-streaming", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux allOrdersStreaming() { + return orderQueryService.allOrdersStreaming(); + } + @GetMapping("/total-shipped/{product-id}") public Integer totalShipped(@PathVariable("product-id") String productId) { return orderQueryService.totalShipped(productId); diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java b/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java index 202b48abfd..fbdf819961 100644 --- a/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java +++ b/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java @@ -17,7 +17,10 @@ import org.axonframework.config.ProcessingGroup; import org.axonframework.eventhandling.EventHandler; import org.axonframework.queryhandling.QueryHandler; import org.axonframework.queryhandling.QueryUpdateEmitter; +import org.reactivestreams.Publisher; import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import java.util.ArrayList; import java.util.HashMap; @@ -101,6 +104,11 @@ public class InMemoryOrdersEventHandler implements OrdersEventHandler { return new ArrayList<>(orders.values()); } + @QueryHandler + public Publisher handleStreaming(FindAllOrderedProductsQuery query) { + return Mono.fromCallable(orders::values).flatMapMany(Flux::fromIterable); + } + @QueryHandler public Integer handle(TotalProductsShippedQuery query) { return orders.values() diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java b/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java index 192fc78226..ae391c3cb1 100644 --- a/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java +++ b/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java @@ -9,6 +9,7 @@ import org.axonframework.messaging.responsetypes.ResponseType; import org.axonframework.messaging.responsetypes.ResponseTypes; import org.axonframework.queryhandling.QueryGateway; import org.axonframework.queryhandling.SubscriptionQueryResult; +import org.reactivestreams.Publisher; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; @@ -34,6 +35,11 @@ public class OrderQueryService { .collect(Collectors.toList())); } + public Flux allOrdersStreaming() { + Publisher publisher = queryGateway.streamingQuery(new FindAllOrderedProductsQuery(), Order.class); + return Flux.from(publisher).map(OrderResponse::new); + } + public Integer totalShipped(String productId) { return queryGateway.scatterGather(new TotalProductsShippedQuery(productId), ResponseTypes.instanceOf(Integer.class), 10L, TimeUnit.SECONDS) diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java b/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java index 0d4aad4c97..7e49abf93b 100644 --- a/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java +++ b/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java @@ -11,6 +11,7 @@ import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery; import com.baeldung.axon.coreapi.queries.Order; import com.baeldung.axon.coreapi.queries.OrderUpdatesQuery; import com.baeldung.axon.coreapi.queries.TotalProductsShippedQuery; +import org.reactivestreams.Publisher; import java.util.List; @@ -32,6 +33,8 @@ public interface OrdersEventHandler { List handle(FindAllOrderedProductsQuery query); + Publisher handleStreaming(FindAllOrderedProductsQuery query); + Integer handle(TotalProductsShippedQuery query); Order handle(OrderUpdatesQuery query); diff --git a/axon/src/main/resources/order-api.http b/axon/src/main/resources/order-api.http index d5f358cbb9..bd2a4289ab 100644 --- a/axon/src/main/resources/order-api.http +++ b/axon/src/main/resources/order-api.http @@ -10,6 +10,10 @@ POST http://localhost:8080/ship-unconfirmed-order GET http://localhost:8080/all-orders +### Receive all existing orders using a stream + +GET http://localhost:8080/all-orders-streaming + ### Create Order with id 666a1661-474d-4046-8b12-8b5896312768 POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768 diff --git a/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java b/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java index daef0b684d..2396d0f10b 100644 --- a/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java +++ b/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java @@ -14,10 +14,13 @@ import com.baeldung.axon.coreapi.queries.OrderUpdatesQuery; import com.baeldung.axon.coreapi.queries.TotalProductsShippedQuery; import org.axonframework.queryhandling.QueryUpdateEmitter; import org.junit.jupiter.api.*; +import reactor.core.publisher.Flux; +import reactor.test.StepVerifier; import java.util.Arrays; import java.util.List; import java.util.UUID; +import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -68,6 +71,26 @@ public abstract class AbstractOrdersEventHandlerUnitTest { assertEquals(orderTwo, order_2); } + @Test + void givenTwoOrdersPlacedOfWhichOneNotShipped_whenFindAllOrderedProductsQueryStreaming_thenCorrectOrdersAreReturned() { + resetWithTwoOrders(); + final Consumer orderVerifier = order -> { + if (order.getOrderId().equals(orderOne.getOrderId())) { + assertEquals(orderOne, order); + } else if (order.getOrderId().equals(orderTwo.getOrderId())) { + assertEquals(orderTwo, order); + } else { + throw new RuntimeException("Would expect either order one or order two"); + } + }; + + StepVerifier.create(Flux.from(handler.handleStreaming(new FindAllOrderedProductsQuery()))) + .assertNext(orderVerifier) + .assertNext(orderVerifier) + .expectComplete() + .verify(); + } + @Test void givenNoOrdersPlaced_whenTotalProductsShippedQuery_thenZeroReturned() { assertEquals(0, handler.handle(new TotalProductsShippedQuery(PRODUCT_ID_1))); diff --git a/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java b/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java index 60808b2271..dfb4881fdc 100644 --- a/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java +++ b/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java @@ -6,6 +6,7 @@ import com.baeldung.axon.coreapi.events.OrderShippedEvent; import com.baeldung.axon.coreapi.events.ProductAddedEvent; import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent; import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent; +import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery; import com.baeldung.axon.coreapi.queries.Order; import org.axonframework.eventhandling.gateway.EventGateway; @@ -13,6 +14,7 @@ import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import reactor.core.publisher.Flux; import reactor.test.StepVerifier; import java.util.Collections; @@ -60,6 +62,15 @@ class OrderQueryServiceIntegrationTest { .isEmpty()); } + @Test + void givenOrderCreatedEventSend_whenCallingAllOrdersStreaming_thenOneOrderIsReturned() { + Flux result = queryService.allOrdersStreaming(); + StepVerifier.create(result) + .assertNext(order -> assertEquals(orderId, order.getOrderId())) + .expectComplete() + .verify(); + } + @Test void givenThreeDeluxeChairsShipped_whenCallingAllShippedChairs_then234PlusTreeIsReturned() { Order order = new Order(orderId); diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java new file mode 100644 index 0000000000..c57c1f96b8 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.listandset; + +import org.junit.Test; +import org.junit.Assert; +import java.util.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ListAndSetUnitTest { + + @Test + public void givenList_whenDuplicates_thenAllowed(){ + List integerList = new ArrayList<>(); + integerList.add(2); + integerList.add(3); + integerList.add(4); + integerList.add(4); + assertEquals(integerList.size(), 4); + } + + @Test + public void givenSet_whenDuplicates_thenNotAllowed(){ + Set integerSet = new HashSet<>(); + integerSet.add(2); + integerSet.add(3); + integerSet.add(4); + integerSet.add(4); + assertEquals(integerSet.size(), 3); + } + + @Test + public void givenSet_whenOrdering_thenMayBeAllowed(){ + Set set1 = new LinkedHashSet<>(); + set1.add(2); + set1.add(3); + set1.add(4); + Set set2 = new LinkedHashSet<>(); + set2.add(2); + set2.add(3); + set2.add(4); + Assert.assertArrayEquals(set1.toArray(), set2.toArray()); + } +} diff --git a/core-java-modules/core-java-collections-list-4/pom.xml b/core-java-modules/core-java-collections-list-4/pom.xml index 773f8c105b..49b3f849d4 100644 --- a/core-java-modules/core-java-collections-list-4/pom.xml +++ b/core-java-modules/core-java-collections-list-4/pom.xml @@ -56,6 +56,12 @@ ${assertj.version} test + + org.springframework + spring-core + ${spring.version} + test + @@ -80,6 +86,7 @@ 3.22.0 17 17 + 5.3.22 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java new file mode 100644 index 0000000000..479ccaf92f --- /dev/null +++ b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java @@ -0,0 +1,132 @@ +package com.baeldung.list.tostring; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +class ListToStringUnitTest { + + @Test + void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingString() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + String commaSeparatedString = String.join(",", arraysAsList); + + assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE"); + } + + @Test + void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingStringJoiner() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + StringJoiner stringJoiner = new StringJoiner(","); + arraysAsList.stream() + .forEach(v -> stringJoiner.add(v)); + String commaSeparatedString = stringJoiner.toString(); + + assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE"); + + StringJoiner stringJoinerWithDelimiterPrefixSuffix = new StringJoiner(",", "[", "]"); + arraysAsList.stream() + .forEach(v -> stringJoinerWithDelimiterPrefixSuffix.add(v)); + String commaSeparatedStringWithDelimiterPrefixSuffix = stringJoinerWithDelimiterPrefixSuffix.toString(); + + assertThat(commaSeparatedStringWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]"); + } + + @Test + void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingCollectors() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + String commaSeparatedUsingCollect = arraysAsList.stream() + .collect(Collectors.joining(",")); + + assertThat(commaSeparatedUsingCollect).isEqualTo("ONE,TWO,THREE"); + + String commaSeparatedObjectToString = arraysAsList.stream() + .map(Object::toString) + .collect(Collectors.joining(",")); + + assertThat(commaSeparatedObjectToString).isEqualTo("ONE,TWO,THREE"); + + String commaSeparatedStringValueOf = arraysAsList.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + + assertThat(commaSeparatedStringValueOf).isEqualTo("ONE,TWO,THREE"); + + String commaSeparatedStringValueOfWithDelimiterPrefixSuffix = arraysAsList.stream() + .map(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + + assertThat(commaSeparatedStringValueOfWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]"); + + String commaSeparatedUsingReduce = arraysAsList.stream() + .reduce((x, y) -> x + "," + y) + .get(); + + assertThat(commaSeparatedUsingReduce).isEqualTo("ONE,TWO,THREE"); + } + + @Test + void givenAListOfString_whenUsingApacheCommonsLang_thenConvertToStringByUsingStringUtils() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + String commaSeparatedString = org.apache.commons.lang3.StringUtils.join(arraysAsList, ","); + + assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE"); + + String commaSeparatedStringIndex = org.apache.commons.lang3.StringUtils.join(arraysAsList.toArray(), ",", 0, 3); + + assertThat(commaSeparatedStringIndex).isEqualTo("ONE,TWO,THREE"); + } + + @Test + void givenAListOfString_whenUsingSpringCore_thenConvertToStringByUsingStringUtils() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + String collectionToCommaDelimitedString = org.springframework.util.StringUtils.collectionToCommaDelimitedString(arraysAsList); + + assertThat(collectionToCommaDelimitedString).isEqualTo("ONE,TWO,THREE"); + + String collectionToDelimitedString = org.springframework.util.StringUtils.collectionToDelimitedString(arraysAsList, ","); + + assertThat(collectionToDelimitedString).isEqualTo("ONE,TWO,THREE"); + } + + @Test + void givenAListOfString_whenUsingGoogleGuava_thenConvertToStringByUsingJoiner() { + + List arraysAsList = Arrays.asList("ONE", "TWO", "THREE"); + + String commaSeparatedString = com.google.common.base.Joiner.on(",") + .join(arraysAsList); + + assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE"); + + List arraysAsListWithNull = Arrays.asList("ONE", null, "TWO", null, "THREE"); + + String commaSeparatedStringSkipNulls = com.google.common.base.Joiner.on(",") + .skipNulls() + .join(arraysAsListWithNull); + + assertThat(commaSeparatedStringSkipNulls).isEqualTo("ONE,TWO,THREE"); + + String commaSeparatedStringUseForNull = com.google.common.base.Joiner.on(",") + .useForNull(" ") + .join(arraysAsListWithNull); + + assertThat(commaSeparatedStringUseForNull).isEqualTo("ONE, ,TWO, ,THREE"); + } + +} diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 7c3146d32b..cc84760560 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -3,4 +3,5 @@ This module contains articles about date operations in Java. ### Relevant Articles: +- [Create Date From Unix Timestamp in Java](https://www.baeldung.com/java-date-unix-timestamp) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) diff --git a/core-java-modules/core-java-function/README.md b/core-java-modules/core-java-function/README.md index 7fe6044835..eb27aea153 100644 --- a/core-java-modules/core-java-function/README.md +++ b/core-java-modules/core-java-function/README.md @@ -5,3 +5,4 @@ ### Relevant Articles: - [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain) - [Use Cases for Static Methods in Java](https://www.baeldung.com/java-static-methods-use-cases) +- [TriFunction Interface in Java](https://www.baeldung.com/java-trifunction) diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md index 27a71cb2a2..fdf9ebcb77 100644 --- a/core-java-modules/core-java-io-4/README.md +++ b/core-java-modules/core-java-io-4/README.md @@ -11,4 +11,5 @@ This module contains articles about core Java input and output (IO) - [Read User Input Until a Condition is Met](https://www.baeldung.com/java-read-input-until-condition) - [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip) - [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file) +- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path) - [[<-- Prev]](/core-java-modules/core-java-io-3) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 93307f8294..f3d72fe8b5 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -4,3 +4,4 @@ This module contains articles about core Java input/output(IO) APIs. ### Relevant Articles: - [Constructing a Relative Path From Two Absolute Paths in Java](https://www.baeldung.com/java-relative-path-absolute) +- [Java Scanner Taking a Character Input](https://www.baeldung.com/java-scanner-character-input) diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index 48af72a036..3c1e1d79ee 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -7,4 +7,5 @@ - [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string) - [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables) - [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation/) +- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java new file mode 100644 index 0000000000..9220472cad --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java @@ -0,0 +1,51 @@ +package com.baeldung.portscanner; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class PortScanner { + private static final int poolSize = 10; + private static final int timeOut = 200; + + public void runPortScan(String ip, int nbrPortMaxToScan) throws IOException, RuntimeException { + ConcurrentLinkedQueue openPorts = new ConcurrentLinkedQueue<>(); + ExecutorService executorService = Executors.newFixedThreadPool(poolSize); + AtomicInteger port = new AtomicInteger(0); + while (port.get() < nbrPortMaxToScan) { + final int currentPort = port.getAndIncrement(); + executorService.submit(() -> { + try { + Socket socket = new Socket(); + socket.connect(new InetSocketAddress(ip, currentPort), timeOut); + socket.close(); + openPorts.add(currentPort); + System.out.println(ip + " ,port open: " + currentPort); + } catch (IOException e) { + System.err.println(e); + } + }); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10, TimeUnit.MINUTES); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + List openPortList = new ArrayList<>(); + System.out.println("openPortsQueue: " + openPorts.size()); + while (!openPorts.isEmpty()) { + openPortList.add(openPorts.poll()); + } + + openPortList.forEach(p -> System.out.println("port " + p + " is open")); + } +} diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java new file mode 100644 index 0000000000..2fc4ff7550 --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.portScanner; + +import com.baeldung.portscanner.PortScanner; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +class PortScannerUnitTest { + + private static final int nbrPortMax = 1000; // Max is 65535, number of available ports + private static final String ip = "127.0.0.1"; + PortScanner portScanner = new PortScanner(); + + @Test public void when_Run_then_lunchPortScan() throws IOException, RuntimeException { + portScanner.runPortScan(ip, nbrPortMax); + } +} diff --git a/core-java-modules/core-java-numbers-5/README.md b/core-java-modules/core-java-numbers-5/README.md index 19e155b525..714e808239 100644 --- a/core-java-modules/core-java-numbers-5/README.md +++ b/core-java-modules/core-java-numbers-5/README.md @@ -5,3 +5,4 @@ - [Armstrong Numbers in Java](https://www.baeldung.com/java-armstrong-numbers) - [List All Factors of a Number in Java](https://www.baeldung.com/java-list-factors-integer) - [Make Division of Two Integers Result in a Float](https://www.baeldung.com/java-integer-division-float-result) +- [Creating Random Numbers With No Duplicates in Java](https://www.baeldung.com/java-unique-random-numbers) diff --git a/core-java-modules/core-java-string-operations-5/README.md b/core-java-modules/core-java-string-operations-5/README.md index 7917fcf77b..71c28aac30 100644 --- a/core-java-modules/core-java-string-operations-5/README.md +++ b/core-java-modules/core-java-string-operations-5/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [Compare Characters in Java](https://www.baeldung.com/java-compare-characters) +- [String Concatenation in Java](https://www.baeldung.com/java-string-concatenation) diff --git a/core-java-modules/core-java-uuid/README.md b/core-java-modules/core-java-uuid/README.md index 836552d798..0a77c36acd 100644 --- a/core-java-modules/core-java-uuid/README.md +++ b/core-java-modules/core-java-uuid/README.md @@ -3,3 +3,4 @@ ### Relevant Articles: - [Generating Alphanumeric UUID String in Java](https://www.baeldung.com/java-generate-alphanumeric-uuid) - [Guide to UUID in Java](http://www.baeldung.com/java-uuid) +- [Validate UUID String in Java](https://www.baeldung.com/java-validate-uuid-string) diff --git a/docker-modules/docker-compose/README.md b/docker-modules/docker-compose/README.md index 7c3347332e..5ab629e54f 100644 --- a/docker-modules/docker-compose/README.md +++ b/docker-modules/docker-compose/README.md @@ -6,4 +6,5 @@ - [Difference Between links and depends_on in Docker Compose](https://www.baeldung.com/ops/docker-compose-links-depends-on) - [Mounting Multiple Volumes on a Docker Container](https://www.baeldung.com/ops/docker-mounting-multiple-volumes) - [Rebuild Docker Container in Docker Compose](https://www.baeldung.com/rebuild-docker-container-compose/) +- [Assign Static IP to Docker Container and Docker-Compose](https://www.baeldung.com/ops/docker-assign-static-ip-container) diff --git a/docker-modules/docker-images/README.md b/docker-modules/docker-images/README.md index 3b2ae6b56f..7813ec4279 100644 --- a/docker-modules/docker-images/README.md +++ b/docker-modules/docker-images/README.md @@ -3,3 +3,5 @@ - [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository) - [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context) - [Adding a Comment in a Dockerfile](https://www.baeldung.com/ops/docker-dockerfile-comments/) +- [Updating PATH Environment Variable in Dockerfile](https://www.baeldung.com/ops/dockerfile-path-environment-variable) +- [Keep Subdirectory Structure in Dockerfile Copy](https://www.baeldung.com/ops/dockerfile-copy-same-subdirectory-structure) diff --git a/docker-modules/docker-java-jar/README.md b/docker-modules/docker-java-jar/README.md index 73c8249e58..9b5aa501ee 100644 --- a/docker-modules/docker-java-jar/README.md +++ b/docker-modules/docker-java-jar/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [Dockerizing a Java Application](https://www.baeldung.com/java-dockerize-app) +- [Debugging an Application Running in Docker With IntelliJ IDEA](https://www.baeldung.com/docker-debug-app-with-intellij) diff --git a/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx b/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx new file mode 100644 index 0000000000..6cf79f230e --- /dev/null +++ b/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx @@ -0,0 +1,88 @@ + + + + + + false + true + false + + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + + + + + + + + http://localhost:3000 + GET + true + false + true + false + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + + diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index c268aeacc5..66548e45cb 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -24,8 +24,8 @@ - 5.3.22 - 5.6.0 + 5.3.23 + 5.7.3 1.5.10.RELEASE diff --git a/patterns-modules/design-patterns-architectural/README.md b/patterns-modules/design-patterns-architectural/README.md index bb11eea5e1..0f0e75afeb 100644 --- a/patterns-modules/design-patterns-architectural/README.md +++ b/patterns-modules/design-patterns-architectural/README.md @@ -4,3 +4,4 @@ - [DAO vs Repository Patterns](https://www.baeldung.com/java-dao-vs-repository) - [Difference Between MVC and MVP Patterns](https://www.baeldung.com/mvc-vs-mvp-pattern) - [The DTO Pattern (Data Transfer Object)](https://www.baeldung.com/java-dto-pattern) +- [SEDA With Spring Integration and Apache Camel](https://www.baeldung.com/spring-apache-camel-seda-integration) diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index 4bc7d8b663..56cb2fb1d0 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -8,3 +8,4 @@ - [JDBC Connection Status](https://www.baeldung.com/jdbc-connection-status) - [Get the Number of Rows in a ResultSet](https://www.baeldung.com/java-resultset-number-of-rows) - [Converting a JDBC ResultSet to JSON in Java](https://www.baeldung.com/java-jdbc-convert-resultset-to-json) +- [Guide to MicroStream](https://www.baeldung.com/microstream-intro) diff --git a/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java new file mode 100644 index 0000000000..e073a1ec88 --- /dev/null +++ b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java @@ -0,0 +1,157 @@ +package com.baeldung.mongo.insert; + +import com.mongodb.*; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.MongoDatabase; +import org.bson.Document; +import org.bson.conversions.Bson; + +import java.util.ArrayList; +import java.util.List; + +import static com.mongodb.client.model.Filters.eq; +import static com.mongodb.client.model.Filters.in; + +public class InsertArrayOperation { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + private static DB db; + private static DBCollection dbCollection; + private static String collectionName; + private static String databaseName; + + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + + databaseName = "baeldung"; + collectionName = "student"; + + database = mongoClient.getDatabase(databaseName); + collection = database.getCollection(collectionName); + + db = mongoClient.getDB(databaseName); + dbCollection = db.getCollection(collectionName); + } + } + + public static void insertSingleBsonDocumentWithStringArray() { + BasicDBList coursesList = new BasicDBList(); + coursesList.add("Chemistry"); + coursesList.add("Science"); + + DBObject student = new BasicDBObject().append("studentId", "STUD1") + .append("name", "Jim") + .append("age", 13) + .append("courses", coursesList); + + dbCollection.insert(student); + + Bson filter = eq("studentId", "STUD1"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + while (cursor.hasNext()) { + System.out.println(cursor.next()); + } + } + + public static void insertSingleDocumentWithStringArray() { + List coursesList = new ArrayList<>(); + coursesList.add("Science"); + coursesList.add("Geography"); + + Document student = new Document().append("studentId", "STUD2") + .append("name", "Sam") + .append("age", 13) + .append("courses", coursesList); + + collection.insertOne(student); + + Bson filter = eq("studentId", "STUD2"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + while (cursor.hasNext()) { + System.out.println(cursor.next()); + } + } + + public static void insertMultipleDocumentsWithStringArray() { + List coursesList1 = new ArrayList<>(); + coursesList1.add("Chemistry"); + coursesList1.add("Geography"); + + Document student1 = new Document().append("studentId", "STUD3") + .append("name", "Sarah") + .append("age", 12) + .append("courses", coursesList1); + + List coursesList2 = new ArrayList<>(); + coursesList2.add("Maths"); + coursesList2.add("History"); + + Document student2 = new Document().append("studentId", "STUD4") + .append("name", "Tom") + .append("age", 13) + .append("courses", coursesList2); + + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + collection.insertMany(students); + + Bson filter = in("studentId", "STUD3", "STUD4"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + while (cursor.hasNext()) { + System.out.println(cursor.next()); + } + } + + public static void insertSingleDocumentWithObjectArray() { + Document course1 = new Document().append("name", "C1") + .append("points", 5); + + Document course2 = new Document().append("name", "C2") + .append("points", 7); + + List coursesList = new ArrayList<>(); + coursesList.add(course1); + coursesList.add(course2); + + Document student = new Document().append("studentId", "STUD5") + .append("name", "Avin") + .append("age", 13) + .append("courses", coursesList); + + collection.insertOne(student); + + Bson filter = eq("studentId", "STUD5"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + while (cursor.hasNext()) { + System.out.println(cursor.next()); + } + } + + public static void main(String args[]) { + + setUp(); + + insertSingleBsonDocumentWithStringArray(); + + insertSingleDocumentWithStringArray(); + + insertMultipleDocumentsWithStringArray(); + + insertSingleDocumentWithObjectArray(); + } +} diff --git a/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java new file mode 100644 index 0000000000..a844a003f0 --- /dev/null +++ b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java @@ -0,0 +1,150 @@ +package com.baeldung.mongo.insert; + +import com.mongodb.*; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.MongoDatabase; +import org.bson.Document; +import org.bson.conversions.Bson; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static com.mongodb.client.model.Filters.eq; +import static com.mongodb.client.model.Filters.in; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class InsertArrayOperationLiveTest { + + private static MongoClient mongoClient; + private static MongoDatabase database; + private static MongoCollection collection; + private static DB db; + private static DBCollection dbCollection; + + @BeforeClass + public static void setUp() { + if (mongoClient == null) { + mongoClient = new MongoClient("localhost", 27017); + + database = mongoClient.getDatabase("baeldung"); + collection = database.getCollection("student"); + + db = mongoClient.getDB("baeldung"); + dbCollection = db.getCollection("student"); + + collection.drop(); + } + } + + @Test + public void givenSingleStudentObjectWithStringArray_whenInsertingDBObject_thenCheckingForDocument() { + BasicDBList coursesList = new BasicDBList(); + coursesList.add("Chemistry"); + coursesList.add("Science"); + + DBObject student = new BasicDBObject().append("studentId", "STUD1") + .append("name", "Jim") + .append("age", 13) + .append("courses", coursesList); + + dbCollection.insert(student); + + Bson filter = eq("studentId", "STUD2"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + + assertNotNull(cursor); + assertTrue(cursor.hasNext()); + } + + @Test + public void givenSingleStudentObjectWithStringArray_whenInsertingDocument_thenCheckingForDocument() { + List coursesList = new ArrayList<>(); + coursesList.add("Science"); + coursesList.add("Geography"); + + Document student = new Document().append("studentId", "STUD2") + .append("name", "Sam") + .append("age", 13) + .append("courses", coursesList); + + collection.insertOne(student); + + Bson filter = eq("studentId", "STUD2"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + + assertNotNull(cursor); + assertTrue(cursor.hasNext()); + } + + @Test + public void givenMultipleStudentObjectsWithStringArray_whenInsertingDocuments_thenCheckingForDocuments() { + List coursesList1 = new ArrayList<>(); + coursesList1.add("Chemistry"); + coursesList1.add("Geography"); + + Document student1 = new Document().append("studentId", "STUD3") + .append("name", "Sarah") + .append("age", 12) + .append("courses", coursesList1); + + List coursesList2 = new ArrayList<>(); + coursesList2.add("Maths"); + coursesList2.add("History"); + + Document student2 = new Document().append("studentId", "STUD4") + .append("name", "Tom") + .append("age", 13) + .append("courses", coursesList2); + + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + collection.insertMany(students); + + Bson filter = in("studentId", "STUD3", "STUD4"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + + assertNotNull(cursor); + assertTrue(cursor.hasNext()); + } + + @Test + public void givenSingleStudentObjectWithObjectArray_whenInsertingDocument_thenCheckingForDocument() { + Document course1 = new Document().append("name", "C1") + .append("points", 5); + + Document course2 = new Document().append("name", "C2") + .append("points", 7); + + List coursesList = new ArrayList<>(); + coursesList.add(course1); + coursesList.add(course2); + + Document student = new Document().append("studentId", "STUD5") + .append("name", "Sam") + .append("age", 13) + .append("courses", coursesList); + + collection.insertOne(student); + + Bson filter = eq("studentId", "STUD5"); + FindIterable documents = collection.find(filter); + + MongoCursor cursor = documents.iterator(); + + assertNotNull(cursor); + assertTrue(cursor.hasNext()); + } +} diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java similarity index 91% rename from spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java rename to spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java index e0bbef1c7f..5fc8597252 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java @@ -20,7 +20,8 @@ import static org.mockito.Mockito.when; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SpringBoot.class) -public class KeycloakConfigurationIntegrationTest { +//requires running Keycloak server and realm setup as shown in https://www.baeldung.com/spring-boot-keycloak +public class KeycloakConfigurationLiveTest { @Spy private KeycloakSecurityContextClientRequestInterceptor factory; diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml index 79c090dde5..de4e879089 100644 --- a/spring-boot-modules/spring-boot-libraries-2/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml @@ -133,6 +133,7 @@ 2.4.5 0.2.1 2.9.2 + com.baeldung.openapi.OpenApiApplication \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java index f901592938..b46d7ca9b0 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java @@ -1,9 +1,12 @@ package com.baeldung.kong; +import org.jobrunr.autoconfigure.JobRunrAutoConfiguration; import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication +@EnableAutoConfiguration(exclude = { JobRunrAutoConfiguration.class}) public class StockApp { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-mvc-2/README.md b/spring-boot-modules/spring-boot-mvc-2/README.md index 30e6d71a30..1d89726b71 100644 --- a/spring-boot-modules/spring-boot-mvc-2/README.md +++ b/spring-boot-modules/spring-boot-mvc-2/README.md @@ -5,8 +5,6 @@ This module contains articles about Spring Web MVC in Spring Boot projects. ### Relevant Articles: - [Functional Controllers in Spring MVC](https://www.baeldung.com/spring-mvc-functional-controllers) -- [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings) -- [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty) - [Testing REST with multiple MIME types](https://www.baeldung.com/testing-rest-api-with-multiple-media-types) - [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) - [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json) diff --git a/spring-boot-modules/spring-boot-mvc-2/pom.xml b/spring-boot-modules/spring-boot-mvc-2/pom.xml index f303171df8..bcc0cb68a0 100644 --- a/spring-boot-modules/spring-boot-mvc-2/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-2/pom.xml @@ -28,22 +28,6 @@ spring-boot-devtools true - - - io.springfox - springfox-swagger2 - ${spring.fox.version} - - - io.springfox - springfox-swagger-ui - ${spring.fox.version} - - - io.springfox - springfox-spring-webmvc - ${spring.fox.version} - org.apache.commons commons-lang3 @@ -90,8 +74,7 @@ 3.0.0 - com.baeldung.swagger2boot.SpringBootSwaggerApplication - + com.baeldung.springbootmvc.SpringBootMvcFnApplication 1.4.11.1 diff --git a/spring-boot-modules/spring-boot-swagger-2/README.md b/spring-boot-modules/spring-boot-swagger-2/README.md index e607b56299..242f3d3385 100644 --- a/spring-boot-modules/spring-boot-swagger-2/README.md +++ b/spring-boot-modules/spring-boot-swagger-2/README.md @@ -1,3 +1,5 @@ ### Relevant Articles: - [Swagger: Specify Two Responses with the Same Response Code](https://www.baeldung.com/swagger-two-responses-one-response-code) +- [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings) +- [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-2/pom.xml b/spring-boot-modules/spring-boot-swagger-2/pom.xml index 055d8ce3eb..a054773731 100644 --- a/spring-boot-modules/spring-boot-swagger-2/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-2/pom.xml @@ -39,6 +39,16 @@ javax.validation validation-api + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-spring-webmvc + ${springfox.version} + @@ -63,6 +73,13 @@ + + org.springframework.boot + spring-boot-maven-plugin + + ${start-class} + + @@ -70,6 +87,8 @@ 3.0.0 3.0.34 1.6.10 + 3.1.1 + com.baeldung.tworesponses.Application \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java similarity index 89% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java index 0f68f75d16..e166d28e7c 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.swagger2boot; +package com.baeldung.swagger2bootmvc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; 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-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java similarity index 88% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java index 6f3557d597..d4a7774510 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java @@ -1,7 +1,8 @@ -package com.baeldung.swagger2boot.config; +package com.baeldung.swagger2bootmvc.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; @@ -9,10 +10,12 @@ import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + @Configuration -@EnableSwagger2WebMvc +@EnableWebMvc +@EnableSwagger2 public class Swagger2Config { @Bean public Docket api() { diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java similarity index 91% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java index ac6d99c40c..5edf610154 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java @@ -1,4 +1,4 @@ -package com.baeldung.swagger2boot.controller; +package com.baeldung.swagger2bootmvc.controller; import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; -import com.baeldung.swagger2boot.model.Foo; +import com.baeldung.swagger2bootmvc.model.Foo; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; 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-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java similarity index 68% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java index d8102a8407..fa879f3bea 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java @@ -1,19 +1,17 @@ -package com.baeldung.swagger2boot.controller; +package com.baeldung.swagger2bootmvc.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 org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; -import javax.validation.Valid; -import javax.websocket.server.PathParam; +import com.baeldung.swagger2bootmvc.model.User; -import static org.apache.commons.lang3.RandomStringUtils.randomNumeric; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; @Controller public class UserController { diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java similarity index 94% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java index e48c2016c0..f3fe56e07d 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java @@ -1,4 +1,4 @@ -package com.baeldung.swagger2boot.model; +package com.baeldung.swagger2bootmvc.model; import java.util.List; 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-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java similarity index 92% rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java index d4a6479f4e..b4ec55f564 100644 --- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java @@ -1,4 +1,4 @@ -package com.baeldung.swagger2boot.model; +package com.baeldung.swagger2bootmvc.model; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/resources/swagger-description.yml b/spring-boot-modules/spring-boot-swagger-2/src/main/resources/swagger-description.yml similarity index 100% rename from spring-boot-modules/spring-boot-mvc-2/src/main/resources/swagger-description.yml rename to spring-boot-modules/spring-boot-swagger-2/src/main/resources/swagger-description.yml diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java index b842b948d7..2cef3d4238 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -@FeignClient(name = "product-client", url = "http://localhost:8081/product/", configuration = FeignConfig.class) +@FeignClient(name = "product-client", url = "http://localhost:8084/product/", configuration = FeignConfig.class) public interface ProductClient { @RequestMapping(value = "{id}", method = RequestMethod.GET) diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java index 392cb19050..4dda2bbe15 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java @@ -27,9 +27,10 @@ public class ProductClientUnitTest { @Before public void startWireMockServer() { - wireMockServer = new WireMockServer(8081); - configureFor("localhost", 8081); + wireMockServer = new WireMockServer(8084); + configureFor("localhost", 8084); wireMockServer.start(); + } @After diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java index 269cd2d2d6..bfc0c3d281 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java @@ -20,7 +20,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @RunWith(SpringRunner.class) @WebMvcTest(ProductController.class) @ImportAutoConfiguration({FeignAutoConfiguration.class, TestControllerAdvice.class}) @@ -37,8 +36,8 @@ public class ProductControllerUnitTest { @Before public void startWireMockServer() { - wireMockServer = new WireMockServer(8081); - configureFor("localhost", 8081); + wireMockServer = new WireMockServer(8084); + configureFor("localhost", 8084); wireMockServer.start(); } diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java index 3d4182f423..bce0e21e7a 100644 --- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java @@ -7,15 +7,18 @@ 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.AuthenticationManager; 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.config.annotation.web.configuration.WebSecurityCustomizer; 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.security.provisioning.JdbcUserDetailsManager; +import org.springframework.security.provisioning.UserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.context.WebApplicationContext; import com.baeldung.relationships.security.AuthenticationSuccessHandlerImpl; @@ -24,7 +27,7 @@ import com.baeldung.relationships.security.CustomUserDetailsService; @Configuration @EnableWebSecurity @ComponentScan("com.baeldung.security") -public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { +public class SpringSecurityConfig { @Autowired private WebApplicationContext applicationContext; @@ -42,24 +45,28 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { userDetailsService = applicationContext.getBean(CustomUserDetailsService.class); } - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService) + @Bean + public UserDetailsManager users(HttpSecurity http) throws Exception { + AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class) + .userDetailsService(userDetailsService) .passwordEncoder(encoder()) .and() .authenticationProvider(authenticationProvider()) - .jdbcAuthentication() - .dataSource(dataSource); + .build(); + + JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource); + jdbcUserDetailsManager.setAuthenticationManager(authenticationManager); + return jdbcUserDetailsManager; } - @Override - public void configure(WebSecurity web) { - web.ignoring() + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> web.ignoring() .antMatchers("/resources/**"); } - @Override - protected void configure(final HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login") .permitAll() @@ -70,6 +77,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { .and() .csrf() .disable(); + return http.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java index 6bf04120ab..ea882f7ba9 100644 --- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java @@ -4,16 +4,16 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.SecurityFilterChain; @Configuration @EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { - @Override - protected void configure(final HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeRequests() @@ -22,6 +22,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .and() .formLogin() .permitAll(); + return http.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java index 71c7bcccc6..6b6fa8c6a3 100644 --- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java @@ -1,33 +1,50 @@ package com.baeldung.roles.ip.config; 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.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { @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); + @Bean + public InMemoryUserDetailsManager userDetailsService(HttpSecurity http) throws Exception { + UserDetails user = User.withUsername("john") + .password("{noop}123") + .authorities("ROLE_USER") + .build(); + http.getSharedObject(AuthenticationManagerBuilder.class) + .authenticationProvider(authenticationProvider) + .build(); + return new InMemoryUserDetailsManager(user); } - @Override - protected void configure(final HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 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(); + .antMatchers("/login") + .permitAll() + .antMatchers("/foos/**") + .access("isAuthenticated() and hasIpAddress('11.11.11.11')") + .anyRequest() + .authenticated() + .and() + .formLogin() + .permitAll() + .and() + .csrf() + .disable(); + return http.build(); } } \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java index 9b7ccfd25b..d464b82d1c 100644 --- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java @@ -1,26 +1,28 @@ package com.baeldung.roles.rolesauthorities.config; -import com.baeldung.roles.rolesauthorities.CustomAuthenticationProvider; -import com.baeldung.roles.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.AuthenticationManager; 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.config.annotation.web.configuration.WebSecurityCustomizer; 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.SecurityFilterChain; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import com.baeldung.roles.rolesauthorities.CustomAuthenticationProvider; +import com.baeldung.roles.rolesauthorities.persistence.UserRepository; + @Configuration @ComponentScan(basePackages = {"com.baeldung.rolesauthorities"}) @EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { +public class SecurityConfig { @Autowired private UserRepository userRepository; @@ -31,39 +33,43 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private LogoutSuccessHandler myLogoutSuccessHandler; - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.authenticationProvider(authProvider()); + @Bean + public AuthenticationManager authManager(HttpSecurity http) throws Exception { + return http.getSharedObject(AuthenticationManagerBuilder.class) + .authenticationProvider(authProvider()) + .build(); } - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring() + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> web.ignoring() .antMatchers("/resources/**"); } - - @Override - protected void configure(HttpSecurity http) throws Exception { - - http - .csrf().disable() + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() .authorizeRequests() - .antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll() - .antMatchers("/protectedbyrole").hasRole("USER") - .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE") - .and() + .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() + .loginPage("/login") + .failureUrl("/login?error=true") + .permitAll() + .and() .logout() - .logoutSuccessHandler(myLogoutSuccessHandler) - .invalidateHttpSession(false) - .logoutSuccessUrl("/logout.html?logSucc=true") - .deleteCookies("JSESSIONID") - .permitAll(); + .logoutSuccessHandler(myLogoutSuccessHandler) + .invalidateHttpSession(false) + .logoutSuccessUrl("/logout.html?logSucc=true") + .deleteCookies("JSESSIONID") + .permitAll(); + return http.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java index 5141e1af7c..146853c18b 100644 --- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java +++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java @@ -1,5 +1,8 @@ package com.baeldung.roles.voter; +import java.util.Arrays; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -11,17 +14,14 @@ 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.SecurityFilterChain; import org.springframework.security.web.access.expression.WebExpressionVoter; -import java.util.Arrays; -import java.util.List; - @Configuration @EnableWebSecurity -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { @@ -36,22 +36,23 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .roles("ADMIN"); } - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .csrf() - .disable() - .authorizeRequests() - .anyRequest() - .authenticated() - .accessDecisionManager(accessDecisionManager()) - .and() - .formLogin() - .permitAll() - .and() - .logout() - .permitAll() - .deleteCookies("JSESSIONID").logoutSuccessUrl("/login"); + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .anyRequest() + .authenticated() + .accessDecisionManager(accessDecisionManager()) + .and() + .formLogin() + .permitAll() + .and() + .logout() + .permitAll() + .deleteCookies("JSESSIONID") + .logoutSuccessUrl("/login"); + return http.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java index fb597e46c8..5714b2fb3e 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java +++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java @@ -1,20 +1,21 @@ package com.baeldung.filter; -import com.baeldung.security.RestAuthenticationEntryPoint; 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.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.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import com.baeldung.security.RestAuthenticationEntryPoint; + @Configuration @EnableWebSecurity -public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { +public class CustomWebSecurityConfigurerAdapter { @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; @@ -27,19 +28,18 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda .authorities("ROLE_USER"); } - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .antMatchers("/securityNone") - .permitAll() - .anyRequest() - .authenticated() - .and() - .httpBasic() - .authenticationEntryPoint(authenticationEntryPoint); - + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/securityNone") + .permitAll() + .anyRequest() + .authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint); http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); + return http.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java index 4b32a1126e..839fa15734 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java +++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java @@ -1,27 +1,30 @@ package com.baeldung.inmemory; +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.core.userdetails.UserDetails; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { +public class InMemoryAuthWebSecurityConfigurer { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); - auth.inMemoryAuthentication() - .passwordEncoder(encoder) - .withUser("spring") - .password(encoder.encode("secret")) - .roles("USER"); + @Bean + public InMemoryUserDetailsManager userDetailsService() { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + UserDetails user = User.withUsername("spring") + .password(encoder.encode("secret")) + .roles("USER") + .build(); + return new InMemoryUserDetailsManager(user); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/private/**") .authenticated() @@ -29,6 +32,7 @@ public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdap .permitAll() .and() .httpBasic(); + return http.build(); } } diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java index 4b6494f666..72d3ef79d7 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java +++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java @@ -1,23 +1,26 @@ package com.baeldung.inmemory; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.context.annotation.Bean; 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.core.userdetails.UserDetails; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; //@Configuration -public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { +public class InMemoryNoOpAuthWebSecurityConfigurer { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication() - .withUser("spring") + @Bean + public InMemoryUserDetailsManager userDetailsService() { + UserDetails user = User.withUsername("spring") .password("{noop}secret") - .roles("USER"); + .roles("USER") + .build(); + return new InMemoryUserDetailsManager(user); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/private/**") .authenticated() @@ -25,5 +28,6 @@ public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurer .permitAll() .and() .httpBasic(); + return http.build(); } } diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java index 59a2ae1dc2..a1c6e1ee76 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java +++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java @@ -1,9 +1,14 @@ package com.baeldung.passwordstorage; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -14,18 +19,16 @@ import org.springframework.security.crypto.password.StandardPasswordEncoder; import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - @Configuration -public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerAdapter { +public class PasswordStorageWebSecurityConfigurer { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.eraseCredentials(false) // 4 - .userDetailsService(getUserDefaultDetailsService()) - .passwordEncoder(passwordEncoder()); + @Bean + public AuthenticationManager authManager(HttpSecurity http) throws Exception { + AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); + authenticationManagerBuilder.eraseCredentials(false) + .userDetailsService(getUserDefaultDetailsService()) + .passwordEncoder(passwordEncoder()); + return authenticationManagerBuilder.build(); } @Bean diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java index a6311972c2..7a8848dcae 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java +++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java @@ -1,16 +1,17 @@ package com.baeldung.postman.basic; 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.web.SecurityFilterChain; @Configuration -public class PostmanBasicAuthConfig extends WebSecurityConfigurerAdapter { +public class PostmanBasicAuthConfig { - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeRequests() @@ -18,6 +19,7 @@ public class PostmanBasicAuthConfig extends WebSecurityConfigurerAdapter { .authenticated() .and() .httpBasic(); + return http.build(); } @Autowired diff --git a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java b/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java index 7f0b20ea34..0a79151f89 100644 --- a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java +++ b/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java @@ -1,28 +1,31 @@ package com.baeldung.security; -import com.baeldung.security.web.MySavedRequestAwareAuthenticationSuccessHandler; -import com.baeldung.security.web.RestAuthenticationEntryPoint; -import com.baeldung.web.error.CustomAccessDeniedHandler; 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.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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.UserDetails; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import com.baeldung.security.web.MySavedRequestAwareAuthenticationSuccessHandler; +import com.baeldung.security.web.RestAuthenticationEntryPoint; +import com.baeldung.web.error.CustomAccessDeniedHandler; + @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @ComponentScan("com.baeldung.security") -public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { +public class SecurityJavaConfig { @Autowired private CustomAccessDeniedHandler accessDeniedHandler; @@ -35,17 +38,23 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { private SimpleUrlAuthenticationFailureHandler myFailureHandler = new SimpleUrlAuthenticationFailureHandler(); - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication() - .withUser("admin").password(encoder().encode("adminPass")).roles("ADMIN") - .and() - .withUser("user").password(encoder().encode("userPass")).roles("USER"); + @Bean + public InMemoryUserDetailsManager userDetailsService() { + UserDetails admin = User.withUsername("admin") + .password(encoder().encode("adminPass")) + .roles("ADMIN") + .build(); + UserDetails user = User.withUsername("user") + .password(encoder().encode("userPass")) + .roles("USER") + .build(); + return new InMemoryUserDetailsManager(admin, user); } - @Override - protected void configure(final HttpSecurity http) throws Exception { - http.csrf().disable() + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf() + .disable() .authorizeRequests() .and() .exceptionHandling() @@ -53,11 +62,16 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() - .antMatchers("/api/csrfAttacker*").permitAll() - .antMatchers("/api/customer/**").permitAll() - .antMatchers("/api/foos/**").authenticated() - .antMatchers("/api/async/**").permitAll() - .antMatchers("/api/admin/**").hasRole("ADMIN") + .antMatchers("/api/csrfAttacker*") + .permitAll() + .antMatchers("/api/customer/**") + .permitAll() + .antMatchers("/api/foos/**") + .authenticated() + .antMatchers("/api/async/**") + .permitAll() + .antMatchers("/api/admin/**") + .hasRole("ADMIN") .and() .formLogin() .successHandler(mySuccessHandler) @@ -66,6 +80,7 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { .httpBasic() .and() .logout(); + return http.build(); } @Bean diff --git a/spring-web-modules/spring-mvc-basics-5/README.md b/spring-web-modules/spring-mvc-basics-5/README.md index dfd6522b0f..e7f39c8ea2 100644 --- a/spring-web-modules/spring-mvc-basics-5/README.md +++ b/spring-web-modules/spring-mvc-basics-5/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring - [Spring @RequestParam Annotation](https://www.baeldung.com/spring-request-param) - [Spring @RequestParam vs @PathVariable Annotations](https://www.baeldung.com/spring-requestparam-vs-pathvariable) - [@RequestMapping Value in Properties File](https://www.baeldung.com/spring-requestmapping-properties-file) +- [Map a JSON POST to Multiple Spring MVC Parameters](https://www.baeldung.com/spring-mvc-json-param-mapping) - More articles: [[<-- prev]](../spring-mvc-basics-4)