diff --git a/algorithms/README.md b/algorithms/README.md
index 5f101c296c..3401b6d935 100644
--- a/algorithms/README.md
+++ b/algorithms/README.md
@@ -15,3 +15,4 @@
- [Introduction to JGraphT](http://www.baeldung.com/jgrapht)
- [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm)
- [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance)
+- [How to Find the Kth Largest Element in Java](http://www.baeldung.com/java-kth-largest-element)
diff --git a/core-java/src/main/java/com/baeldung/staticclass/Pizza.java b/core-java/src/main/java/com/baeldung/staticclass/Pizza.java
new file mode 100644
index 0000000000..ee6283cee1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/staticclass/Pizza.java
@@ -0,0 +1,33 @@
+package com.baeldung.staticclass;
+
+public class Pizza {
+
+ private static String cookedCount;
+ private boolean isThinCrust;
+
+ // Accessible globally
+ public static class PizzaSalesCounter {
+
+ private static String orderedCount;
+ public static String deliveredCount;
+
+ PizzaSalesCounter() {
+ System.out.println("Static field of enclosing class is "
+ + Pizza.cookedCount);
+ System.out.println("Non-static field of enclosing class is "
+ + new Pizza().isThinCrust);
+ }
+ }
+
+ Pizza() {
+ System.out.println("Non private static field of static class is "
+ + PizzaSalesCounter.deliveredCount);
+ System.out.println("Private static field of static class is "
+ + PizzaSalesCounter.orderedCount);
+ }
+
+ public static void main(String[] a) {
+ // Create instance of the static class without an instance of enclosing class
+ new Pizza.PizzaSalesCounter();
+ }
+}
diff --git a/java-vavr-stream/pom.xml b/java-vavr-stream/pom.xml
new file mode 100644
index 0000000000..ca3807cd15
--- /dev/null
+++ b/java-vavr-stream/pom.xml
@@ -0,0 +1,20 @@
+
+
+ 4.0.0
+ com.baeldung.samples
+ java-vavr-stream
+ 1.0
+ jar
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+ io.vavr
+ vavr
+ 0.9.2
+
+
+
\ No newline at end of file
diff --git a/java-vavr-stream/src/main/java/com/baeldung/samples/java/vavr/VavrSampler.java b/java-vavr-stream/src/main/java/com/baeldung/samples/java/vavr/VavrSampler.java
new file mode 100644
index 0000000000..d539342f69
--- /dev/null
+++ b/java-vavr-stream/src/main/java/com/baeldung/samples/java/vavr/VavrSampler.java
@@ -0,0 +1,98 @@
+package com.baeldung.samples.java.vavr;
+
+import io.vavr.collection.Stream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+
+/**
+ *
+ * @author baeldung
+ */
+public class VavrSampler {
+
+ static int[] intArray = new int[]{1, 2, 4};
+ static List intList = new ArrayList();
+ static int[][] intOfInts = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
+
+ public static void main(String[] args) {
+ vavrStreamElementAccess();
+ System.out.println("====================================");
+ vavrParallelStreamAccess();
+ System.out.println("====================================");
+ jdkFlatMapping();
+ System.out.println("====================================");
+ vavrStreamManipulation();
+ System.out.println("====================================");
+ vavrStreamDistinct();
+ }
+
+ public static void vavrStreamElementAccess() {
+ System.out.println("Vavr Element Access");
+ System.out.println("====================================");
+ Stream vavredStream = Stream.ofAll(intArray);
+ System.out.println("Vavr index access: " + vavredStream.get(2));
+ System.out.println("Vavr head element access: " + vavredStream.get());
+
+ Stream vavredStringStream = Stream.of("foo", "bar", "baz");
+ System.out.println("Find foo " + vavredStringStream.indexOf("foo"));
+ }
+
+ public static void vavrParallelStreamAccess() {
+ try {
+ System.out.println("Vavr Stream Concurrent Modification");
+ System.out.println("====================================");
+ Stream vavrStream = Stream.ofAll(intList);
+ intList.add(5);
+ vavrStream.forEach(i -> System.out.println("in a Vavr Stream: " + i));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ Stream wrapped = Stream.ofAll(intArray);
+ intArray[2] = 5;
+ wrapped.forEach(i -> System.out.println("Vavr looped " + i));
+ }
+
+ public static void jdkFlatMapping() {
+ System.out.println("JDK FlatMap -> Uncomment line 68 to test");
+ System.out.println("====================================");
+ int[][] intOfInts = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
+
+ IntStream mapToInt = Arrays.stream(intOfInts)
+ .map(intArr -> Arrays.stream(intArr))
+ .flatMapToInt(val -> val.map(n -> {
+ return n * n;
+ }))
+ .peek(n -> System.out.println("Peeking at " + n));
+ //Uncomment to execute pipeline
+ //mapToInt.forEach(n -> System.out.println("FlatMapped Result "+n));
+ }
+
+ public static void vavrStreamManipulation() {
+ System.out.println("Vavr Stream Manipulation");
+ System.out.println("====================================");
+ List stringList = new ArrayList<>();
+ stringList.add("foo");
+ stringList.add("bar");
+ stringList.add("baz");
+ Stream vavredStream = Stream.ofAll(stringList);
+ vavredStream.forEach(item -> System.out.println("Vavr Stream item: " + item));
+ Stream vavredStream2 = vavredStream.insert(2, "buzz");
+ vavredStream2.forEach(item -> System.out.println("Vavr Stream item after stream addition: " + item));
+ stringList.forEach(item -> System.out.println("List item after stream addition: " + item));
+ Stream deletionStream = vavredStream.remove("bar");
+ deletionStream.forEach(item -> System.out.println("Vavr Stream item after stream item deletion: " + item));
+
+ }
+
+ public static void vavrStreamDistinct() {
+ Stream vavredStream = Stream.of("foo", "bar", "baz", "buxx", "bar", "bar", "foo");
+ Stream distinctVavrStream = vavredStream.distinctBy((y, z) -> {
+ return y.compareTo(z);
+ });
+ distinctVavrStream.forEach(item -> System.out.println("Vavr Stream item after distinct query " + item));
+
+ }
+}
diff --git a/pom.xml b/pom.xml
index 0d26188082..73f1b27f7e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,7 @@
vavr
java-lite
+ java-vavr-stream
javax-servlets
javaxval
jaxb
@@ -203,7 +204,6 @@
spring-protobuf
spring-quartz
spring-rest-angular
- spring-rest-docs
spring-rest-full
spring-rest-query-language
spring-rest
diff --git a/spring-5/README.md b/spring-5/README.md
index 400e343263..8249fe3813 100644
--- a/spring-5/README.md
+++ b/spring-5/README.md
@@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans)
- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config)
- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive)
-- [Spring 5 Testing with @EnabledIf Annotation](https://github.com/eugenp/tutorials/tree/master/spring-5)
+- [Spring 5 Testing with @EnabledIf Annotation](http://www.baeldung.com/sring-5-enabledif)
+- [Introduction to Spring REST Docs](http://www.baeldung.com/spring-rest-docs)
diff --git a/spring-5/pom.xml b/spring-5/pom.xml
index ac49e8d6f4..4c2df68f1b 100644
--- a/spring-5/pom.xml
+++ b/spring-5/pom.xml
@@ -39,6 +39,14 @@
org.springframework.boot
spring-boot-starter-webflux
+
+ org.springframework.boot
+ spring-boot-starter-hateoas
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
org.projectreactor
reactor-spring
@@ -135,6 +143,23 @@
${junit.platform.version}
test
+
+
+ org.springframework.restdocs
+ spring-restdocs-mockmvc
+ test
+
+
+ org.springframework.restdocs
+ spring-restdocs-webtestclient
+ test
+
+
+ org.springframework.restdocs
+ spring-restdocs-restassured
+ test
+
+
@@ -163,6 +188,29 @@
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+ ${asciidoctor-plugin.version}
+
+
+ generate-docs
+ package
+
+ process-asciidoc
+
+
+ html
+ book
+
+ ${snippetsDirectory}
+
+ src/docs/asciidocs
+ target/generated-docs
+
+
+
+
@@ -199,6 +247,8 @@
1.1.3
1.0
1.0
+ 1.5.6
+ ${project.build.directory}/generated-snippets
diff --git a/spring-rest-docs/src/docs/asciidocs/api-guide.adoc b/spring-5/src/docs/asciidocs/api-guide.adoc
similarity index 82%
rename from spring-rest-docs/src/docs/asciidocs/api-guide.adoc
rename to spring-5/src/docs/asciidocs/api-guide.adoc
index 9fbe74c072..6eadfb5efd 100644
--- a/spring-rest-docs/src/docs/asciidocs/api-guide.adoc
+++ b/spring-5/src/docs/asciidocs/api-guide.adoc
@@ -55,13 +55,6 @@ use of HTTP status codes.
| The requested resource did not exist
|===
-[[overview-headers]]
-== Headers
-
-Every response has the following header(s):
-
-include::{snippets}/headers-example/response-headers.adoc[]
-
[[overview-hypermedia]]
== Hypermedia
@@ -86,18 +79,14 @@ The index provides the entry point into the service.
A `GET` request is used to access the index
-==== Response structure
+==== Request structure
-include::{snippets}/index-example/http-response.adoc[]
+include::{snippets}/index-example/http-request.adoc[]
==== Example response
include::{snippets}/index-example/http-response.adoc[]
-==== Example request
-
-include::{snippets}/index-example/http-request.adoc[]
-
==== CURL request
include::{snippets}/index-example/curl-request.adoc[]
@@ -113,12 +102,12 @@ include::{snippets}/index-example/links.adoc[]
The CRUD provides the entry point into the service.
-[[resources-crud-access]]
+[[resources-crud-get]]
=== Accessing the crud GET
-A `GET` request is used to access the CRUD read
+A `GET` request is used to access the CRUD read.
-==== Response structure
+==== Request structure
include::{snippets}/crud-get-example/http-request.adoc[]
@@ -130,12 +119,12 @@ include::{snippets}/crud-get-example/http-response.adoc[]
include::{snippets}/crud-get-example/curl-request.adoc[]
-[[resources-crud-access]]
+[[resources-crud-post]]
=== Accessing the crud POST
-A `POST` request is used to access the CRUD create
+A `POST` request is used to access the CRUD create.
-==== Response structure
+==== Request structure
include::{snippets}/crud-create-example/http-request.adoc[]
@@ -147,15 +136,18 @@ include::{snippets}/crud-create-example/http-response.adoc[]
include::{snippets}/crud-create-example/curl-request.adoc[]
-[[resources-crud-access]]
+[[resources-crud-delete]]
=== Accessing the crud DELETE
-A `DELETE` request is used to access the CRUD create
+A `DELETE` request is used to access the CRUD delete.
-==== Response structure
+==== Request structure
include::{snippets}/crud-delete-example/http-request.adoc[]
+==== Path Parameters
+include::{snippets}/crud-delete-example/path-parameters.adoc[]
+
==== Example response
include::{snippets}/crud-delete-example/http-response.adoc[]
@@ -164,12 +156,12 @@ include::{snippets}/crud-delete-example/http-response.adoc[]
include::{snippets}/crud-delete-example/curl-request.adoc[]
-[[resources-crud-access]]
+[[resources-crud-patch]]
=== Accessing the crud PATCH
-A `PATCH` request is used to access the CRUD create
+A `PATCH` request is used to access the CRUD update.
-==== Response structure
+==== Request structure
include::{snippets}/crud-patch-example/http-request.adoc[]
@@ -181,12 +173,12 @@ include::{snippets}/crud-patch-example/http-response.adoc[]
include::{snippets}/crud-patch-example/curl-request.adoc[]
-[[resources-crud-access]]
+[[resources-crud-put]]
=== Accessing the crud PUT
-A `PUT` request is used to access the CRUD create
+A `PUT` request is used to access the CRUD update.
-==== Response structure
+==== Request structure
include::{snippets}/crud-put-example/http-request.adoc[]
diff --git a/spring-5/src/main/java/com/baeldung/actuator/DownstreamServiceReactiveHealthIndicator.java b/spring-5/src/main/java/com/baeldung/actuator/DownstreamServiceReactiveHealthIndicator.java
new file mode 100644
index 0000000000..5f36330ff6
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/actuator/DownstreamServiceReactiveHealthIndicator.java
@@ -0,0 +1,23 @@
+package com.baeldung.actuator;
+
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+@Component
+public class DownstreamServiceReactiveHealthIndicator implements ReactiveHealthIndicator {
+
+ @Override
+ public Mono health() {
+ return checkDownstreamServiceHealth().onErrorResume(
+ ex -> Mono.just(new Health.Builder().down(ex).build())
+ );
+ }
+
+ private Mono checkDownstreamServiceHealth() {
+ // we could use WebClient to check health reactively
+ return Mono.just(new Health.Builder().up().build());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-5/src/main/java/com/baeldung/actuator/FeaturesEndpoint.java b/spring-5/src/main/java/com/baeldung/actuator/FeaturesEndpoint.java
new file mode 100644
index 0000000000..2ed32501ae
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/actuator/FeaturesEndpoint.java
@@ -0,0 +1,47 @@
+package com.baeldung.actuator;
+
+import org.springframework.boot.actuate.endpoint.annotation.*;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+@Endpoint(id = "features", enableByDefault = true)
+public class FeaturesEndpoint {
+
+ private Map features = new ConcurrentHashMap<>();
+
+ @ReadOperation
+ public Map features() {
+ return features;
+ }
+
+ @ReadOperation
+ public Feature feature(@Selector String name) {
+ return features.get(name);
+ }
+
+ @WriteOperation
+ public void configureFeature(@Selector String name, Feature feature) {
+ features.put(name, feature);
+ }
+
+ @DeleteOperation
+ public void deleteFeature(@Selector String name) {
+ features.remove(name);
+ }
+
+ public static class Feature {
+ private Boolean enabled;
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+ }
+
+}
diff --git a/spring-5/src/main/java/com/baeldung/actuator/InfoWebEndpointExtension.java b/spring-5/src/main/java/com/baeldung/actuator/InfoWebEndpointExtension.java
new file mode 100644
index 0000000000..acd92d1846
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/actuator/InfoWebEndpointExtension.java
@@ -0,0 +1,32 @@
+package com.baeldung.actuator;
+
+import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
+import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
+import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
+import org.springframework.boot.actuate.info.InfoEndpoint;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+@Component
+@EndpointWebExtension(endpoint = InfoEndpoint.class)
+public class InfoWebEndpointExtension {
+
+ private final InfoEndpoint delegate;
+
+ public InfoWebEndpointExtension(InfoEndpoint infoEndpoint) {
+ this.delegate = infoEndpoint;
+ }
+
+ @ReadOperation
+ public WebEndpointResponse