diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
index 0aaa1b6c23..60171220cd 100644
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
@@ -13,22 +13,22 @@ public class KadaneAlgorithm {
int start = 0;
int end = 0;
- int maxSoFar = 0, maxEndingHere = 0;
-
+ int maxSoFar = arr[0], maxEndingHere = arr[0];
for (int i = 0; i < size; i++) {
if (arr[i] > maxEndingHere + arr[i]) {
start = i;
maxEndingHere = arr[i];
- } else
+ } else {
maxEndingHere = maxEndingHere + arr[i];
+ }
if (maxSoFar < maxEndingHere) {
maxSoFar = maxEndingHere;
end = i;
}
}
- logger.info("Found Maximum Subarray between {} and {}", start, end);
+ logger.info("Found Maximum Subarray between {} and {}", Math.min(start, end), end);
return maxSoFar;
}
}
diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
index 9bece56f5b..71531dcf59 100644
--- a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
+++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
@@ -9,11 +9,22 @@ class KadaneAlgorithmUnitTest {
@Test
void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() {
//given
- int[] arr = new int[]{-3, 1, -8, 4, -1, 2, 1, -5, 5};
+ int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 };
//when
KadaneAlgorithm algorithm = new KadaneAlgorithm();
int maxSum = algorithm.maxSubArraySum(arr);
//then
assertEquals(6, maxSum);
}
+
+ @Test
+ void givenArrayWithAllNegativeNumbersWhenMaximumSubarrayThenReturnsExpectedResult() {
+ //given
+ int[] arr = new int[] { -8, -7, -5, -4, -3, -1, -2 };
+ //when
+ KadaneAlgorithm algorithm = new KadaneAlgorithm();
+ int maxSum = algorithm.maxSubArraySum(arr);
+ //then
+ assertEquals(-1, maxSum);
+ }
}
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-guides/pom.xml b/core-java-modules/core-java-arrays-guides/pom.xml
index df8639820d..263954445e 100644
--- a/core-java-modules/core-java-arrays-guides/pom.xml
+++ b/core-java-modules/core-java-arrays-guides/pom.xml
@@ -24,6 +24,12 @@
jmh-generator-annprocess
${jmh.version}
+
+ org.assertj
+ assertj-core
+ 3.19.0
+ test
+
diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java
index 5fd0385181..df7e0566ed 100644
--- a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java
+++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java
@@ -2,7 +2,6 @@ package com.baeldung.genericarrays;
import org.junit.Test;
-import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java
new file mode 100644
index 0000000000..5dea901b25
--- /dev/null
+++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java
@@ -0,0 +1,77 @@
+package com.baeldung.genericarrays;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.IntFunction;
+import java.util.stream.Stream;
+
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class StreamToArrayUnitTest {
+
+ @Test
+ public void givenAStream_thenCanGetArrayOfObject() {
+ Object[] strings = Stream.of("A", "AAA", "B", "AAB", "C")
+ .filter(string -> string.startsWith("A"))
+ .toArray();
+
+ assertThat(strings).containsExactly("A", "AAA", "AAB");
+ assertThat(strings).isNotInstanceOf(String[].class);
+ }
+
+ @Test
+ public void givenAStream_thenCanGetArrayOfString() {
+ String[] strings = Stream.of("A", "AAA", "B", "AAB", "C")
+ .filter(string -> string.startsWith("A"))
+ .toArray(String[]::new);
+
+ assertThat(strings).containsExactly("A", "AAA", "AAB");
+ assertThat(strings).isInstanceOf(String[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void givenAStream_whenConvertToOptional_thenCanGetArrayOfOptional() {
+ Stream> stream = Stream.of("A", "AAA", "B", "AAB", "C")
+ .filter(string -> string.startsWith("A"))
+ .map(Optional::of);
+ Optional[] strings = stream
+ .toArray(Optional[]::new);
+
+ assertThat(strings).containsExactly(Optional.of("A"),
+ Optional.of("AAA"),
+ Optional.of("AAB"));
+ assertThat(strings).isInstanceOf(Optional[].class);
+ }
+
+ @Test
+ public void givenAStream_whenConvertToOptional_thenCanGetArrayOfOptionalWithHelper() {
+ Optional[] strings = Stream.of("A", "AAA", "B", "AAB", "C")
+ .filter(string -> string.startsWith("A"))
+ .map(Optional::of)
+ .toArray(genericArray(Optional[]::new));
+
+ assertThat(strings).containsExactly(Optional.of("A"),
+ Optional.of("AAA"),
+ Optional.of("AAB"));
+ assertThat(strings).isInstanceOf(Optional[].class);
+ }
+
+ @Test
+ public void whenInvalidUseOfGenericArray_thenIllegalCast() {
+ assertThatThrownBy(() -> {
+ ArrayList[] lists = Stream.of(singletonList("A"))
+ .toArray(genericArray(List[]::new));
+ }).isInstanceOf(ClassCastException.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static IntFunction genericArray(IntFunction arrayCreator) {
+ return size -> (R[])arrayCreator.apply(size);
+ }
+}
diff --git a/core-java-modules/core-java-jvm/pom.xml b/core-java-modules/core-java-jvm/pom.xml
index 08e536998c..17ff2f658f 100644
--- a/core-java-modules/core-java-jvm/pom.xml
+++ b/core-java-modules/core-java-jvm/pom.xml
@@ -77,7 +77,6 @@
3.6.1
3.27.0-GA
- 2.1.0.1
1.8.0
0.10
8.0.1
diff --git a/core-java-modules/core-java-lang-4/README.md b/core-java-modules/core-java-lang-4/README.md
index ff00688772..77d14f0fc8 100644
--- a/core-java-modules/core-java-lang-4/README.md
+++ b/core-java-modules/core-java-lang-4/README.md
@@ -2,4 +2,4 @@
This module contains articles about core features in the Java language
-- TODO
+- [The Java final Keyword – Impact on Performance](https://www.baeldung.com/java-final-performance)
diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java
index b140f7085b..489b85d12d 100644
--- a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java
+++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java
@@ -47,6 +47,7 @@ public class Outer {
// Anonymous Inner class extending a class
public String greet() {
Outer anonymous = new Outer() {
+ @Override
public String greet() {
return "Running Anonymous Class...";
}
@@ -58,6 +59,7 @@ public class Outer {
public String greet(String name) {
HelloWorld helloWorld = new HelloWorld() {
+ @Override
public String greet(String name) {
return "Welcome to " + name;
}
@@ -68,8 +70,9 @@ public class Outer {
// Anonymous inner class implementing nested interface
public String greetSomeone(String name) {
-
+
HelloSomeone helloSomeOne = new HelloSomeone() {
+ @Override
public String greet(String name) {
return "Hello " + name;
}
@@ -94,7 +97,8 @@ interface HelloWorld {
public String greet(String name);
// Nested class within an interface
- class InnerClass {
+ class InnerClass implements HelloWorld {
+ @Override
public String greet(String name) {
return "Inner class within an interface";
}
diff --git a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java
index 7469e8ba64..42cacbd3ea 100644
--- a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java
+++ b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java
@@ -148,48 +148,46 @@ public class BinaryTree {
}
}
-
public void traverseInOrderWithoutRecursion() {
- Stack stack = new Stack();
+ Stack stack = new Stack<>();
+ Node current = root;
+
+ while (current != null || !stack.isEmpty()) {
+ while (current != null) {
+ stack.push(current);
+ current = current.left;
+ }
+
+ Node top = stack.pop();
+ visit(top.value);
+ current = top.right;
+ }
+ }
+
+ public void traversePreOrderWithoutRecursion() {
+ Stack stack = new Stack<>();
Node current = root;
stack.push(root);
- while(! stack.isEmpty()) {
- while(current.left != null) {
- current = current.left;
- stack.push(current);
- }
+
+ while (current != null && !stack.isEmpty()) {
current = stack.pop();
visit(current.value);
- if(current.right != null) {
- current = current.right;
- stack.push(current);
- }
+
+ if (current.right != null)
+ stack.push(current.right);
+
+ if (current.left != null)
+ stack.push(current.left);
}
}
- public void traversePreOrderWithoutRecursion() {
- Stack stack = new Stack();
- Node current = root;
- stack.push(root);
- while(! stack.isEmpty()) {
- current = stack.pop();
- visit(current.value);
-
- if(current.right != null)
- stack.push(current.right);
-
- if(current.left != null)
- stack.push(current.left);
- }
- }
-
public void traversePostOrderWithoutRecursion() {
- Stack stack = new Stack();
+ Stack stack = new Stack<>();
Node prev = root;
Node current = root;
stack.push(root);
- while (!stack.isEmpty()) {
+ while (current != null && !stack.isEmpty()) {
current = stack.peek();
boolean hasChild = (current.left != null || current.right != null);
boolean isPrevLastChild = (prev == current.right || (prev == current.left && current.right == null));
diff --git a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java
index f99cb52ed7..e89557f21b 100644
--- a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java
+++ b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java
@@ -13,7 +13,7 @@ public class BinaryTreeUnitTest {
BinaryTree bt = createBinaryTree();
- assertTrue(!bt.isEmpty());
+ assertFalse(bt.isEmpty());
}
@Test
@@ -72,6 +72,7 @@ public class BinaryTreeUnitTest {
@Test
public void it_deletes_the_root() {
+
int value = 12;
BinaryTree bt = new BinaryTree();
bt.add(value);
@@ -91,6 +92,14 @@ public class BinaryTreeUnitTest {
bt.traverseInOrderWithoutRecursion();
}
+ @Test
+ public void givenAnEmptyBinaryTree_WhenTraversingInOrderWithoutRecursion_ThenNoException() {
+
+ BinaryTree empty = new BinaryTree();
+
+ empty.traverseInOrderWithoutRecursion();
+ }
+
@Test
public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() {
@@ -101,6 +110,14 @@ public class BinaryTreeUnitTest {
bt.traversePreOrderWithoutRecursion();
}
+ @Test
+ public void givenAnEmptyBinaryTree_WhenTraversingPreOrderWithoutRecursion_ThenNoException() {
+
+ BinaryTree empty = new BinaryTree();
+
+ empty.traversePreOrderWithoutRecursion();
+ }
+
@Test
public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() {
@@ -111,6 +128,14 @@ public class BinaryTreeUnitTest {
bt.traversePostOrderWithoutRecursion();
}
+ @Test
+ public void givenAnEmptyBinaryTree_WhenTraversingPostOrderWithoutRecursion_ThenNoException() {
+
+ BinaryTree empty = new BinaryTree();
+
+ empty.traversePostOrderWithoutRecursion();
+ }
+
@Test
public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() {
diff --git a/jjwt/README.md b/jjwt/README.md
index 25f5a8f6f0..1798d5193b 100644
--- a/jjwt/README.md
+++ b/jjwt/README.md
@@ -47,3 +47,4 @@ Available commands (assumes httpie - https://github.com/jkbrzt/httpie):
## Relevant articles:
- [Supercharge Java Authentication with JSON Web Tokens (JWTs)](https://www.baeldung.com/java-json-web-tokens-jjwt)
+- [Decode a JWT Token in Java](https://www.baeldung.com/java-jwt-token-decode)
diff --git a/jjwt/pom.xml b/jjwt/pom.xml
index aa238fafb5..9d38d1b0e9 100644
--- a/jjwt/pom.xml
+++ b/jjwt/pom.xml
@@ -41,6 +41,12 @@
jjwt
${jjwt.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java
new file mode 100644
index 0000000000..922d5c0ce5
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java
@@ -0,0 +1,46 @@
+package io.jsonwebtoken.jjwtfun.util;
+
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator;
+
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Base64;
+
+import static io.jsonwebtoken.SignatureAlgorithm.HS256;
+
+public class JWTDecoderUtil {
+
+ public static String decodeJWTToken(String token) {
+ Base64.Decoder decoder = Base64.getDecoder();
+
+ String[] chunks = token.split("\\.");
+
+ String header = new String(decoder.decode(chunks[0]));
+ String payload = new String(decoder.decode(chunks[1]));
+
+ return header + " " + payload;
+ }
+
+ public static String decodeJWTToken(String token, String secretKey) throws Exception {
+ Base64.Decoder decoder = Base64.getDecoder();
+
+ String[] chunks = token.split("\\.");
+
+ String header = new String(decoder.decode(chunks[0]));
+ String payload = new String(decoder.decode(chunks[1]));
+
+ String tokenWithoutSignature = chunks[0] + "." + chunks[1];
+ String signature = chunks[2];
+
+ SignatureAlgorithm sa = HS256;
+ SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());
+
+ DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
+
+ if (!validator.isValid(tokenWithoutSignature, signature)) {
+ throw new Exception("Could not verify JWT token integrity!");
+ }
+
+ return header + " " + payload;
+ }
+}
diff --git a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java
new file mode 100644
index 0000000000..3103a6c8a3
--- /dev/null
+++ b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java
@@ -0,0 +1,32 @@
+package io.jsonwebtoken.jjwtfun.util;
+
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class JWTDecoderUtilUnitTest {
+
+ private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9";
+ private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE";
+
+ @Test
+ void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() {
+ assertThat(JWTDecoderUtil.decodeJWTToken(SIMPLE_TOKEN))
+ .contains(SignatureAlgorithm.HS256.getValue());
+ }
+
+ @Test
+ void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() {
+ assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET"))
+ .hasMessage("Could not verify JWT token integrity!");
+ }
+
+ @Test
+ void givenSignedToken_whenDecodingWithValidSecret_thenIntegrityIsValidated() throws Exception {
+ assertThat(JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "MySecretKey"))
+ .contains("Baeldung User");
+ }
+}
diff --git a/kubernetes/k8s-intro/README.md b/kubernetes/k8s-intro/README.md
index 37ca5f3686..0055e8a27c 100644
--- a/kubernetes/k8s-intro/README.md
+++ b/kubernetes/k8s-intro/README.md
@@ -10,4 +10,8 @@ An easy way to check that everything is working as expected is issuing any *kube
```shell
$ kubectl get nodes
```
-If you get a valid response, then you're good to go.
\ No newline at end of file
+If you get a valid response, then you're good to go.
+
+### Relevant Articles:
+
+- [Paging and Async Calls with the Kubernetes API](https://www.baeldung.com/java-kubernetes-paging-async)
diff --git a/kubernetes/k8s-intro/pom.xml b/kubernetes/k8s-intro/pom.xml
index 26d6a872d4..4a5bb09711 100644
--- a/kubernetes/k8s-intro/pom.xml
+++ b/kubernetes/k8s-intro/pom.xml
@@ -16,6 +16,12 @@
client-java
11.0.0
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.3
+
diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java
new file mode 100644
index 0000000000..fbc2662170
--- /dev/null
+++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java
@@ -0,0 +1,11 @@
+package com.baeldung.kubernetes.intro;
+
+import io.kubernetes.client.openapi.ApiCallback;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import okhttp3.Call;
+
+@FunctionalInterface
+public interface ApiInvoker {
+ Call apply(CoreV1Api api, ApiCallback callback) throws ApiException;
+}
diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java
new file mode 100644
index 0000000000..d9c29dcb64
--- /dev/null
+++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java
@@ -0,0 +1,74 @@
+package com.baeldung.kubernetes.intro;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.function.BiFunction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.kubernetes.client.openapi.ApiCallback;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import okhttp3.Call;
+
+public class AsyncHelper implements ApiCallback {
+
+ private static final Logger log = LoggerFactory.getLogger(AsyncHelper.class);
+
+ private CoreV1Api api;
+ private CompletableFuture callResult;
+
+ private AsyncHelper(CoreV1Api api) {
+ this.api = api;
+ }
+
+ public static CompletableFuture doAsync(CoreV1Api api, ApiInvoker invoker) {
+
+ AsyncHelper p = new AsyncHelper<>(api);
+ return p.execute(invoker);
+ }
+
+ private CompletableFuture execute( ApiInvoker invoker) {
+
+ try {
+ callResult = new CompletableFuture<>();
+ log.info("[I38] Calling API...");
+ final Call call = invoker.apply(api,this);
+ log.info("[I41] API Succesfully invoked: method={}, url={}",
+ call.request().method(),
+ call.request().url());
+ return callResult;
+ }
+ catch(ApiException aex) {
+ callResult.completeExceptionally(aex);
+ return callResult;
+ }
+ }
+
+ @Override
+ public void onFailure(ApiException e, int statusCode, Map> responseHeaders) {
+ log.error("[E53] onFailure",e);
+ callResult.completeExceptionally(e);
+ }
+
+ @Override
+ public void onSuccess(R result, int statusCode, Map> responseHeaders) {
+ log.error("[E61] onSuccess: statusCode={}",statusCode);
+ callResult.complete(result);
+ }
+
+ @Override
+ public void onUploadProgress(long bytesWritten, long contentLength, boolean done) {
+ log.info("[E61] onUploadProgress: bytesWritten={}, contentLength={}, done={}",bytesWritten,contentLength,done);
+ }
+
+ @Override
+ public void onDownloadProgress(long bytesRead, long contentLength, boolean done) {
+ log.info("[E75] onDownloadProgress: bytesRead={}, contentLength={}, done={}",bytesRead,contentLength,done);
+ }
+}
+
diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java
new file mode 100644
index 0000000000..acd4512196
--- /dev/null
+++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java
@@ -0,0 +1,50 @@
+/**
+ *
+ */
+package com.baeldung.kubernetes.intro;
+
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import io.kubernetes.client.openapi.models.V1NodeList;
+import io.kubernetes.client.util.Config;
+
+/**
+ * @author Philippe
+ *
+ */
+public class ListNodesAsync {
+
+ private static Logger log = LoggerFactory.getLogger(ListNodesAsync.class);
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception {
+
+ // Initial setup
+ ApiClient client = Config.defaultClient();
+ CoreV1Api api = new CoreV1Api(client);
+
+ // Start async call
+ CompletableFuture p = AsyncHelper.doAsync(api,(capi,cb) ->
+ capi.listNodeAsync(null, null, null, null, null, null, null, null, 10, false, cb)
+ );
+
+ p.thenAcceptAsync((nodeList) -> {
+ log.info("[I40] Processing results...");
+ nodeList.getItems()
+ .stream()
+ .forEach((node) -> System.out.println(node.getMetadata()));
+ });
+
+ log.info("[I46] Waiting results...");
+ p.get(10, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java
new file mode 100644
index 0000000000..1c160ae607
--- /dev/null
+++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java
@@ -0,0 +1,46 @@
+/**
+ *
+ */
+package com.baeldung.kubernetes.intro;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import io.kubernetes.client.openapi.models.V1NodeList;
+import io.kubernetes.client.openapi.models.V1PodList;
+import io.kubernetes.client.util.Config;
+
+/**
+ * @author Philippe
+ *
+ */
+public class ListPodsPaged {
+
+ private static final Logger log = LoggerFactory.getLogger(ListPodsPaged.class);
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception {
+
+ ApiClient client = Config.defaultClient();
+ CoreV1Api api = new CoreV1Api(client);
+ String continuationToken = null;
+ int limit = 2; // Just for illustration purposes. Real world values would range from ~100 to ~1000/page
+ Long remaining = null;
+ do {
+ log.info("==========================================================================");
+ log.info("Retrieving data: continuationToken={}, remaining={}", continuationToken,remaining);
+ V1PodList items = api.listPodForAllNamespaces(null, continuationToken, null, null, limit, null, null, null, 10, false);
+ continuationToken = items.getMetadata().getContinue();
+ remaining = items.getMetadata().getRemainingItemCount();
+ items.getItems()
+ .stream()
+ .forEach((node) -> System.out.println(node.getMetadata()));
+ } while( continuationToken != null );
+ }
+
+}
diff --git a/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java
new file mode 100644
index 0000000000..af32df8224
--- /dev/null
+++ b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java
@@ -0,0 +1,10 @@
+package com.baeldung.kubernetes.intro;
+
+import org.junit.jupiter.api.Test;
+
+class ListNodesAsyncLiveTest {
+ @Test
+ void whenListNodes_thenSuccess() throws Exception {
+ ListNodesAsync.main(new String[] {});
+ }
+}
diff --git a/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java
new file mode 100644
index 0000000000..6fb3c5b32d
--- /dev/null
+++ b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java
@@ -0,0 +1,10 @@
+package com.baeldung.kubernetes.intro;
+
+import org.junit.jupiter.api.Test;
+
+class ListPodsPagedLiveTest {
+ @Test
+ void whenListPodsPage_thenSuccess() throws Exception {
+ ListPodsPaged.main(new String[] {});
+ }
+}
diff --git a/kubernetes/k8s-intro/src/test/resources/logback.xml b/kubernetes/k8s-intro/src/test/resources/logback.xml
new file mode 100644
index 0000000000..479545e643
--- /dev/null
+++ b/kubernetes/k8s-intro/src/test/resources/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml
index ace3e538c9..f5bf8784a9 100644
--- a/parent-boot-2/pom.xml
+++ b/parent-boot-2/pom.xml
@@ -82,7 +82,7 @@
3.3.0
1.0.22.RELEASE
- 2.4.0
+ 2.4.3
1.9.1
3.4.0
diff --git a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
index 099864589c..03bed5fedf 100644
--- a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
+++ b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java
@@ -38,8 +38,8 @@ public class UsingOptional {
.flatMap(list -> list.stream().findFirst());
}
- private Optional getOptionalList() {
- return Optional.ofNullable(getList());
+ private Optional> getOptionalList() {
+ return Optional.of(getList());
}
private String doSomething(boolean processed) {
diff --git a/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java b/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java
index 73797d48c8..576d2bacf3 100644
--- a/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java
+++ b/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java
@@ -19,22 +19,22 @@ class UsingOptionalUnitTest {
}
@Test
- public void whenArgIsFalse_thenReturnEmptyResponse() {
+ void whenArgIsFalse_thenReturnEmptyResponse() {
Optional
diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md
index 29d9dafe66..875ee502b4 100644
--- a/spring-boot-modules/spring-boot-data-2/README.md
+++ b/spring-boot-modules/spring-boot-data-2/README.md
@@ -2,3 +2,4 @@
- [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper)
- [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found)
+- [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository)
diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java
new file mode 100644
index 0000000000..ff0a8a1bb3
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java
@@ -0,0 +1,39 @@
+package com.baeldung.boot.readonlyrepository;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Book
+{
+ @Id
+ @GeneratedValue
+ private Long id;
+ private String author;
+ private String title;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java
new file mode 100644
index 0000000000..6327ef5a56
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java
@@ -0,0 +1,10 @@
+package com.baeldung.boot.readonlyrepository;
+
+import java.util.List;
+
+public interface BookReadOnlyRepository extends ReadOnlyRepository {
+
+ List findByAuthor(String author);
+
+ List findByTitle(String title);
+}
diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java
new file mode 100644
index 0000000000..16f3fd429e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java
@@ -0,0 +1,15 @@
+package com.baeldung.boot.readonlyrepository;
+
+import org.springframework.data.repository.NoRepositoryBean;
+import org.springframework.data.repository.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+@NoRepositoryBean
+public interface ReadOnlyRepository extends Repository {
+
+ Optional findById(ID id);
+
+ List findAll();
+}
diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java
new file mode 100644
index 0000000000..f5a67197ad
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.boot.readonlyrepository;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ReadOnlyRepositoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ReadOnlyRepositoryApplication.class, args);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java
new file mode 100644
index 0000000000..363b310c8c
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java
@@ -0,0 +1,6 @@
+package com.baeldung.boot.readonlyrepository;
+
+import org.springframework.data.repository.CrudRepository;
+
+public interface BookRepository extends BookReadOnlyRepository, CrudRepository {
+}
diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java
new file mode 100644
index 0000000000..cdb6065f23
--- /dev/null
+++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.boot.readonlyrepository;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+
+@SpringBootTest( classes = ReadOnlyRepositoryApplication.class )
+public class ReadOnlyRepositoryUnitTest
+{
+ @Autowired
+ private BookRepository bookRepository;
+
+ @Autowired
+ private BookReadOnlyRepository bookReadOnlyRepository;
+
+ @Test
+ public void givenBooks_whenUsingReadOnlyRepository_thenGetThem() {
+ Book aChristmasCarolCharlesDickens = new Book();
+ aChristmasCarolCharlesDickens.setTitle("A Christmas Carol");
+ aChristmasCarolCharlesDickens.setAuthor("Charles Dickens");
+ bookRepository.save(aChristmasCarolCharlesDickens);
+
+ Book greatExpectationsCharlesDickens = new Book();
+ greatExpectationsCharlesDickens.setTitle("Great Expectations");
+ greatExpectationsCharlesDickens.setAuthor("Charles Dickens");
+ bookRepository.save(greatExpectationsCharlesDickens);
+
+ Book greatExpectationsKathyAcker = new Book();
+ greatExpectationsKathyAcker.setTitle("Great Expectations");
+ greatExpectationsKathyAcker.setAuthor("Kathy Acker");
+ bookRepository.save(greatExpectationsKathyAcker);
+
+ List charlesDickensBooks = bookReadOnlyRepository.findByAuthor("Charles Dickens");
+ Assertions.assertEquals(2, charlesDickensBooks.size());
+
+ List greatExpectationsBooks = bookReadOnlyRepository.findByTitle("Great Expectations");
+ Assertions.assertEquals(2, greatExpectationsBooks.size());
+
+ List allBooks = bookReadOnlyRepository.findAll();
+ Assertions.assertEquals(3, allBooks.size());
+
+ Long bookId = allBooks.get(0).getId();
+ Book book = bookReadOnlyRepository.findById(bookId).orElseThrow(NoSuchElementException::new);
+ Assertions.assertNotNull(book);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml
index 94a4018103..ae546016f2 100644
--- a/spring-boot-modules/spring-boot-deployment/pom.xml
+++ b/spring-boot-modules/spring-boot-deployment/pom.xml
@@ -84,12 +84,6 @@
${jquery.version}
-
- org.springframework.cloud
- spring-cloud-context
- ${springcloud.version}
-
-
org.apache.httpcomponents
httpclient
@@ -195,9 +189,7 @@
2.2
18.0
3.1.7
- 2.0.2.RELEASE
4.5.8
- 2.3.3.RELEASE
diff --git a/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java
index 6dcbfe390f..8467a25acd 100644
--- a/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java
+++ b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java
@@ -1,34 +1,35 @@
package com.baeldung.charencoding.controller;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.io.IOException;
+import org.junit.jupiter.api.Test;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.web.filter.CharacterEncodingFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
-import org.junit.jupiter.api.Test;
-import org.springframework.web.filter.CharacterEncodingFilter;
+import static org.junit.jupiter.api.Assertions.assertEquals;
class CharEncodingCheckControllerUnitTest {
@Test
void whenCharEncodingFilter_thenVerifyEncoding() throws ServletException, IOException {
- HttpServletRequest request = mock(HttpServletRequest.class);
- HttpServletResponse response = mock(HttpServletResponse.class);
- FilterChain chain = mock(FilterChain.class);
-
+ HttpServletRequest request = new MockHttpServletRequest();
+ HttpServletResponse response = new MockHttpServletResponse();
+ FilterChain chain = new MockFilterChain();
+
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
-
+
filter.doFilter(request, response, chain);
-
- verify(request).setCharacterEncoding("UTF-8");
- verify(response).setCharacterEncoding("UTF-8");
+
+ assertEquals("UTF-8", request.getCharacterEncoding());
+ assertEquals("UTF-8", response.getCharacterEncoding());
}
}
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java
index 8040c93ee0..e02d1de272 100644
--- a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java
@@ -2,6 +2,7 @@ package com.baeldung.boot.properties.multidocument;
import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@@ -21,6 +22,7 @@ public class StagingMultidocumentFilesIntegrationTest {
private String baelRootProperty;
@Test
+ @Disabled("Fix and update https://www.baeldung.com/spring-boot-yaml-vs-properties article")
public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
assertThat(baelCustomProperty).isEqualTo("stagingValue");
assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
diff --git a/spring-boot-rest-2/README.md b/spring-boot-rest-2/README.md
new file mode 100644
index 0000000000..f09159198c
--- /dev/null
+++ b/spring-boot-rest-2/README.md
@@ -0,0 +1,3 @@
+### Relevant Article:
+
+- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints)
diff --git a/spring-boot-rest-2/pom.xml b/spring-boot-rest-2/pom.xml
new file mode 100644
index 0000000000..d74c393f27
--- /dev/null
+++ b/spring-boot-rest-2/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+ com.baeldung.web
+ spring-boot-rest-2
+ spring-boot-rest-2
+ war
+ Spring Boot Rest Module
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ io.springfox
+ springfox-boot-starter
+ 3.0.0
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java
new file mode 100644
index 0000000000..510e208f9e
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.endpoint;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootRestApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootRestApplication.class, args);
+ }
+}
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java
new file mode 100644
index 0000000000..732b298981
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java
@@ -0,0 +1,15 @@
+package com.baeldung.endpoint.controller;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @GetMapping("/hello")
+ public ResponseEntity hello() {
+ return ResponseEntity.ok("hello baeldung");
+ }
+
+}
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java
new file mode 100644
index 0000000000..c57f6b5ecd
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java
@@ -0,0 +1,27 @@
+package com.baeldung.endpoint.listener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.context.event.EventListener;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.Map;
+
+@Configuration
+public class AnnotationDrivenEndpointsListener {
+ private final Logger LOGGER = LoggerFactory.getLogger("AnnotationDrivenEndpointsListener.class");
+
+ @EventListener
+ public void handleContextRefresh(ContextRefreshedEvent event) {
+ ApplicationContext applicationContext = event.getApplicationContext();
+ RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext
+ .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
+ Map map = requestMappingHandlerMapping.getHandlerMethods();
+ map.forEach((key, value) -> LOGGER.info("{} {}", key, value));
+ }
+}
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java
new file mode 100644
index 0000000000..ae00fc3927
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java
@@ -0,0 +1,27 @@
+package com.baeldung.endpoint.listener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.Map;
+
+@Configuration
+public class EndpointsListener implements ApplicationListener {
+ private final Logger LOGGER = LoggerFactory.getLogger("EndpointsListener.class");
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ ApplicationContext applicationContext = event.getApplicationContext();
+ RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext
+ .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
+ Map map = requestMappingHandlerMapping.getHandlerMethods();
+ map.forEach((key, value) -> LOGGER.info("{} {}", key, value));
+ }
+}
diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java
new file mode 100644
index 0000000000..bd258122cd
--- /dev/null
+++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java
@@ -0,0 +1,21 @@
+package com.baeldung.endpoint.swagger;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+@Configuration
+public class SpringFoxConfig {
+
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.any())
+ .paths(PathSelectors.any())
+ .build();
+ }
+}
diff --git a/spring-boot-rest-2/src/main/resources/application.properties b/spring-boot-rest-2/src/main/resources/application.properties
new file mode 100644
index 0000000000..5046c9660f
--- /dev/null
+++ b/spring-boot-rest-2/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+
+management.endpoints.web.exposure.include=mappings
diff --git a/spring-caching/pom.xml b/spring-caching/pom.xml
index f58be35a76..9fa9ba0333 100644
--- a/spring-caching/pom.xml
+++ b/spring-caching/pom.xml
@@ -79,7 +79,6 @@
org.springframework.data
spring-data-commons
- 2.3.0.RELEASE
diff --git a/spring-cloud/spring-cloud-zuul/pom.xml b/spring-cloud/spring-cloud-zuul/pom.xml
index 6035ba7e59..13834848fe 100644
--- a/spring-cloud/spring-cloud-zuul/pom.xml
+++ b/spring-cloud/spring-cloud-zuul/pom.xml
@@ -38,6 +38,11 @@
pom
import
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-zuul
+ ${spring-cloud-netflix-zuul.version}
+
@@ -46,10 +51,6 @@
org.springframework.boot
spring-boot-starter-web
-
- org.springframework.cloud
- spring-cloud-starter-netflix-zuul
-
com.h2database
h2
@@ -79,8 +80,8 @@
- Hoxton.SR4
- 2.3.3.RELEASE
+ 2020.0.0
+ 2.2.2.RELEASE
diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
index b42d32b6b3..bb735a71ed 100644
--- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
+++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml
@@ -19,6 +19,10 @@
spring-cloud-zuul-ratelimit
${rate.limit.version}
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-zuul
+
org.springframework.boot
spring-boot-starter-data-jpa
diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml
index 7978d9c77b..b7e1702558 100644
--- a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml
+++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml
@@ -13,6 +13,10 @@
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-zuul
+
org.springframework.boot
spring-boot-starter-thymeleaf
diff --git a/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java
new file mode 100644
index 0000000000..b29f9ab0ce
--- /dev/null
+++ b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java
@@ -0,0 +1,45 @@
+package com.baeldung.scheduling.dynamic;
+
+import java.time.Instant;
+import java.util.Date;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+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.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+
+@Configuration
+@ComponentScan("com.baeldung.scheduling.dynamic")
+@EnableScheduling
+public class DynamicSchedulingConfig implements SchedulingConfigurer {
+
+ @Autowired
+ private TickService tickService;
+
+ @Bean
+ public Executor taskExecutor() {
+ return Executors.newSingleThreadScheduledExecutor();
+ }
+
+ @Override
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+ taskRegistrar.setScheduler(taskExecutor());
+ taskRegistrar.addTriggerTask(
+ () -> tickService.tick(),
+ context -> {
+ Optional lastCompletionTime =
+ Optional.ofNullable(context.lastCompletionTime());
+ Instant nextExecutionTime =
+ lastCompletionTime.orElseGet(Date::new).toInstant()
+ .plusMillis(tickService.getDelay());
+ return Date.from(nextExecutionTime);
+ }
+ );
+ }
+
+}
diff --git a/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java
new file mode 100644
index 0000000000..5da56f33a9
--- /dev/null
+++ b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java
@@ -0,0 +1,22 @@
+package com.baeldung.scheduling.dynamic;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class TickService {
+
+ private long delay = 0;
+
+ public long getDelay() {
+ this.delay += 1000;
+ System.out.println("delaying " + this.delay + " milliseconds...");
+ return this.delay;
+ }
+
+ public void tick() {
+ final long now = System.currentTimeMillis() / 1000;
+ System.out
+ .println("schedule tasks with dynamic delay - " + now);
+ }
+
+}
diff --git a/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java b/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java
new file mode 100644
index 0000000000..2ff9cfaefa
--- /dev/null
+++ b/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.scheduling;
+
+import com.baeldung.scheduling.dynamic.DynamicSchedulingConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {
+ DynamicSchedulingConfig.class}, loader = AnnotationConfigContextLoader.class)
+public class DynamicSchedulingIntegrationTest {
+
+ @Test
+ public void testTickServiceTick() throws InterruptedException {
+ Thread.sleep(6000);
+ }
+}
diff --git a/spring-security-modules/spring-5-security/pom.xml b/spring-security-modules/spring-5-security/pom.xml
index f50b5ff7a9..d009115c92 100644
--- a/spring-security-modules/spring-5-security/pom.xml
+++ b/spring-security-modules/spring-5-security/pom.xml
@@ -49,7 +49,7 @@
org.owasp.esapi
esapi
- 2.2.2.0
+ ${esapi.version}
org.jsoup
diff --git a/spring-web-modules/spring-mvc-java-2/README.md b/spring-web-modules/spring-mvc-java-2/README.md
index 41ff7bdf7c..74d8cca312 100644
--- a/spring-web-modules/spring-mvc-java-2/README.md
+++ b/spring-web-modules/spring-mvc-java-2/README.md
@@ -6,4 +6,4 @@
- [A Quick Guide to Spring MVC Matrix Variables](https://www.baeldung.com/spring-mvc-matrix-variables)
- [Converting a Spring MultipartFile to a File](https://www.baeldung.com/spring-multipartfile-to-file)
- [Testing a Spring Multipart POST Request](https://www.baeldung.com/spring-multipart-post-request-test)
-- [Spring @Pathvariable Annotation](https://www.baeldung.com/spring-pathvariable)
+- [Spring @PathVariable Annotation](https://www.baeldung.com/spring-pathvariable)
diff --git a/testing-modules/mockito-3/.gitignore b/testing-modules/mockito-3/.gitignore
new file mode 100644
index 0000000000..38fe5148c1
--- /dev/null
+++ b/testing-modules/mockito-3/.gitignore
@@ -0,0 +1,4 @@
+/target/
+/.settings/
+/.classpath
+/.project
\ No newline at end of file
diff --git a/testing-modules/mockito-3/pom.xml b/testing-modules/mockito-3/pom.xml
new file mode 100644
index 0000000000..8d506561ed
--- /dev/null
+++ b/testing-modules/mockito-3/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+ mockito-3
+ 0.0.1-SNAPSHOT
+ mockito-3
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+
+
+ org.mockito
+ mockito-inline
+ ${mockito.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ 3.8.0
+ 3.8.0
+
+
+
diff --git a/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java b/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java
new file mode 100644
index 0000000000..2e2f5ead33
--- /dev/null
+++ b/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java
@@ -0,0 +1,22 @@
+package com.baeldung.mockito.mockedstatic;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class StaticUtils {
+
+ private StaticUtils() {
+ }
+
+ public static List range(int start, int end) {
+ return IntStream.range(start, end)
+ .boxed()
+ .collect(Collectors.toList());
+ }
+
+ public static String name() {
+ return "Baeldung";
+ }
+
+}
diff --git a/testing-modules/mockito-3/src/main/resources/logback.xml b/testing-modules/mockito-3/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/testing-modules/mockito-3/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java b/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java
new file mode 100644
index 0000000000..a212e6e3eb
--- /dev/null
+++ b/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.mockito.mockedstatic;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.Arrays;
+
+class MockedStaticUnitTest {
+
+ @Test
+ void givenStaticMethodWithNoArgs_whenMocked_thenReturnsMockSuccessfully() {
+ assertThat(StaticUtils.name()).isEqualTo("Baeldung");
+
+ try (MockedStatic utilities = Mockito.mockStatic(StaticUtils.class)) {
+ utilities.when(StaticUtils::name).thenReturn("Eugen");
+ assertThat(StaticUtils.name()).isEqualTo("Eugen");
+ }
+
+ assertThat(StaticUtils.name()).isEqualTo("Baeldung");
+ }
+
+ @Test
+ void givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() {
+ assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
+
+ try (MockedStatic utilities = Mockito.mockStatic(StaticUtils.class)) {
+ utilities.when(() -> StaticUtils.range(2, 6))
+ .thenReturn(Arrays.asList(10, 11, 12));
+
+ assertThat(StaticUtils.range(2, 6)).containsExactly(10, 11, 12);
+ }
+
+ assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
+ }
+
+}
diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml
index fd4a13d026..c0c28e085d 100644
--- a/testing-modules/pom.xml
+++ b/testing-modules/pom.xml
@@ -23,7 +23,8 @@
junit5-migration
load-testing-comparison
mockito
- mockito-2
+ mockito-2
+ mockito-3
hamcrest
mocks
mockserver
diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml
index 9e0c986bb2..74d55d4c08 100644
--- a/testing-modules/spring-testing/pom.xml
+++ b/testing-modules/spring-testing/pom.xml
@@ -125,7 +125,7 @@
3.1.6
5.7.0
1.7.0
- 5.3.0
+ 5.3.4
4.0.1
2.1.1
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java
index 9b692edd7b..9481c54b48 100644
--- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java
+++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java
@@ -1,15 +1,14 @@
package com.baeldung.overrideproperties;
import com.baeldung.overrideproperties.resolver.PropertySourceResolver;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-@RunWith(SpringRunner.class)
+@SpringBootTest
@ContextConfiguration(initializers = PropertyOverrideContextInitializer.class, classes = Application.class)
public class ContextPropertySourceResolverIntegrationTest {
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java
index 815b628f0a..77b882d3a2 100644
--- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java
+++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java
@@ -1,18 +1,17 @@
package com.baeldung.overrideproperties;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.baeldung.overrideproperties.resolver.PropertySourceResolver;
-@RunWith(SpringRunner.class)
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
@SpringBootTest
@ActiveProfiles("test")
@EnableWebMvc
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java
index a8c4267c5c..994a8a4288 100644
--- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java
+++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java
@@ -12,6 +12,6 @@ public class PropertyOverrideContextInitializer implements ApplicationContextIni
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(configurableApplicationContext, "example.firstProperty=" + PROPERTY_FIRST_VALUE);
- TestPropertySourceUtils.addPropertiesFilesToEnvironment(configurableApplicationContext, "context-override-application.properties");
+ TestPropertySourceUtils.addPropertiesFilesToEnvironment(configurableApplicationContext, "classpath:context-override-application.properties");
}
}
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java
index d00aa51e6c..bb08d701d9 100644
--- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java
+++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java
@@ -1,16 +1,16 @@
package com.baeldung.overrideproperties;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.baeldung.overrideproperties.resolver.PropertySourceResolver;
-@RunWith(SpringRunner.class)
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
@SpringBootTest(properties = { "example.firstProperty=annotation" })
@EnableWebMvc
public class SpringBootPropertySourceResolverIntegrationTest {
@@ -23,8 +23,8 @@ public class SpringBootPropertySourceResolverIntegrationTest {
final String firstProperty = propertySourceResolver.getFirstProperty();
final String secondProperty = propertySourceResolver.getSecondProperty();
- Assert.assertEquals("annotation", firstProperty);
- Assert.assertEquals("file", secondProperty);
+ assertEquals("annotation", firstProperty);
+ assertEquals("file", secondProperty);
}
}
\ No newline at end of file
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java
index dc15851277..673742124a 100644
--- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java
+++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java
@@ -1,17 +1,16 @@
package com.baeldung.overrideproperties;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.baeldung.overrideproperties.resolver.PropertySourceResolver;
-@RunWith(SpringRunner.class)
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
@SpringBootTest
@EnableWebMvc
public class TestResourcePropertySourceResolverIntegrationTest {