diff --git a/README.adoc b/README.adoc index 4e4ff32..b6ca220 100644 --- a/README.adoc +++ b/README.adoc @@ -7,12 +7,12 @@ :toc: :icons: font :source-highlighter: prettify -:project_id: gs-spring-cloud-circuitbreaker -This guide walks you through the process of applying circuit breakers to potentially-failing method calls using Spring Cloud Circuit Breaker. +:project_id: draft-gs-template +This guide walks you through the process of creating a Spring application. == What you'll build -You'll build a microservice application that uses the http://martinfowler.com/bliki/CircuitBreaker.html[Circuit Breaker pattern] to gracefully degrade functionality when a method call fails. Use of the Circuit Breaker pattern can allow a microservice to continue operating when a related service fails, preventing the failure from cascading and giving the failing service time to recover. +You'll build a Spring application. == What you'll need @@ -23,204 +23,57 @@ include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/ include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/how_to_complete_this_guide.adoc[] -[[reveal-gradle]] -[.reveal-gradle] -== Build with Gradle +include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/hide-show-gradle.adoc[] -[[scratch]] -[.use-gradle] -== Build with Gradle - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_system_intro.adoc[] - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/create_directory_structure_hello.adoc[] - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/create_both_builds.adoc[] - -`bookstore/build.gradle` -// AsciiDoc source formatting doesn't support groovy, so using java instead -[source,java] ----- -include::https://raw.githubusercontent.com/spring-guides/{project_id}/master/initial/bookstore/build.gradle[] ----- - -`reading/build.gradle` -// AsciiDoc source formatting doesn't support groovy, so using java instead -[source,java] ----- -include::https://raw.githubusercontent.com/spring-guides/{project_id}/master/initial/reading/build.gradle[] ----- - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/spring-boot-gradle-plugin.adoc[] - -[[reveal-maven]] -[.reveal-maven] -== Build with Maven - -[[use-maven]] -[.use-maven] -== Build with Maven - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_system_intro_maven.adoc[] - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/create_directory_structure_hello.adoc[] - -`bookstore/pom.xml` -[source,xml] ----- -include::https://raw.githubusercontent.com/spring-guides/{project_id}/master/initial/bookstore/pom.xml[] ----- - -`reading/pom.xml` -[source,xml] ----- -include::https://raw.githubusercontent.com/spring-guides/{project_id}/master/initial/reading/pom.xml[] ----- - -include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/spring-boot-maven-plugin.adoc[] +include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/hide-show-maven.adoc[] include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/hide-show-sts.adoc[] [[initial]] -== Set up a server microservice application - -The Bookstore service will have a single endpoint. It will be accessible at `/recommended`, and will (for simplicity) return a `Mono` of `String` recommended reading list. +== Create a resource controller -Edit our main class, in `BookstoreApplication.java`. It should look like this: +Create a new controller for your Spring application: -`bookstore/src/main/java/hello/BookstoreApplication.java` +`src/main/java/hello/GreetingController.java` [source,java,tabsize=2] ---- -include::complete/bookstore/src/main/java/hello/BookstoreApplication.java[] +include::complete/src/main/java/hello/GreetingController.java[] ---- -The `@RestController` annotation marks `BookstoreApplication` as a controller class, like `@Controller` does, and also ensures that `@RequestMapping` methods in this class will behave as though annotated with `@ResponseBody`. That is, the return values of `@RequestMapping` methods in this class will be automatically converted appropriately from their original types and will be written directly to the response body. +NOTE: The above example does not specify `GET` vs. `PUT`, `POST`, and so forth, because `@RequestMapping` maps all HTTP operations by default. Use `@RequestMapping(method=GET)` to narrow this mapping. -We're going to run this application locally alongside a client service application, so in `src/main/resources/application.properties`, set `server.port` so that the Bookstore service won't conflict with the client when we get that running. -`bookstore/src/main/resources/application.properties` -[source,properties] ----- -include::complete/bookstore/src/main/resources/application.properties[] ----- +== Make the application executable -== Set up a client microservice application +Although it is possible to package this service as a traditional link:/understanding/WAR[WAR] file for deployment to an external application server, the simpler approach demonstrated below creates a standalone application. You package everything in a single, executable JAR file, driven by a good old Java `main()` method. Along the way, you use Spring's support for embedding the link:/understanding/Tomcat[Tomcat] servlet container as the HTTP runtime, instead of deploying to an external instance. -The Reading application will be our front-end (as it were) to the Bookstore application. We'll be able to view our reading list there at `/to-read`, and that reading list will be retrieved from the Bookstore service application. -`reading/src/main/java/hello/ReadingApplication.java` +`src/main/java/hello/Application.java` [source,java,tabsize=2] ---- -package hello; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.reactive.function.client.WebClient; - -@RestController -@SpringBootApplication -public class ReadingApplication { - - @RequestMapping("/to-read") - public Mono toRead() { - return WebClient.builder().build() - .get().uri("http://localhost:8090/recommended").retrieve() - .bodyToMono(String.class); - } - - public static void main(String[] args) { - SpringApplication.run(ReadingApplication.class, args); - } -} +include::complete/src/main/java/hello/Application.java[] ---- -To get the list from Bookstore, we're using Spring's `WebClient` class. `WebClient` makes an HTTP GET request to the Bookstore service's URL as we provide it and then returns the result as a `Mono` of `String`. (For more information on using Spring to consume a RESTful service using `WebClient`, see the https://spring.io/guides/gs/reactive-rest-service/[Building a Reactive RESTful Web Service] guide.) +include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/spring-boot-application.adoc[] -Add the `server.port` property to `src/main/resources/application.properties`: +include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_an_executable_jar_subhead.adoc[] -`reading/src/main/resources/application.properties` -[source,properties] ----- -include::complete/reading/src/main/resources/application.properties[] ----- - -We now can access, in a browser, the `/to-read` endpoint on our Reading application, and see our reading list. Yet since we rely on the Bookstore application, if anything happens to it, or if Reading is simply unable to access Bookstore, we'll have no list and our users will get a nasty HTTP `500` error message. - -== Apply The Circuit Breaker Pattern -Spring Cloud's Circuit Breaker library provides an implementation of the Circuit Breaker pattern: -when we wrap a method call in a circuit breaker, Spring Cloud Circuit Breaker watches for failing -calls to that method, and if failures build up to a threshold, Spring Cloud Circuit Breaker opens -the circuit so that subsequent calls automatically fail. While the circuit is open, Spring Cloud -Circuit Breaker redirects calls to the method, and they’re passed on to our specified fallback -method. - -Spring Cloud Circuit Breaker supports many different circuit breaker implementations including, -Resilience4J, Hystrix, Sentinal, and Spring Retry. In this guide we will use the Resilience4J -implementation. To use this implementation we just need to add `spring-cloud-starter-circuitbreaker-reactor-resilience4j` -to our application's classpath. - -`reading/pom.xml` -[source,xml] ----- -include::complete/reading/pom.xml[] ----- - -`reading/build.gradle` -[source,groovy] ----- -include::complete/reading/build.gradle[] ----- - -Spring Cloud Circuit Breaker provides an interface called `ReactiveCircuitBreakerFactory` which -we can use to create new circuit breakers for our application. An implementation of this interface -will be auto-configured based on the starter that is on your application's classpath. Lets create -a new service that uses this interface to make API calls to the Bookstore application - -`reading/src/main/java/hello/BookService.java` -[source,java] ----- -include::complete/reading/src/main/java/hello/BookService.java[] ----- - -The `ReactiveCircuitBreakerFactory` has a single method called `create` we can use to create new circuit -breakers. Once we have our circuit breaker all we have -to do is call `run`. Run takes a `Mono` or `Flux` and an optional -`Function`. The optional `Function` parameter acts as our fallback if anything goes wrong. In our -sample here the fallback will just return a `Mono` containing the `String` `Cloud Native Java (O'Reilly)`. - -With our new service in place, we can update the code in `ReadingApplication` to use this new service. - -`reading/src/main/java/hello/ReadingApplication.java` -[source,java] ----- -include::complete/reading/src/main/java/hello/ReadingApplication.java[] ----- +include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/master/build_an_executable_jar_with_both.adoc[] -== Try it out +Logging output is displayed. The service should be up and running within a few seconds. -Run both the Bookstore service and the Reading service, and then open a browser to the Reading service, at `localhost:8080/to-read`. You should see the complete recommended reading list: ----- -Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt) ----- +== Test the application -Now shut down the Bookstore application. Our list source is gone, but thanks to Hystrix and Spring Cloud Netflix, we have a reliable abbreviated list to stand in the gap; you should see: +Now that the application is running, you can test it. ----- -Cloud Native Java (O'Reilly) ----- == Summary -Congratulations! You've just developed a Spring application that uses the Circuit Breaker pattern to protect against cascading failures and to provide fallback behavior for potentially failing calls. - +Congratulations! You've just developed a Spring application! diff --git a/complete/bookstore/.mvn/wrapper/maven-wrapper.jar b/complete/bookstore/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d50..0000000 Binary files a/complete/bookstore/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/complete/bookstore/.mvn/wrapper/maven-wrapper.properties b/complete/bookstore/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947..0000000 --- a/complete/bookstore/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/complete/bookstore/build.gradle b/complete/bookstore/build.gradle deleted file mode 100644 index 11efa36..0000000 --- a/complete/bookstore/build.gradle +++ /dev/null @@ -1,45 +0,0 @@ -buildscript { - ext { - springBootVersion = '2.2.2.RELEASET' - } - repositories { - mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' - -bootJar { - baseName = 'bookstore' - version = '0.0.1-SNAPSHOT' -} -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - mavenCentral() -} - - -dependencies { - compile('org.springframework.boot:spring-boot-starter-webflux') - testCompile('org.springframework.boot:spring-boot-starter-test') -} - - -eclipse { - classpath { - containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') - containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' - } -} - diff --git a/complete/bookstore/pom.xml b/complete/bookstore/pom.xml deleted file mode 100644 index 2f0a39c..0000000 --- a/complete/bookstore/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - 4.0.0 - - hello - bookstore - 0.0.1-SNAPSHOT - jar - - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - - - - UTF-8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter-webflux - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - diff --git a/complete/bookstore/src/main/java/hello/BookstoreApplication.java b/complete/bookstore/src/main/java/hello/BookstoreApplication.java deleted file mode 100644 index 6dfa00a..0000000 --- a/complete/bookstore/src/main/java/hello/BookstoreApplication.java +++ /dev/null @@ -1,22 +0,0 @@ -package hello; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestMapping; - -@RestController -@SpringBootApplication -public class BookstoreApplication { - - @RequestMapping(value = "/recommended") - public Mono readingList(){ - return Mono.just("Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)"); - } - - public static void main(String[] args) { - SpringApplication.run(BookstoreApplication.class, args); - } -} diff --git a/complete/bookstore/src/main/resources/application.properties b/complete/bookstore/src/main/resources/application.properties deleted file mode 100644 index f620381..0000000 --- a/complete/bookstore/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8090 diff --git a/complete/bookstore/src/test/java/hello/BookstoreApplicationTests.java b/complete/bookstore/src/test/java/hello/BookstoreApplicationTests.java deleted file mode 100644 index 1c77fd2..0000000 --- a/complete/bookstore/src/test/java/hello/BookstoreApplicationTests.java +++ /dev/null @@ -1,26 +0,0 @@ -package hello; - -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.test.context.junit4.SpringRunner; -import org.springframework.test.web.reactive.server.WebTestClient; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) -public class BookstoreApplicationTests { - - @Autowired - private WebTestClient webTestClient; - - @Test - public void recommendedTest() { - webTestClient.get().uri("/recommended").exchange() - .expectStatus().isOk() - .expectBody(String.class).value(m -> m.equals("Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)")); - } -} diff --git a/complete/reading/.mvn/wrapper/maven-wrapper.jar b/complete/reading/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d50..0000000 Binary files a/complete/reading/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/complete/reading/.mvn/wrapper/maven-wrapper.properties b/complete/reading/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947..0000000 --- a/complete/reading/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/complete/reading/build.gradle b/complete/reading/build.gradle deleted file mode 100644 index a5b8f38..0000000 --- a/complete/reading/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -buildscript { - ext { - springBootVersion = '2.2.2.RELEASE' - } - repositories { - mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' - -bootJar { - baseName = 'reading' - version = '0.0.1-SNAPSHOT' -} -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - mavenCentral() -} - - -dependencies { - compile('org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j') - compile('org.springframework.boot:spring-boot-starter-webflux') - testCompile('org.springframework.boot:spring-boot-starter-test') -} - -dependencyManagement { - imports { - mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR1" - } -} - -eclipse { - classpath { - containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') - containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' - } -} - diff --git a/complete/reading/pom.xml b/complete/reading/pom.xml deleted file mode 100644 index 8a21fbe..0000000 --- a/complete/reading/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - 4.0.0 - - hello - reading - 0.0.1-SNAPSHOT - jar - - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - - - - UTF-8 - 1.8 - - - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-reactor-resilience4j - - - org.springframework.boot - spring-boot-starter-webflux - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.cloud - spring-cloud-dependencies - Hoxton.SR1 - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - diff --git a/complete/reading/src/main/java/hello/BookService.java b/complete/reading/src/main/java/hello/BookService.java deleted file mode 100644 index 67f0b0a..0000000 --- a/complete/reading/src/main/java/hello/BookService.java +++ /dev/null @@ -1,32 +0,0 @@ -package hello; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.stereotype.Service; -import org.springframework.web.reactive.function.client.WebClient; - -@Service -public class BookService { - - private static final Logger LOG = LoggerFactory.getLogger(BookService.class); - - - private final WebClient webClient; - private final ReactiveCircuitBreaker readingListCircuitBreaker; - - public BookService(ReactiveCircuitBreakerFactory circuitBreakerFactory) { - this.webClient = WebClient.builder().baseUrl("http://localhost:8090").build(); - this.readingListCircuitBreaker = circuitBreakerFactory.create("recommended"); - } - - public Mono readingList() { - return readingListCircuitBreaker.run(webClient.get().uri("/recommended").retrieve().bodyToMono(String.class), throwable -> { - LOG.warn("Error making request to book service", throwable); - return Mono.just("Cloud Native Java (O'Reilly)"); - }); - } -} diff --git a/complete/reading/src/main/java/hello/ReadingApplication.java b/complete/reading/src/main/java/hello/ReadingApplication.java deleted file mode 100644 index a7fd88e..0000000 --- a/complete/reading/src/main/java/hello/ReadingApplication.java +++ /dev/null @@ -1,27 +0,0 @@ -package hello; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.reactive.function.client.WebClient; - -@RestController -@SpringBootApplication -public class ReadingApplication { - - @Autowired - private BookService bookService; - - @RequestMapping("/to-read") - public Mono toRead() { - return bookService.readingList(); - } - - public static void main(String[] args) { - SpringApplication.run(ReadingApplication.class, args); - } -} diff --git a/complete/reading/src/main/resources/application.properties b/complete/reading/src/main/resources/application.properties deleted file mode 100644 index 4c00e40..0000000 --- a/complete/reading/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8080 diff --git a/complete/reading/src/test/java/hello/BookServiceTests.java b/complete/reading/src/test/java/hello/BookServiceTests.java deleted file mode 100644 index 61127b9..0000000 --- a/complete/reading/src/test/java/hello/BookServiceTests.java +++ /dev/null @@ -1,32 +0,0 @@ -package hello; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.client.MockRestServiceServer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - - -@RunWith(SpringRunner.class) -@RestClientTest(BookService.class) -public class BookServiceTests { - - @Autowired - private BookService bookService; - - @Autowired - private MockRestServiceServer server; - - @Test - public void readingListTest() { - this.server.expect(requestTo("http://localhost:8090/recommended")) - .andRespond(withSuccess("books", MediaType.TEXT_PLAIN)); - assertThat(bookService.readingList()).isEqualTo("books"); - } -} diff --git a/complete/reading/src/test/java/hello/ReadingApplicationTests.java b/complete/reading/src/test/java/hello/ReadingApplicationTests.java deleted file mode 100644 index 7bfb8dc..0000000 --- a/complete/reading/src/test/java/hello/ReadingApplicationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -package hello; - -import org.junit.After; -import org.junit.Before; -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.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT) -public class ReadingApplicationTests { - - private MockRestServiceServer server; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private RestTemplate rest; - - @Before - public void setup() { - this.server = MockRestServiceServer.createServer(rest); - } - - @After - public void teardown() { - this.server = null; - } - - @Test - public void toReadTest() { - this.server.expect(requestTo("http://localhost:8090/recommended")) - .andExpect(method(HttpMethod.GET)). - andRespond(withSuccess("books", MediaType.TEXT_PLAIN)); - String books = testRestTemplate.getForObject("/to-read", String.class); - assertThat(books).isEqualTo("books"); - } - - @Test - public void toReadFailureTest() { - this.server.expect(requestTo("http://localhost:8090/recommended")). - andExpect(method(HttpMethod.GET)).andRespond(withServerError()); - String books = testRestTemplate.getForObject("/to-read", String.class); - assertThat(books).isEqualTo("Cloud Native Java (O'Reilly)"); - } -} diff --git a/initial/bookstore/.mvn/wrapper/maven-wrapper.jar b/initial/bookstore/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d50..0000000 Binary files a/initial/bookstore/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/initial/bookstore/.mvn/wrapper/maven-wrapper.properties b/initial/bookstore/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947..0000000 --- a/initial/bookstore/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/initial/bookstore/build.gradle b/initial/bookstore/build.gradle deleted file mode 100644 index c275586..0000000 --- a/initial/bookstore/build.gradle +++ /dev/null @@ -1,45 +0,0 @@ -buildscript { - ext { - springBootVersion = '2.2.2.RELEASE' - } - repositories { - mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' - -bootJar { - baseName = 'bookstore' - version = '0.0.1-SNAPSHOT' -} -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - mavenCentral() -} - - -dependencies { - compile('org.springframework.boot:spring-boot-starter-webflux') - testCompile('org.springframework.boot:spring-boot-starter-test') -} - - -eclipse { - classpath { - containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') - containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' - } -} - diff --git a/initial/bookstore/pom.xml b/initial/bookstore/pom.xml deleted file mode 100644 index 61ab60d..0000000 --- a/initial/bookstore/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - 4.0.0 - - hello - bookstore - 0.0.1-SNAPSHOT - jar - - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - - - - UTF-8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter-webflux - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - diff --git a/initial/reading/.mvn/wrapper/maven-wrapper.jar b/initial/reading/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d50..0000000 Binary files a/initial/reading/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/initial/reading/.mvn/wrapper/maven-wrapper.properties b/initial/reading/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947..0000000 --- a/initial/reading/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/initial/reading/build.gradle b/initial/reading/build.gradle deleted file mode 100644 index 6f941cd..0000000 --- a/initial/reading/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -buildscript { - ext { - springBootVersion = '2.2.2.RELEASE' - } - repositories { - mavenCentral() - maven { url 'https://repo.spring.io/milestone' } - maven { url 'https://repo.spring.io/snapshot' } - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } -} - -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' - -bootJar { - baseName = 'reading' - version = '0.0.1-SNAPSHOT' -} -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - mavenCentral() -} - - -dependencies { - compile('spring-cloud-starter-circuitbreaker-reactor-resilience4j') - compile('org.springframework.boot:spring-boot-starter-webflux') - testCompile('org.springframework.boot:spring-boot-starter-test') -} - -dependencyManagement { - imports { - mavenBom "org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR1" - } -} - -eclipse { - classpath { - containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') - containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' - } -} - diff --git a/initial/reading/pom.xml b/initial/reading/pom.xml deleted file mode 100644 index 5741ed0..0000000 --- a/initial/reading/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - 4.0.0 - - hello - reading - 0.0.1-SNAPSHOT - jar - - - org.springframework.boot - spring-boot-starter-parent - 2.2.2.RELEASE - - - - - UTF-8 - 1.8 - - - - - org.springframework.cloud - spring-cloud-starter-circuitbreaker-reactor-resilience4j - - - org.springframework.boot - spring-boot-starter-webflux - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.cloud - spring-cloud-dependencies - Hoxton.SR1 - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - -