Add loadbalancing sample.

This commit is contained in:
Olga MaciaszekSharma
2023-10-20 16:18:32 +02:00
committed by Sébastien Deleuze
parent 680b442816
commit 2e5ebdb5db
12 changed files with 250 additions and 0 deletions

View File

@@ -47,6 +47,11 @@ h|test
|image:https://ci.spring.io/api/v1/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/context-refresh-http-cr-app-test/badge[link=https://ci.spring.io/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/context-refresh-http-cr-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/context-refresh-http-test/badge[link=https://ci.spring.io/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/context-refresh-http-test]
|loadbalancing
|image:https://ci.spring.io/api/v1/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/loadbalancing-app-test/badge[link=https://ci.spring.io/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/loadbalancing-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/loadbalancing-cr-app-test/badge[link=https://ci.spring.io/teams/spring-checkpoint-restore-smoke-tests/pipelines/spring-checkpoint-restore-smoke-tests-3.2.x/jobs/loadbalancing-cr-app-test]
|
|===
== Data

View File

@@ -18,6 +18,9 @@ groups:
- name: context-refresh-http
app_test: true
test: true
- name: loadbalancing
app_test: true
test: false
- name: data
smoke_tests:
- name: data-jdbc

View File

@@ -0,0 +1,26 @@
plugins {
id "java"
id "org.springframework.boot"
id "org.springframework.cr.smoke-test"
}
// Not using Spring Cloud bom due to existing issues with dependency management
ext {
set('springCloudCommonsVerions', "4.1.0-SNAPSHOT")
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.crac:crac:$cracVersion")
implementation(project(":cr-listener"))
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer:${springCloudCommonsVerions}")
testImplementation("org.springframework.boot:spring-boot-starter-test")
appTestImplementation(project(":cr-smoke-test-support"))
}
crSmokeTest {
webApplication = true
}

View File

@@ -0,0 +1,9 @@
services:
test-service:
image: springcloud/test-service:latest
ports:
- "8081"
demo-service:
image: springcloud/demo-service:latest
ports:
- "8082"

View File

@@ -0,0 +1,23 @@
package com.example.loadbalancing;
import org.junit.jupiter.api.Test;
import org.springframework.cr.smoketest.support.junit.ApplicationTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
@ApplicationTest
class LoadBalancerApplicationTests {
@Test
void loadBalancing(WebTestClient webClient) {
webClient.get()
.exchange()
.expectStatus()
.isOk()
.expectBody()
.consumeWith(result -> assertThat(new String(result.getResponseBodyContent())).isEqualTo("testdemo"));
}
}

View File

@@ -0,0 +1,32 @@
package com.example.loadbalancing;
import com.example.loadbalancing.service.LoadBalancerClientTestService;
import reactor.core.publisher.Flux;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class LoadBalancerApplication {
public static void main(String[] args) {
SpringApplication.run(LoadBalancerApplication.class, args);
}
@RestController
static class TestController {
@Autowired
private LoadBalancerClientTestService testService;
@GetMapping("/")
public Flux<String> test() {
return testService.callServices();
}
}
}

View File

@@ -0,0 +1,24 @@
package com.example.loadbalancing.client;
import java.net.URI;
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
@Component
public class DemoServiceClient {
private final WebClient webClient;
public DemoServiceClient(@LoadBalanced WebClient.Builder builder) {
this.webClient = builder.build();
}
public Mono<String> demo() {
return webClient.get().uri(URI.create("http://demo-service")).retrieve().bodyToMono(String.class);
}
}

View File

@@ -0,0 +1,24 @@
package com.example.loadbalancing.client;
import java.net.URI;
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
@Component
public class TestServiceClient {
private final WebClient webClient;
public TestServiceClient(@LoadBalanced WebClient.Builder builder) {
this.webClient = builder.build();
}
public Mono<String> test() {
return webClient.get().uri(URI.create("http://test-service")).retrieve().bodyToMono(String.class);
}
}

View File

@@ -0,0 +1,47 @@
package com.example.loadbalancing.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.CompletionContext;
import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.context.annotation.Bean;
public class CustomLoadBalancerConfiguration {
@Bean
LoadBalancerLifecycle<Object, Object, ServiceInstance> loadBalancerLifecycle() {
return new TestLoadBalancerLifecycle();
}
static class TestLoadBalancerLifecycle implements LoadBalancerLifecycle<Object, Object, ServiceInstance> {
private static final Log LOG = LogFactory.getLog(TestLoadBalancerLifecycle.class);
@Override
public void onStart(Request<Object> request) {
if (LOG.isInfoEnabled()) {
LOG.info("On Start: " + request);
}
}
@Override
public void onStartRequest(Request<Object> request, Response<ServiceInstance> lbResponse) {
if (LOG.isInfoEnabled()) {
LOG.info("On Start Request: " + request + ", LB response: " + lbResponse);
}
}
@Override
public void onComplete(CompletionContext<Object, ServiceInstance, Object> completionContext) {
if (LOG.isInfoEnabled()) {
LOG.info("On Complete: " + completionContext);
}
}
}
}

View File

@@ -0,0 +1,19 @@
package com.example.loadbalancing.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
@LoadBalancerClient(name = "test-service", configuration = CustomLoadBalancerConfiguration.class)
public class WebClientConfig {
@LoadBalanced
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}

View File

@@ -0,0 +1,26 @@
package com.example.loadbalancing.service;
import com.example.loadbalancing.client.DemoServiceClient;
import com.example.loadbalancing.client.TestServiceClient;
import reactor.core.publisher.Flux;
import org.springframework.stereotype.Component;
@Component
public class LoadBalancerClientTestService {
private final TestServiceClient testServiceClient;
private final DemoServiceClient demoServiceClient;
public LoadBalancerClientTestService(TestServiceClient testServiceClient, DemoServiceClient demoServiceClient) {
this.testServiceClient = testServiceClient;
this.demoServiceClient = demoServiceClient;
}
public Flux<String> callServices() {
return testServiceClient.test().concatWith(demoServiceClient.demo());
}
}

View File

@@ -0,0 +1,12 @@
spring:
application:
name: loadbalancer-client
cloud:
discovery:
client:
simple:
instances:
test-service:
- uri: http://${TEST-SERVICE_HOST:localhost}:${TEST-SERVICE_PORT_8081:8081}
demo-service:
- uri: http://${DEMO-SERVICE_HOST:localhost}:${DEMO-SERVICE_PORT_8082:8082}