Merge remote-tracking branch 'eugenp/master'
This commit is contained in:
		
						commit
						5e3ab6f573
					
				| @ -15,3 +15,4 @@ | |||||||
| - [Introduction to JGraphT](http://www.baeldung.com/jgrapht) | - [Introduction to JGraphT](http://www.baeldung.com/jgrapht) | ||||||
| - [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm) | - [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 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) | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								core-java/src/main/java/com/baeldung/staticclass/Pizza.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								core-java/src/main/java/com/baeldung/staticclass/Pizza.java
									
									
									
									
									
										Normal file
									
								
							| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								java-vavr-stream/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								java-vavr-stream/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <groupId>com.baeldung.samples</groupId> | ||||||
|  |     <artifactId>java-vavr-stream</artifactId> | ||||||
|  |     <version>1.0</version> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  |     <properties> | ||||||
|  |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|  |         <maven.compiler.source>1.8</maven.compiler.source> | ||||||
|  |         <maven.compiler.target>1.8</maven.compiler.target> | ||||||
|  |     </properties> | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>io.vavr</groupId> | ||||||
|  |             <artifactId>vavr</artifactId> | ||||||
|  |             <version>0.9.2</version> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | </project> | ||||||
| @ -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<Integer> intList = new ArrayList<Integer>(); | ||||||
|  |     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<Integer> vavredStream = Stream.ofAll(intArray); | ||||||
|  |         System.out.println("Vavr index access: " + vavredStream.get(2)); | ||||||
|  |         System.out.println("Vavr head element access: " + vavredStream.get()); | ||||||
|  | 
 | ||||||
|  |         Stream<String> 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<Integer> vavrStream = Stream.ofAll(intList); | ||||||
|  |             intList.add(5); | ||||||
|  |             vavrStream.forEach(i -> System.out.println("in a Vavr Stream: " + i)); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             ex.printStackTrace(); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         Stream<Integer> 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<String> stringList = new ArrayList<>(); | ||||||
|  |         stringList.add("foo"); | ||||||
|  |         stringList.add("bar"); | ||||||
|  |         stringList.add("baz"); | ||||||
|  |         Stream<String> vavredStream = Stream.ofAll(stringList); | ||||||
|  |         vavredStream.forEach(item -> System.out.println("Vavr Stream item: " + item)); | ||||||
|  |         Stream<String> 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<String> deletionStream = vavredStream.remove("bar"); | ||||||
|  |         deletionStream.forEach(item -> System.out.println("Vavr Stream item after stream item deletion: " + item)); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void vavrStreamDistinct() { | ||||||
|  |         Stream<String> vavredStream = Stream.of("foo", "bar", "baz", "buxx", "bar", "bar", "foo"); | ||||||
|  |         Stream<String> distinctVavrStream = vavredStream.distinctBy((y, z) -> { | ||||||
|  |             return y.compareTo(z); | ||||||
|  |         }); | ||||||
|  |         distinctVavrStream.forEach(item -> System.out.println("Vavr Stream item after distinct query " + item)); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							| @ -87,6 +87,7 @@ | |||||||
|         <!--         <module>persistence-modules/java-cassandra</module> --> |         <!--         <module>persistence-modules/java-cassandra</module> --> | ||||||
|         <module>vavr</module> |         <module>vavr</module> | ||||||
| 		<module>java-lite</module> | 		<module>java-lite</module> | ||||||
|  | 	<module>java-vavr-stream</module> | ||||||
|         <module>javax-servlets</module> |         <module>javax-servlets</module> | ||||||
|         <module>javaxval</module> |         <module>javaxval</module> | ||||||
|         <module>jaxb</module> |         <module>jaxb</module> | ||||||
| @ -203,7 +204,6 @@ | |||||||
|         <module>spring-protobuf</module> |         <module>spring-protobuf</module> | ||||||
|         <module>spring-quartz</module> |         <module>spring-quartz</module> | ||||||
|         <module>spring-rest-angular</module> |         <module>spring-rest-angular</module> | ||||||
|         <module>spring-rest-docs</module> |  | ||||||
|         <module>spring-rest-full</module> |         <module>spring-rest-full</module> | ||||||
|         <module>spring-rest-query-language</module> |         <module>spring-rest-query-language</module> | ||||||
|         <module>spring-rest</module> |         <module>spring-rest</module> | ||||||
|  | |||||||
| @ -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) | - [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) | - [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 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) | ||||||
|  | |||||||
| @ -39,6 +39,14 @@ | |||||||
| 			<groupId>org.springframework.boot</groupId> | 			<groupId>org.springframework.boot</groupId> | ||||||
| 			<artifactId>spring-boot-starter-webflux</artifactId> | 			<artifactId>spring-boot-starter-webflux</artifactId> | ||||||
| 		</dependency> | 		</dependency> | ||||||
|  |     <dependency> | ||||||
|  | 			<groupId>org.springframework.boot</groupId> | ||||||
|  | 			<artifactId>spring-boot-starter-hateoas</artifactId> | ||||||
|  | 		</dependency> | ||||||
|  | 		<dependency> | ||||||
|  | 			<groupId>org.springframework.boot</groupId> | ||||||
|  | 			<artifactId>spring-boot-starter-actuator</artifactId> | ||||||
|  | 		</dependency> | ||||||
| 		<dependency> | 		<dependency> | ||||||
| 			<groupId>org.projectreactor</groupId> | 			<groupId>org.projectreactor</groupId> | ||||||
| 			<artifactId>reactor-spring</artifactId> | 			<artifactId>reactor-spring</artifactId> | ||||||
| @ -135,6 +143,23 @@ | |||||||
| 			<version>${junit.platform.version}</version> | 			<version>${junit.platform.version}</version> | ||||||
| 			<scope>test</scope> | 			<scope>test</scope> | ||||||
| 		</dependency> | 		</dependency> | ||||||
|  |         <!-- restdocs --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.restdocs</groupId> | ||||||
|  |             <artifactId>spring-restdocs-mockmvc</artifactId> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |          <dependency> | ||||||
|  |             <groupId>org.springframework.restdocs</groupId> | ||||||
|  |             <artifactId>spring-restdocs-webtestclient</artifactId> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |          <dependency> | ||||||
|  |             <groupId>org.springframework.restdocs</groupId> | ||||||
|  |             <artifactId>spring-restdocs-restassured</artifactId> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |          | ||||||
| 
 | 
 | ||||||
| 	</dependencies> | 	</dependencies> | ||||||
| 
 | 
 | ||||||
| @ -163,6 +188,29 @@ | |||||||
| 					</excludes> | 					</excludes> | ||||||
| 				</configuration> | 				</configuration> | ||||||
| 			</plugin> | 			</plugin> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.asciidoctor</groupId> | ||||||
|  |                 <artifactId>asciidoctor-maven-plugin</artifactId> | ||||||
|  |                 <version>${asciidoctor-plugin.version}</version> | ||||||
|  |                 <executions> | ||||||
|  |                     <execution> | ||||||
|  |                         <id>generate-docs</id> | ||||||
|  |                         <phase>package</phase> | ||||||
|  |                         <goals> | ||||||
|  |                             <goal>process-asciidoc</goal> | ||||||
|  |                         </goals> | ||||||
|  |                         <configuration> | ||||||
|  |                             <backend>html</backend> | ||||||
|  |                             <doctype>book</doctype> | ||||||
|  |                             <attributes> | ||||||
|  |                                 <snippets>${snippetsDirectory}</snippets> | ||||||
|  |                             </attributes> | ||||||
|  |                             <sourceDirectory>src/docs/asciidocs</sourceDirectory> | ||||||
|  |                             <outputDirectory>target/generated-docs</outputDirectory> | ||||||
|  |                         </configuration> | ||||||
|  |                     </execution> | ||||||
|  |                 </executions> | ||||||
|  |             </plugin> | ||||||
| 		</plugins> | 		</plugins> | ||||||
| 	</build> | 	</build> | ||||||
| 
 | 
 | ||||||
| @ -199,6 +247,8 @@ | |||||||
| 		<johnzon.version>1.1.3</johnzon.version> | 		<johnzon.version>1.1.3</johnzon.version> | ||||||
| 		<jsonb-api.version>1.0</jsonb-api.version> | 		<jsonb-api.version>1.0</jsonb-api.version> | ||||||
| 		<geronimo-json_1.1_spec.version>1.0</geronimo-json_1.1_spec.version> | 		<geronimo-json_1.1_spec.version>1.0</geronimo-json_1.1_spec.version> | ||||||
|  | 		<asciidoctor-plugin.version>1.5.6</asciidoctor-plugin.version> | ||||||
|  | 		<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> | ||||||
| 	</properties> | 	</properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
|  | |||||||
| @ -55,13 +55,6 @@ use of HTTP status codes. | |||||||
| | The requested resource did not exist | | 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]] | [[overview-hypermedia]] | ||||||
| == Hypermedia | == Hypermedia | ||||||
| 
 | 
 | ||||||
| @ -86,18 +79,14 @@ The index provides the entry point into the service. | |||||||
| 
 | 
 | ||||||
| A `GET` request is used to access the index | 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 | ==== Example response | ||||||
| 
 | 
 | ||||||
| include::{snippets}/index-example/http-response.adoc[] | include::{snippets}/index-example/http-response.adoc[] | ||||||
| 
 | 
 | ||||||
| ==== Example request |  | ||||||
| 
 |  | ||||||
| include::{snippets}/index-example/http-request.adoc[] |  | ||||||
| 
 |  | ||||||
| ==== CURL request | ==== CURL request | ||||||
| 
 | 
 | ||||||
| include::{snippets}/index-example/curl-request.adoc[] | 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. | The CRUD provides the entry point into the service. | ||||||
| 
 | 
 | ||||||
| [[resources-crud-access]] | [[resources-crud-get]] | ||||||
| === Accessing the 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[] | 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[] | include::{snippets}/crud-get-example/curl-request.adoc[] | ||||||
| 
 | 
 | ||||||
| [[resources-crud-access]] | [[resources-crud-post]] | ||||||
| === Accessing the 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[] | 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[] | include::{snippets}/crud-create-example/curl-request.adoc[] | ||||||
| 
 | 
 | ||||||
| [[resources-crud-access]] | [[resources-crud-delete]] | ||||||
| === Accessing the 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[] | include::{snippets}/crud-delete-example/http-request.adoc[] | ||||||
| 
 | 
 | ||||||
|  | ==== Path Parameters | ||||||
|  | include::{snippets}/crud-delete-example/path-parameters.adoc[] | ||||||
|  | 
 | ||||||
| ==== Example response | ==== Example response | ||||||
| 
 | 
 | ||||||
| include::{snippets}/crud-delete-example/http-response.adoc[] | 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[] | include::{snippets}/crud-delete-example/curl-request.adoc[] | ||||||
| 
 | 
 | ||||||
| [[resources-crud-access]] | [[resources-crud-patch]] | ||||||
| === Accessing the 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[] | 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[] | include::{snippets}/crud-patch-example/curl-request.adoc[] | ||||||
| 
 | 
 | ||||||
| [[resources-crud-access]] | [[resources-crud-put]] | ||||||
| === Accessing the 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[] | include::{snippets}/crud-put-example/http-request.adoc[] | ||||||
| 
 | 
 | ||||||
| @ -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> health() { | ||||||
|  |         return checkDownstreamServiceHealth().onErrorResume( | ||||||
|  |           ex -> Mono.just(new Health.Builder().down(ex).build()) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Mono<Health> checkDownstreamServiceHealth() { | ||||||
|  |         // we could use WebClient to check health reactively | ||||||
|  |         return Mono.just(new Health.Builder().up().build()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<String, Feature> features = new ConcurrentHashMap<>(); | ||||||
|  | 
 | ||||||
|  |     @ReadOperation | ||||||
|  |     public Map<String, Feature> 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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<Map> info() { | ||||||
|  |         Map<String, Object> info = this.delegate.info(); | ||||||
|  |         Integer status = getStatus(info); | ||||||
|  |         return new WebEndpointResponse<>(info, status); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Integer getStatus(Map<String, Object> info) { | ||||||
|  |         // return 5xx if this is a snapshot | ||||||
|  |         return 200; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,16 +1,23 @@ | |||||||
| package com.example; | package com.baeldung.restdocs; | ||||||
| 
 | 
 | ||||||
| import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; | import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
|  | import javax.validation.Valid; | ||||||
|  | 
 | ||||||
| import org.springframework.http.HttpHeaders; | import org.springframework.http.HttpHeaders; | ||||||
| import org.springframework.http.HttpStatus; | 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.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.RequestBody; | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; | 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.ResponseStatus; | ||||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||||
| 
 | 
 | ||||||
| @ -18,38 +25,38 @@ import org.springframework.web.bind.annotation.RestController; | |||||||
| @RequestMapping("/crud") | @RequestMapping("/crud") | ||||||
| public class CRUDController { | public class CRUDController { | ||||||
| 
 | 
 | ||||||
|     @RequestMapping(method = RequestMethod.GET) |     @GetMapping | ||||||
|     @ResponseStatus(HttpStatus.OK) |     public List<CrudInput> read(@RequestBody @Valid CrudInput crudInput) { | ||||||
|     public List<CrudInput> read(@RequestBody CrudInput crudInput) { |         List<CrudInput> returnList = new ArrayList<>(); | ||||||
|         List<CrudInput> returnList = new ArrayList<CrudInput>(); |  | ||||||
|         returnList.add(crudInput); |         returnList.add(crudInput); | ||||||
|         return returnList; |         return returnList; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @ResponseStatus(HttpStatus.CREATED) |     @ResponseStatus(HttpStatus.CREATED) | ||||||
|     @RequestMapping(method = RequestMethod.POST) |     @PostMapping | ||||||
|     public HttpHeaders save(@RequestBody CrudInput crudInput) { |     public HttpHeaders save(@RequestBody @Valid CrudInput crudInput) { | ||||||
|         HttpHeaders httpHeaders = new HttpHeaders(); |         HttpHeaders httpHeaders = new HttpHeaders(); | ||||||
|         httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri()); |         httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getId()).toUri()); | ||||||
|         return httpHeaders; |         return httpHeaders; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) |     @DeleteMapping("/{id}") | ||||||
|     @ResponseStatus(HttpStatus.OK) |     @ResponseStatus(HttpStatus.OK) | ||||||
|     HttpHeaders delete(@RequestBody CrudInput crudInput) { |     HttpHeaders delete(@PathVariable("id") long id) { | ||||||
|         HttpHeaders httpHeaders = new HttpHeaders(); |         return new HttpHeaders(); | ||||||
|         return httpHeaders; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @RequestMapping(value = "/{id}", method = RequestMethod.PUT) |     @PutMapping("/{id}") | ||||||
|     @ResponseStatus(HttpStatus.ACCEPTED) |     @ResponseStatus(HttpStatus.ACCEPTED) | ||||||
|     void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { |     void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @RequestMapping(value = "/{id}", method = RequestMethod.PATCH) |     @PatchMapping("/{id}") | ||||||
|     @ResponseStatus(HttpStatus.NO_CONTENT) |     public List<CrudInput> patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { | ||||||
|     void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { |         List<CrudInput> returnList = new ArrayList<CrudInput>(); | ||||||
| 
 |         crudInput.setId(id); | ||||||
|  |         returnList.add(crudInput); | ||||||
|  |         return returnList; | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										66
									
								
								spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java
									
									
									
									
									
										Normal file
									
								
							| @ -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<URI> tagUris; | ||||||
|  | 
 | ||||||
|  |     @JsonCreator | ||||||
|  |     public CrudInput(@JsonProperty("id") long id, @JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List<URI> tagUris) { | ||||||
|  |         this.id=id; | ||||||
|  |         this.title = title; | ||||||
|  |         this.body = body; | ||||||
|  |         this.tagUris = tagUris == null ? Collections.<URI> 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<URI> tagUris) { | ||||||
|  |         this.tagUris = tagUris; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @JsonProperty("tags") | ||||||
|  |     public List<URI> getTagUris() { | ||||||
|  |         return this.tagUris; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -1,17 +1,17 @@ | |||||||
| package com.example; | package com.baeldung.restdocs; | ||||||
| 
 | 
 | ||||||
| import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; | import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; | ||||||
| 
 | 
 | ||||||
| import org.springframework.hateoas.ResourceSupport; | 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.RequestMapping; | ||||||
| import org.springframework.web.bind.annotation.RequestMethod; |  | ||||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||||
| 
 | 
 | ||||||
| @RestController | @RestController | ||||||
| @RequestMapping("/") | @RequestMapping("/") | ||||||
| public class IndexController { | public class IndexController { | ||||||
| 
 | 
 | ||||||
|     @RequestMapping(method = RequestMethod.GET) |     @GetMapping | ||||||
|     public ResourceSupport index() { |     public ResourceSupport index() { | ||||||
|         ResourceSupport index = new ResourceSupport(); |         ResourceSupport index = new ResourceSupport(); | ||||||
|         index.add(linkTo(CRUDController.class).withRel("crud")); |         index.add(linkTo(CRUDController.class).withRel("crud")); | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package com.example; | package com.baeldung.restdocs; | ||||||
| 
 | 
 | ||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
| @ -17,6 +17,7 @@ public class SecurityConfig { | |||||||
|     public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { |     public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { | ||||||
|         return http.authorizeExchange() |         return http.authorizeExchange() | ||||||
|                 .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") |                 .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") | ||||||
|  |                 .pathMatchers("/actuator/**").permitAll() | ||||||
|                 .anyExchange().authenticated() |                 .anyExchange().authenticated() | ||||||
|                 .and().formLogin() |                 .and().formLogin() | ||||||
|                 .and().build(); |                 .and().build(); | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
| server.port=8081 | server.port=8081 | ||||||
|  | management.endpoints.web.expose=* | ||||||
|  | info.app.name=Spring Boot 2 actuator Application | ||||||
| 
 | 
 | ||||||
| logging.level.root=INFO | logging.level.root=INFO | ||||||
| @ -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<String> responseEntity = this.restTemplate.getForEntity("/actuator/info", String.class); | ||||||
|  |         assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenFeatures_thenReturns200() throws IOException { | ||||||
|  |         final ResponseEntity<String> responseEntity = this.restTemplate.getForEntity("/actuator/features", String.class); | ||||||
|  |         assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, Object> 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<String, Object> 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<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<String, Object> 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<String, Object> 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<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								spring-boot/.mvn/wrapper/maven-wrapper.properties
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								spring-boot/.mvn/wrapper/maven-wrapper.properties
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip | ||||||
							
								
								
									
										227
									
								
								spring-boot/mvnw
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										227
									
								
								spring-boot/mvnw
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @ -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 "$@" | ||||||
							
								
								
									
										145
									
								
								spring-boot/mvnw.cmd
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										145
									
								
								spring-boot/mvnw.cmd
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @ -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% | ||||||
| @ -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) |  | ||||||
| @ -1,112 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
| 
 |  | ||||||
|     <groupId>com.example</groupId> |  | ||||||
|     <artifactId>spring-rest-docs</artifactId> |  | ||||||
|     <version>0.0.1-SNAPSHOT</version> |  | ||||||
|     <packaging>jar</packaging> |  | ||||||
| 
 |  | ||||||
|     <name>spring-rest-docs</name> |  | ||||||
|     <description>Demo project for Spring Boot</description> |  | ||||||
| 
 |  | ||||||
|     <parent> |  | ||||||
|         <artifactId>parent-boot-5</artifactId> |  | ||||||
|         <groupId>com.baeldung</groupId> |  | ||||||
|         <version>0.0.1-SNAPSHOT</version> |  | ||||||
|         <relativePath>../parent-boot-5</relativePath> |  | ||||||
|     </parent> |  | ||||||
| 
 |  | ||||||
|     <properties> |  | ||||||
|         <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> |  | ||||||
|         <restdocs.version>1.1.2.RELEASE</restdocs.version> |  | ||||||
|         <jsonpath.version>2.2.0</jsonpath.version> |  | ||||||
|         <asciidoctor-plugin.version>1.5.3</asciidoctor-plugin.version> |  | ||||||
|     </properties> |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.springframework.boot</groupId> |  | ||||||
|             <artifactId>spring-boot-starter-hateoas</artifactId> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.springframework.boot</groupId> |  | ||||||
|             <artifactId>spring-boot-starter-web</artifactId> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>org.springframework.restdocs</groupId> |  | ||||||
|             <artifactId>spring-restdocs-mockmvc</artifactId> |  | ||||||
|             <scope>test</scope> |  | ||||||
|         </dependency> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.jayway.jsonpath</groupId> |  | ||||||
|             <artifactId>json-path</artifactId> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |  | ||||||
| 
 |  | ||||||
|     <build> |  | ||||||
|         <plugins> |  | ||||||
|             <plugin> |  | ||||||
|                 <groupId>org.asciidoctor</groupId> |  | ||||||
|                 <artifactId>asciidoctor-maven-plugin</artifactId> |  | ||||||
|                 <version>${asciidoctor-plugin.version}</version> |  | ||||||
|                 <executions> |  | ||||||
|                     <execution> |  | ||||||
|                         <id>generate-docs</id> |  | ||||||
|                         <phase>package</phase> |  | ||||||
|                         <goals> |  | ||||||
|                             <goal>process-asciidoc</goal> |  | ||||||
|                         </goals> |  | ||||||
|                         <configuration> |  | ||||||
|                             <backend>html</backend> |  | ||||||
|                             <doctype>book</doctype> |  | ||||||
|                             <attributes> |  | ||||||
|                                 <snippets>${snippetsDirectory}</snippets> |  | ||||||
|                             </attributes> |  | ||||||
|                             <sourceDirectory>src/docs/asciidocs</sourceDirectory> |  | ||||||
|                             <outputDirectory>target/generated-docs</outputDirectory> |  | ||||||
|                         </configuration> |  | ||||||
|                     </execution> |  | ||||||
|                 </executions> |  | ||||||
|             </plugin> |  | ||||||
|         </plugins> |  | ||||||
|     </build> |  | ||||||
| 
 |  | ||||||
|     <profiles> |  | ||||||
|         <profile> |  | ||||||
|             <id>integration</id> |  | ||||||
|             <build> |  | ||||||
|                 <plugins> |  | ||||||
|                     <plugin> |  | ||||||
|                         <groupId>org.apache.maven.plugins</groupId> |  | ||||||
|                         <artifactId>maven-surefire-plugin</artifactId> |  | ||||||
|                         <executions> |  | ||||||
|                             <execution> |  | ||||||
|                                 <phase>integration-test</phase> |  | ||||||
|                                 <goals> |  | ||||||
|                                     <goal>test</goal> |  | ||||||
|                                 </goals> |  | ||||||
|                                 <configuration> |  | ||||||
|                                     <excludes> |  | ||||||
|                                         <exclude>**/*LiveTest.java</exclude> |  | ||||||
|                                     </excludes> |  | ||||||
|                                     <includes> |  | ||||||
|                                         <include>**/*IntegrationTest.java</include> |  | ||||||
|                                     </includes> |  | ||||||
|                                 </configuration> |  | ||||||
|                             </execution> |  | ||||||
|                         </executions> |  | ||||||
|                         <configuration> |  | ||||||
|                             <systemPropertyVariables> |  | ||||||
|                                 <test.mime>json</test.mime> |  | ||||||
|                             </systemPropertyVariables> |  | ||||||
|                         </configuration> |  | ||||||
|                     </plugin> |  | ||||||
|                 </plugins> |  | ||||||
|             </build> |  | ||||||
|         </profile> |  | ||||||
|     </profiles> |  | ||||||
|      |  | ||||||
| </project> |  | ||||||
| @ -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<URI> tagUris; |  | ||||||
| 
 |  | ||||||
|     @JsonCreator |  | ||||||
|     public CrudInput(@JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List<URI> tagUris) { |  | ||||||
|         this.title = title; |  | ||||||
|         this.body = body; |  | ||||||
|         this.tagUris = tagUris == null ? Collections.<URI> emptyList() : tagUris; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public String getTitle() { |  | ||||||
|         return title; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public String getBody() { |  | ||||||
|         return body; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @JsonProperty("tags") |  | ||||||
|     public List<URI> getTagUris() { |  | ||||||
|         return this.tagUris; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -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 <<resources-tags,Tags resource>>")), responseFields(fieldWithPath("_links").description("<<resources-index-links,Links>> to other resources"))); |  | ||||||
|         this.mockMvc.perform(get("/")).andExpect(status().isOk()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void crudGetExample() throws Exception { |  | ||||||
| 
 |  | ||||||
|         Map<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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<String, String> 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<String, Object> 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), ". "))); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -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<String, String> note = new HashMap<String, String>(); |  | ||||||
|     // 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<String, String> tag = new HashMap<String, String>(); |  | ||||||
|     // 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<String, Object> note = new HashMap<String, Object>(); |  | ||||||
|     // 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<String, Object> update = new HashMap<String, Object>(); |  | ||||||
|     // 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"); |  | ||||||
|     // } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -8,3 +8,5 @@ | |||||||
| - [Introduction to Vavr’s Validation API](http://www.baeldung.com/vavr-validation-api) | - [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) | - [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) | - [Collection Factory Methods for Vavr](http://www.baeldung.com/vavr-collection-factory-methods) | ||||||
|  | - [Introduction to Future in Vavr](http://www.baeldung.com/vavr-future) | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -59,6 +59,14 @@ public class FutureTest { | |||||||
|           .isEqualTo(HELLO); |           .isEqualTo(HELLO); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @Test | ||||||
|  |     public void whenTransform_thenCorrect() { | ||||||
|  |         Future<Object> future = Future.of(() -> 5) | ||||||
|  |           .transformValue(result -> Try.of(() -> HELLO + result.get())); | ||||||
|  |              | ||||||
|  |         assertThat(future.get()).isEqualTo(HELLO + 5); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenChainingCallbacks_thenCorrect() { |     public void whenChainingCallbacks_thenCorrect() { | ||||||
|         Future.of(() -> HELLO) |         Future.of(() -> HELLO) | ||||||
| @ -140,6 +148,14 @@ public class FutureTest { | |||||||
|           .isEqualTo("Hello from Baeldung"); |           .isEqualTo("Hello from Baeldung"); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     @Test | ||||||
|  |     public void whenCallFlatMap_thenCorrect() { | ||||||
|  |         Future<Object> futureMap = Future.of(() -> 1) | ||||||
|  |           .flatMap((i) -> Future.of(() -> "Hello: " + i)); | ||||||
|  |       | ||||||
|  |         assertThat(futureMap.get()).isEqualTo("Hello: 1"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenFutureFails_thenGetErrorMessage() { |     public void whenFutureFails_thenGetErrorMessage() { | ||||||
|         Future<String> future = Future.of(() -> "Hello".substring(-1)) |         Future<String> future = Future.of(() -> "Hello".substring(-1)) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user