[BAEL-3311] Spring Cloud Gateway Routing Predicate Factories (#8549)
* [BAEL-3311] Spring Cloud Gateway Routing Predicate Factories * [BAEL-3311] Code formatting * [BAEL-3311] LiveTests
This commit is contained in:
parent
1a67e0a280
commit
24e69ed49a
|
@ -68,6 +68,10 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.springcloudgateway.custompredicates;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CustomPredicatesApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(CustomPredicatesApplication.class)
|
||||
.profiles("customroutes")
|
||||
.run(args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.springcloudgateway.custompredicates.config;
|
||||
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.baeldung.springcloudgateway.custompredicates.factories.GoldenCustomerRoutePredicateFactory;
|
||||
import com.baeldung.springcloudgateway.custompredicates.factories.GoldenCustomerRoutePredicateFactory.Config;
|
||||
import com.baeldung.springcloudgateway.custompredicates.service.GoldenCustomerService;
|
||||
|
||||
@Configuration
|
||||
public class CustomPredicatesConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
public GoldenCustomerRoutePredicateFactory goldenCustomer(GoldenCustomerService goldenCustomerService) {
|
||||
return new GoldenCustomerRoutePredicateFactory(goldenCustomerService);
|
||||
}
|
||||
|
||||
|
||||
//@Bean
|
||||
public RouteLocator routes(RouteLocatorBuilder builder, GoldenCustomerRoutePredicateFactory gf ) {
|
||||
|
||||
return builder.routes()
|
||||
.route("dsl_golden_route", r -> r.path("/dsl_api/**")
|
||||
.filters(f -> f.stripPrefix(1))
|
||||
.uri("https://httpbin.org")
|
||||
.predicate(gf.apply(new Config(true, "customerId"))))
|
||||
.route("dsl_common_route", r -> r.path("/dsl_api/**")
|
||||
.filters(f -> f.stripPrefix(1))
|
||||
.uri("https://httpbin.org")
|
||||
.predicate(gf.apply(new Config(false, "customerId"))))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package com.baeldung.springcloudgateway.custompredicates.factories;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import com.baeldung.springcloudgateway.custompredicates.service.GoldenCustomerService;
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
public class GoldenCustomerRoutePredicateFactory extends AbstractRoutePredicateFactory<GoldenCustomerRoutePredicateFactory.Config> {
|
||||
|
||||
private final GoldenCustomerService goldenCustomerService;
|
||||
|
||||
public GoldenCustomerRoutePredicateFactory(GoldenCustomerService goldenCustomerService ) {
|
||||
super(Config.class);
|
||||
this.goldenCustomerService = goldenCustomerService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> shortcutFieldOrder() {
|
||||
return Arrays.asList("isGolden","customerIdCookie");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Predicate<ServerWebExchange> apply(Config config) {
|
||||
|
||||
return (ServerWebExchange t) -> {
|
||||
List<HttpCookie> cookies = t.getRequest()
|
||||
.getCookies()
|
||||
.get(config.getCustomerIdCookie());
|
||||
|
||||
boolean isGolden;
|
||||
if ( cookies == null || cookies.isEmpty()) {
|
||||
isGolden = false;
|
||||
}
|
||||
else {
|
||||
String customerId = cookies.get(0).getValue();
|
||||
isGolden = goldenCustomerService.isGoldenCustomer(customerId);
|
||||
}
|
||||
|
||||
return config.isGolden()?isGolden:!isGolden;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Validated
|
||||
public static class Config {
|
||||
boolean isGolden = true;
|
||||
|
||||
@NotEmpty
|
||||
String customerIdCookie = "customerId";
|
||||
|
||||
|
||||
public Config() {}
|
||||
|
||||
public Config( boolean isGolden, String customerIdCookie) {
|
||||
this.isGolden = isGolden;
|
||||
this.customerIdCookie = customerIdCookie;
|
||||
}
|
||||
|
||||
public boolean isGolden() {
|
||||
return isGolden;
|
||||
}
|
||||
|
||||
public void setGolden(boolean value) {
|
||||
this.isGolden = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the customerIdCookie
|
||||
*/
|
||||
public String getCustomerIdCookie() {
|
||||
return customerIdCookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customerIdCookie the customerIdCookie to set
|
||||
*/
|
||||
public void setCustomerIdCookie(String customerIdCookie) {
|
||||
this.customerIdCookie = customerIdCookie;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package com.baeldung.springcloudgateway.custompredicates.service;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class GoldenCustomerService {
|
||||
|
||||
public boolean isGoldenCustomer(String customerId) {
|
||||
|
||||
// TODO: Add some AI logic to check is this customer deserves a "golden" status ;^)
|
||||
if ( "baeldung".equalsIgnoreCase(customerId)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: golden_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
- Path=/api/**
|
||||
- GoldenCustomer=true
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
- AddRequestHeader=GoldenCustomer,true
|
||||
- id: common_route
|
||||
uri: https://httpbin.org
|
||||
predicates:
|
||||
- Path=/api/**
|
||||
- name: GoldenCustomer
|
||||
args:
|
||||
golden: false
|
||||
customerIdCookie: customerId
|
||||
filters:
|
||||
- StripPrefix=1
|
||||
- AddRequestHeader=GoldenCustomer,false
|
||||
|
||||
|
||||
|
|
@ -5,6 +5,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import org.assertj.core.api.Condition;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
|
@ -27,6 +28,7 @@ public class CustomFiltersLiveTest {
|
|||
@LocalServerPort
|
||||
String port;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient client;
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.springcloudgateway.custompredicates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
import org.junit.Before;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
/**
|
||||
* This test requires
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@ActiveProfiles("customroutes")
|
||||
public class CustomPredicatesApplicationLiveTest {
|
||||
|
||||
@LocalServerPort
|
||||
String serverPort;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void givenNormalCustomer_whenCallHeadersApi_thenResponseForNormalCustomer() throws JSONException {
|
||||
|
||||
String url = "http://localhost:" + serverPort + "/api/headers";
|
||||
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
JSONObject json = new JSONObject(response.getBody());
|
||||
JSONObject headers = json.getJSONObject("headers");
|
||||
assertThat(headers.getString("Goldencustomer")).isEqualTo("false");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGoldenCustomer_whenCallHeadersApi_thenResponseForGoldenCustomer() throws JSONException {
|
||||
|
||||
String url = "http://localhost:" + serverPort + "/api/headers";
|
||||
RequestEntity<Void> request = RequestEntity
|
||||
.get(URI.create(url))
|
||||
.header("Cookie", "customerId=baeldung")
|
||||
.build();
|
||||
|
||||
ResponseEntity<String> response = restTemplate.exchange(request, String.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
JSONObject json = new JSONObject(response.getBody());
|
||||
JSONObject headers = json.getJSONObject("headers");
|
||||
assertThat(headers.getString("Goldencustomer")).isEqualTo("true");
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue