diff --git a/README.md b/README.md
index fd378e5d4..e2774f065 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,9 @@ the URL for an event stream to monitor, for example the `api-gateway` service ru
or running into docker: `http://api-gateway:8080/actuator/hystrix.stream`
-You can tell Config Server to use your local Git repository by using `local` Spring profile and setting
+You can tell Config Server to use your local Git repository by using `native` Spring profile and setting
`GIT_REPO` environment variable, for example:
-`-Dspring.profiles.active=local -DGIT_REPO=/projects/spring-petclinic-microservices-config`
+`-Dspring.profiles.active=native -DGIT_REPO=/projects/spring-petclinic-microservices-config`
## Starting services locally with docker-compose
In order to start entire infrastructure using Docker, you have to build images by executing `./mvnw clean install -PbuildDocker`
diff --git a/pom.xml b/pom.xml
index 38fe5a9fe..cd85814de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,12 +6,12 @@
org.springframework.boot
spring-boot-starter-parent
- 2.1.4.RELEASE
+ 2.2.1.RELEASE
org.springframework.samples
spring-petclinic-microservices
- 2.1.4
+ 2.2.1
${project.artifactId}
pom
@@ -30,8 +30,8 @@
1.8
3.11.1
- 2.1.2.RELEASE
- Greenwich.SR1
+ 2.2.0.RELEASE
+ Hoxton.RC2
2.22.0
@@ -177,10 +177,24 @@
- repository.spring.milestone
- Spring Milestone Repository
- http://repo.spring.io/milestone
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
diff --git a/spring-petclinic-admin-server/pom.xml b/spring-petclinic-admin-server/pom.xml
index d27aa29af..0f9c746d2 100644
--- a/spring-petclinic-admin-server/pom.xml
+++ b/spring-petclinic-admin-server/pom.xml
@@ -12,7 +12,7 @@
org.springframework.samples
spring-petclinic-microservices
- 2.1.4
+ 2.2.1
diff --git a/spring-petclinic-api-gateway/pom.xml b/spring-petclinic-api-gateway/pom.xml
index be54a5828..7b66f6c21 100644
--- a/spring-petclinic-api-gateway/pom.xml
+++ b/spring-petclinic-api-gateway/pom.xml
@@ -11,7 +11,7 @@
org.springframework.samples
spring-petclinic-microservices
- 2.1.4
+ 2.2.1
@@ -60,6 +60,20 @@
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
+
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-ribbon
+
+
+ org.springframework.cloud
+ spring-cloud-netflix-ribbon
+
+
+ com.netflix.ribbon
+ ribbon-eureka
+
+
org.springframework.cloud
@@ -72,6 +86,12 @@
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
+
+
+ org.springframework.cloud
+ spring-cloud-netflix-ribbon
+
+
@@ -125,6 +145,11 @@
junit-jupiter-engine
test
+
+ com.squareup.okhttp3
+ mockwebserver
+ test
+
diff --git a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
index b00c90ab1..1add5f1d8 100644
--- a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
+++ b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
@@ -26,6 +26,7 @@
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
@@ -50,6 +51,12 @@ RestTemplate loadBalancedRestTemplate() {
return new RestTemplate();
}
+ @Bean
+ @LoadBalanced
+ public WebClient.Builder loadBalancedWebClientBuilder() {
+ return WebClient.builder();
+ }
+
@Value("classpath:/static/index.html")
private Resource indexHtml;
@@ -61,7 +68,7 @@ RestTemplate loadBalancedRestTemplate() {
RouterFunction> routerFunction() {
RouterFunction router = RouterFunctions.resources("/**", new ClassPathResource("static/"))
.andRoute(RequestPredicates.GET("/"),
- request -> ServerResponse.ok().contentType(MediaType.TEXT_HTML).syncBody(indexHtml));
+ request -> ServerResponse.ok().contentType(MediaType.TEXT_HTML).bodyValue(indexHtml));
return router;
}
}
diff --git a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/CustomersServiceClient.java b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/CustomersServiceClient.java
index 2aaa6c674..0cb31c9b1 100644
--- a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/CustomersServiceClient.java
+++ b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/CustomersServiceClient.java
@@ -19,6 +19,8 @@
import org.springframework.samples.petclinic.api.dto.OwnerDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
/**
* @author Maciej Szarlinski
@@ -27,9 +29,12 @@
@RequiredArgsConstructor
public class CustomersServiceClient {
- private final RestTemplate loadBalancedRestTemplate;
+ private final WebClient.Builder webClientBuilder;
- public OwnerDetails getOwner(final int ownerId) {
- return loadBalancedRestTemplate.getForObject("http://customers-service/owners/{ownerId}", OwnerDetails.class, ownerId);
+ public Mono getOwner(final int ownerId) {
+ return webClientBuilder.build().get()
+ .uri("http://customers-service/owners/{ownerId}", ownerId)
+ .retrieve()
+ .bodyToMono(OwnerDetails.class);
}
}
diff --git a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
index 97a6af97d..8f9c392a9 100644
--- a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
+++ b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
@@ -15,22 +15,18 @@
*/
package org.springframework.samples.petclinic.api.application;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.RequiredArgsConstructor;
import org.springframework.samples.petclinic.api.dto.VisitDetails;
import org.springframework.samples.petclinic.api.dto.Visits;
import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
-import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
-import static org.springframework.web.util.UriComponentsBuilder.fromHttpUrl;
/**
* @author Maciej Szarlinski
@@ -39,24 +35,29 @@
@RequiredArgsConstructor
public class VisitsServiceClient {
- private final RestTemplate loadBalancedRestTemplate;
+ // Could be changed for testing purpose
+ private String hostname = "http://visits-service/";
- @HystrixCommand(fallbackMethod = "emptyVisitsForPets")
- public Map> getVisitsForPets(final List petIds) {
- UriComponentsBuilder builder = fromHttpUrl("http://visits-service/pets/visits")
- .queryParam("petId", joinIds(petIds));
+ private final WebClient.Builder webClientBuilder;
- return loadBalancedRestTemplate.getForObject(builder.toUriString(), Visits.class)
- .getItems()
- .stream()
- .collect(groupingBy(VisitDetails::getPetId));
+ // FIXME HYSTRIX @HystrixCommand(fallbackMethod = "emptyVisitsForPets")
+ public Mono getVisitsForPets(final List petIds) {
+ return webClientBuilder.build()
+ .get()
+ .uri(hostname + "pets/visits?petId={petId}", joinIds(petIds))
+ .retrieve()
+ .bodyToMono(Visits.class);
}
private String joinIds(List petIds) {
return petIds.stream().map(Object::toString).collect(joining(","));
}
- private Map> emptyVisitsForPets(List petIds) {
- return Collections.emptyMap();
+ private Mono