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 info() { + Map info = this.delegate.info(); + Integer status = getStatus(info); + return new WebEndpointResponse<>(info, status); + } + + private Integer getStatus(Map info) { + // return 5xx if this is a snapshot + return 200; + } +} \ No newline at end of file diff --git a/spring-rest-docs/src/main/java/com/example/CRUDController.java b/spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java similarity index 51% rename from spring-rest-docs/src/main/java/com/example/CRUDController.java rename to spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java index ff8c91d6cd..f6183bc79e 100644 --- a/spring-rest-docs/src/main/java/com/example/CRUDController.java +++ b/spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java @@ -1,16 +1,23 @@ -package com.example; +package com.baeldung.restdocs; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import java.util.ArrayList; import java.util.List; +import javax.validation.Valid; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -18,38 +25,38 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/crud") public class CRUDController { - @RequestMapping(method = RequestMethod.GET) - @ResponseStatus(HttpStatus.OK) - public List read(@RequestBody CrudInput crudInput) { - List returnList = new ArrayList(); + @GetMapping + public List read(@RequestBody @Valid CrudInput crudInput) { + List returnList = new ArrayList<>(); returnList.add(crudInput); return returnList; } @ResponseStatus(HttpStatus.CREATED) - @RequestMapping(method = RequestMethod.POST) - public HttpHeaders save(@RequestBody CrudInput crudInput) { + @PostMapping + public HttpHeaders save(@RequestBody @Valid CrudInput crudInput) { HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri()); + httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getId()).toUri()); return httpHeaders; } - @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.OK) - HttpHeaders delete(@RequestBody CrudInput crudInput) { - HttpHeaders httpHeaders = new HttpHeaders(); - return httpHeaders; + HttpHeaders delete(@PathVariable("id") long id) { + return new HttpHeaders(); } - @RequestMapping(value = "/{id}", method = RequestMethod.PUT) + @PutMapping("/{id}") @ResponseStatus(HttpStatus.ACCEPTED) void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { } - @RequestMapping(value = "/{id}", method = RequestMethod.PATCH) - @ResponseStatus(HttpStatus.NO_CONTENT) - void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { - + @PatchMapping("/{id}") + public List patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { + List returnList = new ArrayList(); + crudInput.setId(id); + returnList.add(crudInput); + return returnList; } } diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java b/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java new file mode 100644 index 0000000000..29046d7725 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java @@ -0,0 +1,66 @@ +package com.baeldung.restdocs; + +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CrudInput { + + @NotNull + private long id; + + @NotBlank + private String title; + + private String body; + + private List tagUris; + + @JsonCreator + public CrudInput(@JsonProperty("id") long id, @JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) { + this.id=id; + this.title = title; + this.body = body; + this.tagUris = tagUris == null ? Collections. emptyList() : tagUris; + } + + public String getTitle() { + return title; + } + + public String getBody() { + return body; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setBody(String body) { + this.body = body; + } + + public void setTagUris(List tagUris) { + this.tagUris = tagUris; + } + + @JsonProperty("tags") + public List getTagUris() { + return this.tagUris; + } + +} \ No newline at end of file diff --git a/spring-rest-docs/src/main/java/com/example/IndexController.java b/spring-5/src/main/java/com/baeldung/restdocs/IndexController.java similarity index 79% rename from spring-rest-docs/src/main/java/com/example/IndexController.java rename to spring-5/src/main/java/com/baeldung/restdocs/IndexController.java index 6b896da416..2c58d5fe6b 100644 --- a/spring-rest-docs/src/main/java/com/example/IndexController.java +++ b/spring-5/src/main/java/com/baeldung/restdocs/IndexController.java @@ -1,17 +1,17 @@ -package com.example; +package com.baeldung.restdocs; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import org.springframework.hateoas.ResourceSupport; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/") public class IndexController { - @RequestMapping(method = RequestMethod.GET) + @GetMapping public ResourceSupport index() { ResourceSupport index = new ResourceSupport(); index.add(linkTo(CRUDController.class).withRel("crud")); diff --git a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java b/spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java similarity index 90% rename from spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java rename to spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java index da09f9accc..02332ee7b6 100644 --- a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java +++ b/spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java @@ -1,4 +1,4 @@ -package com.example; +package com.baeldung.restdocs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java index a9e44a2eee..d31f1552fc 100644 --- a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java +++ b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java @@ -17,6 +17,7 @@ public class SecurityConfig { public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { return http.authorizeExchange() .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") + .pathMatchers("/actuator/**").permitAll() .anyExchange().authenticated() .and().formLogin() .and().build(); diff --git a/spring-5/src/main/resources/application.properties b/spring-5/src/main/resources/application.properties index ccec014c2b..a7e3ec0d5a 100644 --- a/spring-5/src/main/resources/application.properties +++ b/spring-5/src/main/resources/application.properties @@ -1,3 +1,5 @@ server.port=8081 +management.endpoints.web.expose=* +info.app.name=Spring Boot 2 actuator Application logging.level.root=INFO \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/actuator/ActuatorInfoIntegrationTest.java b/spring-5/src/test/java/com/baeldung/actuator/ActuatorInfoIntegrationTest.java new file mode 100644 index 0000000000..964cf1a1ea --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/actuator/ActuatorInfoIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.actuator; + +import com.baeldung.jsonb.Spring5Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5Application.class) +public class ActuatorInfoIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void whenGetInfo_thenReturns200() throws IOException { + final ResponseEntity responseEntity = this.restTemplate.getForEntity("/actuator/info", String.class); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } + + @Test + public void whenFeatures_thenReturns200() throws IOException { + final ResponseEntity responseEntity = this.restTemplate.getForEntity("/actuator/features", String.class); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + } +} \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java new file mode 100644 index 0000000000..20f0a47d83 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java @@ -0,0 +1,180 @@ +package com.baeldung.restdocs; + +import com.baeldung.restdocs.CrudInput; +import com.baeldung.restdocs.SpringRestDocsApplication; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.hateoas.MediaTypes; +import org.springframework.restdocs.JUnitRestDocumentation; +import org.springframework.restdocs.constraints.ConstraintDescriptions; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.singletonList; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.collectionToDelimitedString; +import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringRestDocsApplication.class) +public class ApiDocumentationJUnit4IntegrationTest { + + @Rule + public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets"); + + @Autowired + private WebApplicationContext context; + + @Autowired + private ObjectMapper objectMapper; + + private MockMvc mockMvc; + + @Before + public void setUp() { + + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) + .apply(documentationConfiguration(this.restDocumentation)) + .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))) + .build(); + } + + @Test + public void indexExample() throws Exception { + this.mockMvc.perform(get("/")) + .andExpect(status().isOk()) + .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")), + responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`")))); + } + + @Test + public void crudGetExample() throws Exception { + + Map crud = new HashMap<>(); + crud.put("id", 1L); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + + String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getHeader("Location"); + + crud.put("tags", singletonList(tagLocation)); + + ConstraintDescriptions desc = new ConstraintDescriptions(CrudInput.class); + + this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()) + .andDo(document("crud-get-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), + fieldWithPath("title").description("The title of the input"), fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs")))); + } + + @Test + public void crudCreateExample() throws Exception { + Map crud = new HashMap<>(); + crud.put("id", 2L); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + + String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isCreated()) + .andReturn() + .getResponse() + .getHeader("Location"); + + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isCreated()) + .andDo(document("crud-create-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input"), fieldWithPath("title").description("The title of the input"), + fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs")))); + } + + @Test + public void crudDeleteExample() throws Exception { + this.mockMvc.perform(delete("/crud/{id}", 10)) + .andExpect(status().isOk()) + .andDo(document("crud-delete-example", pathParameters(parameterWithName("id").description("The id of the input to delete")))); + } + + @Test + public void crudPatchExample() throws Exception { + + Map tag = new HashMap<>(); + tag.put("name", "PATCH"); + + String tagLocation = this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(tag))) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getHeader("Location"); + + Map crud = new HashMap<>(); + crud.put("title", "Sample Model Patch"); + crud.put("body", "http://www.baeldung.com/"); + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()); + } + + @Test + public void crudPutExample() throws Exception { + Map tag = new HashMap<>(); + tag.put("name", "PUT"); + + String tagLocation = this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(tag))) + .andExpect(status().isAccepted()) + .andReturn() + .getResponse() + .getHeader("Location"); + + Map crud = new HashMap<>(); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isAccepted()); + } + + @Test + public void contextLoads() { + } + +} diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java new file mode 100644 index 0000000000..748d5fb1b3 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java @@ -0,0 +1,173 @@ +package com.baeldung.restdocs; + +import static java.util.Collections.singletonList; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.collectionToDelimitedString; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +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.hateoas.MediaTypes; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.constraints.ConstraintDescriptions; +import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.restdocs.CrudInput; +import com.baeldung.restdocs.SpringRestDocsApplication; +import com.fasterxml.jackson.databind.ObjectMapper; + +@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class }) +@SpringBootTest(classes = SpringRestDocsApplication.class) +public class ApiDocumentationJUnit5IntegrationTest { + + @Autowired + private ObjectMapper objectMapper; + + private MockMvc mockMvc; + + @BeforeEach + public void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(documentationConfiguration(restDocumentation)) + .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))) + .build(); + } + + @Test + public void indexExample() throws Exception { + this.mockMvc.perform(get("/")) + .andExpect(status().isOk()) + .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")), + responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`")))); + } + + @Test + public void crudGetExample() throws Exception { + + Map crud = new HashMap<>(); + crud.put("id", 1L); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + + String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getHeader("Location"); + + crud.put("tags", singletonList(tagLocation)); + + ConstraintDescriptions desc = new ConstraintDescriptions(CrudInput.class); + + this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()) + .andDo(document("crud-get-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), + fieldWithPath("title").description("The title of the input"), fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs")))); + } + + @Test + public void crudCreateExample() throws Exception { + Map crud = new HashMap<>(); + crud.put("id", 2L); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + + String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isCreated()) + .andReturn() + .getResponse() + .getHeader("Location"); + + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isCreated()) + .andDo(document("crud-create-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input"), fieldWithPath("title").description("The title of the input"), + fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs")))); + } + + @Test + public void crudDeleteExample() throws Exception { + this.mockMvc.perform(delete("/crud/{id}", 10)) + .andExpect(status().isOk()) + .andDo(document("crud-delete-example", pathParameters(parameterWithName("id").description("The id of the input to delete")))); + } + + @Test + public void crudPatchExample() throws Exception { + + Map tag = new HashMap<>(); + tag.put("name", "PATCH"); + + String tagLocation = this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(tag))) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getHeader("Location"); + + Map crud = new HashMap<>(); + crud.put("title", "Sample Model Patch"); + crud.put("body", "http://www.baeldung.com/"); + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isOk()); + } + + @Test + public void crudPutExample() throws Exception { + Map tag = new HashMap<>(); + tag.put("name", "PUT"); + + String tagLocation = this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(tag))) + .andExpect(status().isAccepted()) + .andReturn() + .getResponse() + .getHeader("Location"); + + Map crud = new HashMap<>(); + crud.put("title", "Sample Model"); + crud.put("body", "http://www.baeldung.com/"); + crud.put("tags", singletonList(tagLocation)); + + this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(crud))) + .andExpect(status().isAccepted()); + } + + @Test + public void contextLoads() { + } + +} diff --git a/spring-boot/.mvn/wrapper/maven-wrapper.properties b/spring-boot/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a447c9fa81 --- /dev/null +++ b/spring-boot/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/spring-boot/mvnw b/spring-boot/mvnw new file mode 100755 index 0000000000..e96ccd5fbb --- /dev/null +++ b/spring-boot/mvnw @@ -0,0 +1,227 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/spring-boot/mvnw.cmd b/spring-boot/mvnw.cmd new file mode 100755 index 0000000000..4f0b068a03 --- /dev/null +++ b/spring-boot/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/spring-rest-docs/README.MD b/spring-rest-docs/README.MD deleted file mode 100644 index f5d001d126..0000000000 --- a/spring-rest-docs/README.MD +++ /dev/null @@ -1,5 +0,0 @@ -###The Course -The "REST With Spring" Classes: http://bit.ly/restwithspring - -###Relevant Articles: -- [Introduction to Spring REST Docs](http://www.baeldung.com/spring-rest-docs) diff --git a/spring-rest-docs/pom.xml b/spring-rest-docs/pom.xml deleted file mode 100644 index ffd3cb89b6..0000000000 --- a/spring-rest-docs/pom.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - 4.0.0 - - com.example - spring-rest-docs - 0.0.1-SNAPSHOT - jar - - spring-rest-docs - Demo project for Spring Boot - - - parent-boot-5 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-5 - - - - ${project.build.directory}/generated-snippets - 1.1.2.RELEASE - 2.2.0 - 1.5.3 - - - - - org.springframework.boot - spring-boot-starter-hateoas - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.restdocs - spring-restdocs-mockmvc - test - - - com.jayway.jsonpath - json-path - - - - - - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-plugin.version} - - - generate-docs - package - - process-asciidoc - - - html - book - - ${snippetsDirectory} - - src/docs/asciidocs - target/generated-docs - - - - - - - - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*LiveTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - - - - - diff --git a/spring-rest-docs/src/main/java/com/example/CrudInput.java b/spring-rest-docs/src/main/java/com/example/CrudInput.java deleted file mode 100644 index 36ad67eb21..0000000000 --- a/spring-rest-docs/src/main/java/com/example/CrudInput.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.example; - -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import org.hibernate.validator.constraints.NotBlank; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class CrudInput { - - // @NotBlank - private final String title; - - private final String body; - - private final List tagUris; - - @JsonCreator - public CrudInput(@JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) { - this.title = title; - this.body = body; - this.tagUris = tagUris == null ? Collections. emptyList() : tagUris; - } - - public String getTitle() { - return title; - } - - public String getBody() { - return body; - } - - @JsonProperty("tags") - public List getTagUris() { - return this.tagUris; - } - -} \ No newline at end of file diff --git a/spring-rest-docs/src/main/resources/application.properties b/spring-rest-docs/src/main/resources/application.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-rest-docs/src/test/java/com/example/ApiDocumentationIntegrationTest.java b/spring-rest-docs/src/test/java/com/example/ApiDocumentationIntegrationTest.java deleted file mode 100644 index 1c3aef4845..0000000000 --- a/spring-rest-docs/src/test/java/com/example/ApiDocumentationIntegrationTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package com.example; - -import static java.util.Collections.singletonList; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; -import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; -import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; -import static org.springframework.restdocs.snippet.Attributes.key; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.util.StringUtils.collectionToDelimitedString; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.MediaTypes; -import org.springframework.restdocs.RestDocumentation; -import org.springframework.restdocs.constraints.ConstraintDescriptions; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringRestDocsApplication.class) -@WebAppConfiguration -public class ApiDocumentationIntegrationTest { - - @Rule - public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets"); - - @Autowired - private WebApplicationContext context; - - @Autowired - private ObjectMapper objectMapper; - - private RestDocumentationResultHandler document; - - private MockMvc mockMvc; - - @Before - public void setUp() { - this.document = document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(this.document).build(); - } - - @Test - public void headersExample() throws Exception { - this.document.snippets(responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))); - this.mockMvc.perform(get("/")).andExpect(status().isOk()); - } - - @Test - public void indexExample() throws Exception { - this.document.snippets(links(linkWithRel("crud").description("The <>")), responseFields(fieldWithPath("_links").description("<> to other resources"))); - this.mockMvc.perform(get("/")).andExpect(status().isOk()); - } - - @Test - public void crudGetExample() throws Exception { - - Map tag = new HashMap<>(); - tag.put("name", "GET"); - - String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location"); - - Map crud = new HashMap<>(); - crud.put("title", "Sample Model"); - crud.put("body", "http://www.baeldung.com/"); - crud.put("tags", singletonList(tagLocation)); - - this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk()); - } - - @Test - public void crudCreateExample() throws Exception { - Map tag = new HashMap<>(); - tag.put("name", "CREATE"); - - String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isCreated()).andReturn().getResponse().getHeader("Location"); - - Map crud = new HashMap<>(); - crud.put("title", "Sample Model"); - crud.put("body", "http://www.baeldung.com/"); - crud.put("tags", singletonList(tagLocation)); - - ConstrainedFields fields = new ConstrainedFields(CrudInput.class); - this.document.snippets(requestFields(fields.withPath("title").description("The title of the note"), fields.withPath("body").description("The body of the note"), fields.withPath("tags").description("An array of tag resource URIs"))); - this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isCreated()); - - } - - @Test - public void crudDeleteExample() throws Exception { - - Map tag = new HashMap<>(); - tag.put("name", "DELETE"); - - String tagLocation = this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location"); - - Map crud = new HashMap<>(); - crud.put("title", "Sample Model"); - crud.put("body", "http://www.baeldung.com/"); - crud.put("tags", singletonList(tagLocation)); - - this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk()); - } - - @Test - public void crudPatchExample() throws Exception { - - Map tag = new HashMap<>(); - tag.put("name", "PATCH"); - - String tagLocation = this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isNoContent()).andReturn().getResponse().getHeader("Location"); - - Map crud = new HashMap<>(); - crud.put("title", "Sample Model"); - crud.put("body", "http://www.baeldung.com/"); - crud.put("tags", singletonList(tagLocation)); - - this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isNoContent()); - } - - @Test - public void crudPutExample() throws Exception { - Map tag = new HashMap<>(); - tag.put("name", "PUT"); - - String tagLocation = this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isAccepted()).andReturn().getResponse().getHeader("Location"); - - Map crud = new HashMap<>(); - crud.put("title", "Sample Model"); - crud.put("body", "http://www.baeldung.com/"); - crud.put("tags", singletonList(tagLocation)); - - this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isAccepted()); - } - - @Test - public void contextLoads() { - } - - private static class ConstrainedFields { - - private final ConstraintDescriptions constraintDescriptions; - - ConstrainedFields(Class input) { - this.constraintDescriptions = new ConstraintDescriptions(input); - } - - private FieldDescriptor withPath(String path) { - return fieldWithPath(path).attributes(key("constraints").value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". "))); - } - } - -} diff --git a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentationIntegrationTest.java b/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentationIntegrationTest.java deleted file mode 100644 index 3300fc519c..0000000000 --- a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentationIntegrationTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.example; - -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.hateoas.MediaTypes; -import org.springframework.restdocs.RestDocumentation; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import com.fasterxml.jackson.databind.ObjectMapper; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringRestDocsApplication.class) -@WebAppConfiguration -public class GettingStartedDocumentationIntegrationTest { - - @Rule - public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets"); - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private WebApplicationContext context; - - private MockMvc mockMvc; - - @Before - public void setUp() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(document("{method-name}/{step}/", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))).build(); - } - - @Test - public void index() throws Exception { - this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON)).andExpect(status().isOk()).andExpect(jsonPath("_links.crud", is(notNullValue()))).andExpect(jsonPath("_links.crud", is(notNullValue()))); - } - - // String createNote() throws Exception { - // Map note = new HashMap(); - // note.put("title", "Note creation with cURL"); - // note.put("body", "An example of how to create a note using curl"); - // String noteLocation = this.mockMvc.perform(post("/crud") - // .contentType(MediaTypes.HAL_JSON) - // .content(objectMapper.writeValueAsString(note))) - // .andExpect(status().isCreated()) - // .andExpect(header().string("Location", notNullValue())) - // .andReturn() - // .getResponse() - // .getHeader("Location"); - // return noteLocation; - // } - // - // MvcResult getNote(String noteLocation) throws Exception { - // return this.mockMvc.perform(get(noteLocation)) - // .andExpect(status().isOk()) - // .andExpect(jsonPath("title", is(notNullValue()))) - // .andExpect(jsonPath("body", is(notNullValue()))) - // .andExpect(jsonPath("_links.crud", is(notNullValue()))) - // .andReturn(); - // } - // - // - // String createTag() throws Exception, JsonProcessingException { - // Map tag = new HashMap(); - // tag.put("name", "getting-started"); - // String tagLocation = this.mockMvc.perform(post("/crud") - // .contentType(MediaTypes.HAL_JSON) - // .content(objectMapper.writeValueAsString(tag))) - // .andExpect(status().isCreated()) - // .andExpect(header().string("Location", notNullValue())) - // .andReturn() - // .getResponse() - // .getHeader("Location"); - // return tagLocation; - // } - // - // void getTag(String tagLocation) throws Exception { - // this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk()) - // .andExpect(jsonPath("name", is(notNullValue()))) - // .andExpect(jsonPath("_links.tagged-notes", is(notNullValue()))); - // } - // - // String createTaggedNote(String tag) throws Exception { - // Map note = new HashMap(); - // note.put("title", "Tagged note creation with cURL"); - // note.put("body", "An example of how to create a tagged note using cURL"); - // note.put("tags", Arrays.asList(tag)); - // - // String noteLocation = this.mockMvc.perform(post("/notes") - // .contentType(MediaTypes.HAL_JSON) - // .content(objectMapper.writeValueAsString(note))) - // .andExpect(status().isCreated()) - // .andExpect(header().string("Location", notNullValue())) - // .andReturn() - // .getResponse() - // .getHeader("Location"); - // return noteLocation; - // } - // - // void getTags(String noteTagsLocation) throws Exception { - // this.mockMvc.perform(get(noteTagsLocation)) - // .andExpect(status().isOk()) - // .andExpect(jsonPath("_embedded.tags", hasSize(1))); - // } - // - // void tagExistingNote(String noteLocation, String tagLocation) throws Exception { - // Map update = new HashMap(); - // update.put("tags", Arrays.asList(tagLocation)); - // this.mockMvc.perform(patch(noteLocation) - // .contentType(MediaTypes.HAL_JSON) - // .content(objectMapper.writeValueAsString(update))) - // .andExpect(status().isNoContent()); - // } - // - // MvcResult getTaggedExistingNote(String noteLocation) throws Exception { - // return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn(); - // } - // - // void getTagsForExistingNote(String noteTagsLocation) throws Exception { - // this.mockMvc.perform(get(noteTagsLocation)) - // .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1))); - // } - // - // private String getLink(MvcResult result, String rel) - // throws UnsupportedEncodingException { - // return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href"); - // } - -} diff --git a/vavr/README.md b/vavr/README.md index 4361363fbd..d39c9f36a1 100644 --- a/vavr/README.md +++ b/vavr/README.md @@ -8,3 +8,5 @@ - [Introduction to Vavr’s Validation API](http://www.baeldung.com/vavr-validation-api) - [Guide to Collections API in Vavr](http://www.baeldung.com/vavr-collections) - [Collection Factory Methods for Vavr](http://www.baeldung.com/vavr-collection-factory-methods) +- [Introduction to Future in Vavr](http://www.baeldung.com/vavr-future) + diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java index 002919a937..d5345cad55 100644 --- a/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java +++ b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java @@ -58,6 +58,14 @@ public class FutureTest { assertThat(result) .isEqualTo(HELLO); } + + @Test + public void whenTransform_thenCorrect() { + Future future = Future.of(() -> 5) + .transformValue(result -> Try.of(() -> HELLO + result.get())); + + assertThat(future.get()).isEqualTo(HELLO + 5); + } @Test public void whenChainingCallbacks_thenCorrect() { @@ -139,6 +147,14 @@ public class FutureTest { assertThat(futureResult.get()) .isEqualTo("Hello from Baeldung"); } + + @Test + public void whenCallFlatMap_thenCorrect() { + Future futureMap = Future.of(() -> 1) + .flatMap((i) -> Future.of(() -> "Hello: " + i)); + + assertThat(futureMap.get()).isEqualTo("Hello: 1"); + } @Test public void whenFutureFails_thenGetErrorMessage() {