diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java index 202912a1af..15e813f680 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; public class KadaneAlgorithm { - private Logger logger = LoggerFactory.getLogger(BruteForceAlgorithm.class.getName()); + private Logger logger = LoggerFactory.getLogger(KadaneAlgorithm.class.getName()); public int maxSubArraySum(int[] arr) { @@ -14,15 +14,15 @@ public class KadaneAlgorithm { int end = 0; int maxSoFar = arr[0], maxEndingHere = arr[0]; + for (int i = 1; i < size; i++) { - - if (arr[i] > maxEndingHere + arr[i]) { - start = i; + maxEndingHere = maxEndingHere + arr[i]; + if (arr[i] > maxEndingHere) { maxEndingHere = arr[i]; - } else { - maxEndingHere = maxEndingHere + arr[i]; + if (maxSoFar < maxEndingHere) { + start = i; + } } - if (maxSoFar < maxEndingHere) { maxSoFar = maxEndingHere; end = i; diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java index 8dcc81bc5b..b0ce689645 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class KadaneAlgorithmUnitTest { @Test - void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() { + void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturnsExpectedResult() { //given int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 }; //when @@ -27,7 +27,7 @@ class KadaneAlgorithmUnitTest { //then assertEquals(-1, maxSum); } - + @Test void givenArrayWithAllPosiitveNumbersWhenMaximumSubarrayThenReturnsExpectedResult() { //given @@ -39,4 +39,15 @@ class KadaneAlgorithmUnitTest { assertEquals(10, maxSum); } + @Test + void givenArrayToTestStartIndexWhenMaximumSubarrayThenReturnsExpectedResult() { + //given + int[] arr = new int[] { 1, 2, -1, 3, -6, -2 }; + //when + KadaneAlgorithm algorithm = new KadaneAlgorithm(); + int maxSum = algorithm.maxSubArraySum(arr); + //then + assertEquals(5, maxSum); + } + } \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index ab07d655f9..82d9df9292 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -3,4 +3,5 @@ - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) - [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array) - [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) +- [Calculate Distance Between Two Coordinates in Java](https://www.baeldung.com/java-find-distance-between-points) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) diff --git a/aws-modules/aws-s3/README.md b/aws-modules/aws-s3/README.md index 3389fdf454..59c9f893d9 100644 --- a/aws-modules/aws-s3/README.md +++ b/aws-modules/aws-s3/README.md @@ -8,4 +8,5 @@ This module contains articles about Simple Storage Service (S3) on AWS - [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) - [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) - [Check if a Specified Key Exists in a Given S3 Bucket Using Java](https://www.baeldung.com/java-aws-s3-check-specified-key-exists) -- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) \ No newline at end of file +- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) +- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object) diff --git a/core-java-modules/core-java-arrays-operations-advanced/README.md b/core-java-modules/core-java-arrays-operations-advanced/README.md index e3465c9fa3..b379958f37 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/README.md +++ b/core-java-modules/core-java-arrays-operations-advanced/README.md @@ -13,3 +13,4 @@ This module contains articles about advanced operations on arrays in Java. They - [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) - [Slicing Arrays in Java](https://www.baeldung.com/java-slicing-arrays) - [Combining Two or More Byte Arrays](https://www.baeldung.com/java-concatenate-byte-arrays) +- [Calculating the Sum of Two Arrays in Java](https://www.baeldung.com/java-sum-arrays-element-wise) diff --git a/core-java-modules/core-java-collections-conversions-2/README.md b/core-java-modules/core-java-collections-conversions-2/README.md index efd01c46ee..e8d008104c 100644 --- a/core-java-modules/core-java-collections-conversions-2/README.md +++ b/core-java-modules/core-java-collections-conversions-2/README.md @@ -13,4 +13,5 @@ This module contains articles about conversions among Collection types and array - [Combining Two Lists Into a Map in Java](https://www.baeldung.com/java-combine-two-lists-into-map) - [Convert a List of Strings to a List of Integers](https://www.baeldung.com/java-convert-list-strings-to-integers) - [Convert List to Long[] Array in Java](https://www.baeldung.com/java-convert-list-object-to-long-array) +- [Get the First n Elements of a List Into an Array](https://www.baeldung.com/java-take-start-elements-list-array) - More articles: [[<-- prev]](../core-java-collections-conversions) diff --git a/core-java-modules/core-java-collections-maps-3/README.md b/core-java-modules/core-java-collections-maps-3/README.md index 68df2b9556..0d07bde8c1 100644 --- a/core-java-modules/core-java-collections-maps-3/README.md +++ b/core-java-modules/core-java-collections-maps-3/README.md @@ -9,4 +9,5 @@ This module contains articles about Map data structures in Java. - [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap) - [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor) - [Converting Java Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap) +- [Get Values and Keys as ArrayList From a HashMap](https://www.baeldung.com/java-values-keys-arraylists-hashmap) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2) diff --git a/core-java-modules/core-java-datetime-conversion/README.md b/core-java-modules/core-java-datetime-conversion/README.md index 98c2d6694b..d3a3dae728 100644 --- a/core-java-modules/core-java-datetime-conversion/README.md +++ b/core-java-modules/core-java-datetime-conversion/README.md @@ -9,3 +9,4 @@ This module contains articles about converting between Java date and time object - [Convert Between java.time.Instant and java.sql.Timestamp](https://www.baeldung.com/java-time-instant-to-java-sql-timestamp) - [Convert Between LocalDateTime and ZonedDateTime](https://www.baeldung.com/java-localdatetime-zoneddatetime) - [Conversion From 12-Hour Time to 24-Hour Time in Java](https://www.baeldung.com/java-convert-time-format) +- [Convert Epoch Time to LocalDate and LocalDateTime](https://www.baeldung.com/java-convert-epoch-localdate) diff --git a/core-java-modules/core-java-lang-oop-inheritance/README.md b/core-java-modules/core-java-lang-oop-inheritance/README.md index c87bdf13d7..430f88e717 100644 --- a/core-java-modules/core-java-lang-oop-inheritance/README.md +++ b/core-java-modules/core-java-lang-oop-inheritance/README.md @@ -12,3 +12,4 @@ This module contains articles about inheritance in Java - [Guide to Inheritance in Java](https://www.baeldung.com/java-inheritance) - [Object Type Casting in Java](https://www.baeldung.com/java-type-casting) - [Variable and Method Hiding in Java](https://www.baeldung.com/java-variable-method-hiding) +- [Inner Classes Vs. Subclasses in Java](https://www.baeldung.com/java-inner-classes-vs-subclasses) diff --git a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java index 8b3685adf3..0a9418cb17 100644 --- a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java +++ b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java @@ -1,54 +1,77 @@ package com.baeldung.modulo; +import static org.junit.Assert.assertEquals; + import org.junit.Test; import static org.assertj.core.api.Java6Assertions.*; public class ModuloUnitTest { - @Test - public void whenIntegerDivision_thenLosesRemainder(){ - assertThat(11 / 4).isEqualTo(2); - } - - @Test - public void whenDoubleDivision_thenKeepsRemainder(){ - assertThat(11 / 4.0).isEqualTo(2.75); - } - - @Test - public void whenModulo_thenReturnsRemainder(){ - assertThat(11 % 4).isEqualTo(3); - } - - @Test(expected = ArithmeticException.class) - public void whenDivisionByZero_thenArithmeticException(){ - double result = 1 / 0; - } - - @Test(expected = ArithmeticException.class) - public void whenModuloByZero_thenArithmeticException(){ - double result = 1 % 0; - } - - @Test - public void whenDivisorIsOddAndModulusIs2_thenResultIs1(){ - assertThat(3 % 2).isEqualTo(1); - } - - @Test - public void whenDivisorIsEvenAndModulusIs2_thenResultIs0(){ - assertThat(4 % 2).isEqualTo(0); - } - - @Test - public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds(){ - int QUEUE_CAPACITY= 10; - int[] circularQueue = new int[QUEUE_CAPACITY]; - int itemsInserted = 0; - for (int value = 0; value < 1000; value++) { - int writeIndex = ++itemsInserted % QUEUE_CAPACITY; - circularQueue[writeIndex] = value; + @Test + public void whenIntegerDivision_thenLosesRemainder() { + assertThat(11 / 4).isEqualTo(2); + } + + @Test + public void whenDoubleDivision_thenKeepsRemainder() { + assertThat(11 / 4.0).isEqualTo(2.75); + } + + @Test + public void whenModulo_thenReturnsRemainder() { + assertThat(11 % 4).isEqualTo(3); + } + + @Test(expected = ArithmeticException.class) + public void whenDivisionByZero_thenArithmeticException() { + double result = 1 / 0; + } + + @Test(expected = ArithmeticException.class) + public void whenModuloByZero_thenArithmeticException() { + double result = 1 % 0; + } + + @Test + public void whenDivisorIsOddAndModulusIs2_thenResultIs1() { + assertThat(3 % 2).isEqualTo(1); + } + + @Test + public void whenDivisorIsEvenAndModulusIs2_thenResultIs0() { + assertThat(4 % 2).isEqualTo(0); + } + + @Test + public void whenDividendIsNegativeAndModulusIs2_thenResultIsNegative() { + assertEquals(-1, -9 % 2); + } + + @Test + public void whenDividendIsNegativeAndRemainderIsCheckedForNegativeValue_thenResultIsPositive() { + int remainder = -9 % 2; + + if (remainder < 0) { + remainder += 2; + } + assertEquals(1, remainder); + } + + @Test + public void whenDividendIsNegativeAndUsesMathClass_thenResultIsPositive() { + int remainder = Math.floorMod(-9, 2); + assertEquals(1, remainder); + } + + @Test + public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds() { + int QUEUE_CAPACITY = 10; + int[] circularQueue = new int[QUEUE_CAPACITY]; + int itemsInserted = 0; + for (int value = 0; value < 1000; value++) { + int writeIndex = ++itemsInserted % QUEUE_CAPACITY; + circularQueue[writeIndex] = value; + } } - } } diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java new file mode 100644 index 0000000000..2ea80a1f69 --- /dev/null +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java @@ -0,0 +1,98 @@ +package com.baeldung.regex.squarebrackets; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; + +public class ExtractTextBetweenSquareBracketsUnitTest { + static final String INPUT1 = "some text [THE IMPORTANT MESSAGE] something else"; + static final String EXPECTED1 = "THE IMPORTANT MESSAGE"; + + static final String INPUT2 = "[La La Land], [The last Emperor], and [Life of Pi] are all great movies."; + static final List EXPECTED2 = Lists.newArrayList("La La Land", "The last Emperor", "Life of Pi"); + + @Test + void whenUsingDotStarOnInput1_thenGetExpectedResult() { + String result = null; + String rePattern = "\\[(.*)]"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT1); + if (m.find()) { + result = m.group(1); + } + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingCharClassOnInput1_thenGetExpectedResult() { + String result = null; + String rePattern = "\\[([^]]*)"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT1); + if (m.find()) { + result = m.group(1); + } + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingSplitOnInput1_thenGetExpectedResult() { + String[] strArray = INPUT1.split("[\\[\\]]", -1); + String result = strArray.length == 3 ? strArray[1] : null; + + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingSplitWithLimit_thenGetExpectedResult() { + String[] strArray = "[THE IMPORTANT MESSAGE]".split("[\\[\\]]"); + assertThat(strArray).hasSize(2) + .containsExactly("", "THE IMPORTANT MESSAGE"); + + strArray = "[THE IMPORTANT MESSAGE]".split("[\\[\\]]", -1); + assertThat(strArray).hasSize(3) + .containsExactly("", "THE IMPORTANT MESSAGE", ""); + } + + @Test + void whenUsingNonGreedyOnInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String rePattern = "\\[(.*?)]"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT2); + while (m.find()) { + result.add(m.group(1)); + } + assertThat(result).isEqualTo(EXPECTED2); + } + + @Test + void whenUsingCharClassOnInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String rePattern = "\\[([^]]*)"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT2); + while (m.find()) { + result.add(m.group(1)); + } + assertThat(result).isEqualTo(EXPECTED2); + } + + @Test + void whenUsingSplitInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String[] strArray = INPUT2.split("[\\[\\]]", -1); + for (int i = 1; i < strArray.length; i += 2) { + result.add(strArray[i]); + } + assertThat(result).isEqualTo(EXPECTED2); + } + +} \ No newline at end of file diff --git a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java index 047d53ab62..4dc9e40292 100644 --- a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java +++ b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java @@ -20,6 +20,7 @@ import org.joda.time.DateTimeZone; import org.junit.Test; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.StdDateFormat; @@ -67,6 +68,8 @@ public class JacksonDateUnitTest { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.findAndRegisterModules(); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID); + objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); String converted = objectMapper.writeValueAsString(now); diff --git a/json-modules/json-2/README.md b/json-modules/json-2/README.md index a29484d9fc..f41a7047fa 100644 --- a/json-modules/json-2/README.md +++ b/json-modules/json-2/README.md @@ -13,5 +13,6 @@ This module contains articles about JSON. - [Getting a Value in JSONObject](https://www.baeldung.com/java-jsonobject-get-value) - [Pretty-Print a JSON in Java](https://www.baeldung.com/java-json-pretty-print) - [Remove Whitespaces From a JSON in Java](https://www.baeldung.com/java-json-minify-remove-whitespaces) +- [Programmatic Generation of JSON Schemas in Java](https://www.baeldung.com/java-json-schema-create-automatically) - More Articles: [[<-- prev]](/json-modules/json) diff --git a/json-modules/json-arrays/README.md b/json-modules/json-arrays/README.md new file mode 100644 index 0000000000..f119467046 --- /dev/null +++ b/json-modules/json-arrays/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [How to Check if a Value Exists in a JSON Array for a Particular Key](https://www.baeldung.com/java-json-array-check-key-value-pair) diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index afabf9ecb3..f9da4947a7 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -9,3 +9,4 @@ - [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) +- [Executing SQL Script File in Java](https://www.baeldung.com/java-run-sql-script) diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index a2febc8156..251dba0316 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -44,7 +44,7 @@ spring-boot-graphql spring-boot-groovy - + spring-boot-jasypt spring-boot-jsp spring-boot-keycloak spring-boot-keycloak-2 @@ -91,6 +91,7 @@ spring-boot-3-native spring-boot-3-observation spring-boot-3-test-pitfalls + spring-boot-3-testcontainers spring-boot-resilience4j spring-boot-properties spring-boot-properties-2 diff --git a/spring-boot-modules/spring-boot-3-testcontainers/README.md b/spring-boot-modules/spring-boot-3-testcontainers/README.md new file mode 100644 index 0000000000..5616cce48b --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/README.md @@ -0,0 +1 @@ +## Relevant Articles diff --git a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml new file mode 100644 index 0000000000..173fb8795c --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + spring-boot-3-testcontainers + 0.0.1-SNAPSHOT + spring-boot-3-testcontainers + Testcontainer Improvements in Spring Boot 3 + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + org.springframework.boot + spring-boot-testcontainers + + + + org.testcontainers + mongodb + ${testcontainers.version} + test + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + + + + io.rest-assured + rest-assured + ${rest-assured.version} + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 3.0.0-M7 + 1.18.3 + 5.3.1 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java new file mode 100644 index 0000000000..9a00bfebf2 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.testcontainers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java new file mode 100644 index 0000000000..4780a2f66a --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java @@ -0,0 +1,13 @@ +package com.baeldung.testcontainers.support; + +import java.util.UUID; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("characters") +public record MiddleEarthCharacter(@Id String id, String name, String race) { + public MiddleEarthCharacter(String name, String race) { + this(UUID.randomUUID().toString(), name, race); + } +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java new file mode 100644 index 0000000000..3b7bfddbef --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java @@ -0,0 +1,30 @@ +package com.baeldung.testcontainers.support; + +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("characters") +public class MiddleEarthCharactersController { + private final MiddleEarthCharactersRepository repository; + + public MiddleEarthCharactersController(MiddleEarthCharactersRepository repository) { + this.repository = repository; + } + + @GetMapping + public List findByRace(@RequestParam String race) { + return repository.findAllByRace(race); + } + + @PostMapping + public MiddleEarthCharacter save(@RequestBody MiddleEarthCharacter character) { + return repository.save(character); + } +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java new file mode 100644 index 0000000000..a668650670 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.testcontainers.support; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MiddleEarthCharactersRepository extends MongoRepository { + List findAllByRace(String race); +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesIntegrationTest.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesIntegrationTest.java new file mode 100644 index 0000000000..8689b10110 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesIntegrationTest.java @@ -0,0 +1,59 @@ +package com.baeldung.testcontainers; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.testcontainers.support.MiddleEarthCharacter; +import com.baeldung.testcontainers.support.MiddleEarthCharactersRepository; + +@Testcontainers +@SpringBootTest(webEnvironment = DEFINED_PORT) +@DirtiesContext(classMode = AFTER_CLASS) +class DynamicPropertiesIntegrationTest { + @Container + static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @DynamicPropertySource + static void setProperties(DynamicPropertyRegistry registry) { + registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); + } + + @Autowired + private MiddleEarthCharactersRepository repository; + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + @Test + void whenRequestingHobbits_thenReturnFrodoAndSam() { + repository.saveAll(List.of( + new MiddleEarthCharacter("Frodo", "hobbit"), + new MiddleEarthCharacter("Samwise", "hobbit"), + new MiddleEarthCharacter("Aragon", "human"), + new MiddleEarthCharacter("Gandalf", "wizzard") + )); + + when().get("/characters?race=hobbit") + .then().statusCode(200) + .and().body("name", hasItems("Frodo", "Samwise")); + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java new file mode 100644 index 0000000000..a94c0f772a --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.testcontainers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.devtools.restart.RestartScope; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Bean; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.utility.DockerImageName; + +class LocalDevApplication { + + public static void main(String[] args) { + SpringApplication.from(Application::main) + .with(LocalDevTestcontainersConfig.class) + .run(args); + } + + @TestConfiguration(proxyBeanMethods = false) + static class LocalDevTestcontainersConfig { + @Bean + @RestartScope + @ServiceConnection + public MongoDBContainer mongoDBContainer() { + return new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + } + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionIntegrationTest.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionIntegrationTest.java new file mode 100644 index 0000000000..500d6d2e61 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.testcontainers; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.test.annotation.DirtiesContext; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.testcontainers.support.MiddleEarthCharacter; +import com.baeldung.testcontainers.support.MiddleEarthCharactersRepository; + +@Testcontainers +@SpringBootTest(webEnvironment = DEFINED_PORT) +@DirtiesContext(classMode = AFTER_CLASS) +class ServiceConnectionIntegrationTest { + + @Container + @ServiceConnection + static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @Autowired + private MiddleEarthCharactersRepository repository; + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + @Test + void whenRequestingHobbits_thenReturnFrodoAndSam() { + repository.saveAll(List.of( + new MiddleEarthCharacter("Frodo", "hobbit"), + new MiddleEarthCharacter("Samwise", "hobbit"), + new MiddleEarthCharacter("Aragon", "human"), + new MiddleEarthCharacter("Gandalf", "wizzard") + )); + + when().get("/characters?race=hobbit") + .then().statusCode(200) + .and().body("name", hasItems("Frodo", "Samwise")); + } + +} diff --git a/spring-boot-modules/spring-boot-jasypt/pom.xml b/spring-boot-modules/spring-boot-jasypt/pom.xml index 8595b9c639..b83162fb04 100644 --- a/spring-boot-modules/spring-boot-jasypt/pom.xml +++ b/spring-boot-modules/spring-boot-jasypt/pom.xml @@ -50,4 +50,11 @@ 2.0.0 + + + spring-milestone + Spring Milestone + https://repo.spring.io/milestone + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java index 72c45afbb2..d7e948ca9a 100644 --- a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java +++ b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java @@ -1,6 +1,7 @@ package com.baeldung.configurationproperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.ConstructorBinding; @ConfigurationProperties(prefix = "mail.credentials") public class ImmutableCredentials { @@ -9,12 +10,19 @@ public class ImmutableCredentials { private final String username; private final String password; + @ConstructorBinding public ImmutableCredentials(String authMethod, String username, String password) { this.authMethod = authMethod; this.username = username; this.password = password; } + public ImmutableCredentials(String username, String password) { + this.username = username; + this.password = password; + this.authMethod = "Default"; + } + public String getAuthMethod() { return authMethod; } diff --git a/spring-boot-modules/spring-boot-telegram/README.md b/spring-boot-modules/spring-boot-telegram/README.md new file mode 100644 index 0000000000..4cd6560bc0 --- /dev/null +++ b/spring-boot-modules/spring-boot-telegram/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Creating a Telegram Bot with Spring Boot](https://www.baeldung.com/spring-boot-telegram-bot)