committed by
Spencer Gibb
parent
0af4453ad2
commit
c938a10e9b
2
pom.xml
2
pom.xml
@@ -51,6 +51,7 @@
|
||||
<spring-cloud-commons.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-netflix.version>
|
||||
<spring-tuple.version>1.0.0.RELEASE</spring-tuple.version>
|
||||
<kotlin.version>1.1.51</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -136,7 +137,6 @@
|
||||
<module>spring-cloud-gateway-core</module>
|
||||
<module>spring-cloud-starter-gateway</module>
|
||||
<module>spring-cloud-gateway-sample</module>
|
||||
<module>spring-cloud-gateway-kotlin-extensions</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
|
||||
|
||||
@@ -66,6 +66,18 @@
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
@@ -92,6 +104,76 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!-- Based on instructions here - https://kotlinlang.org/docs/reference/using-maven.html -->
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>${kotlin.version}</version>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<goals> <goal>compile</goal> </goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
|
||||
<sourceDir>${project.basedir}/src/main/java</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<goals> <goal>test-compile</goal> </goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
|
||||
<sourceDir>${project.basedir}/src/test/java</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- Replacing default-compile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<!-- Replacing default-testCompile as it is treated specially by maven -->
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java8plus</id>
|
||||
@@ -103,7 +185,6 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.springframework.cloud.gateway.route
|
||||
|
||||
import reactor.core.publisher.Flux
|
||||
import java.util.function.Predicate
|
||||
|
||||
/**
|
||||
* A Kotlin based DSL to configure a [RouteLocator]
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* val routeLocator = gateway {
|
||||
* route {
|
||||
* id("test")
|
||||
* uri("http://httpbin.org:80")
|
||||
* predicate(host("**.abc.org") and path("/image/png"))
|
||||
* add(addResponseHeader("X-TestHeader", "foobar"))
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
fun gateway(routeLocator: RouteLocatorDsl.() -> Unit) = RouteLocatorDsl().apply(routeLocator).build()
|
||||
|
||||
|
||||
/**
|
||||
* Provider for [RouteLocator] DSL functionality
|
||||
*/
|
||||
class RouteLocatorDsl {
|
||||
private val routes = mutableListOf<Route>()
|
||||
|
||||
/**
|
||||
* DSL to add a route to the [RouteLocator]
|
||||
*
|
||||
* @see [Route.Builder]
|
||||
*/
|
||||
fun route(init: Route.Builder.() -> Unit) {
|
||||
routes += Route.builder().apply(init).build()
|
||||
}
|
||||
|
||||
fun build(): RouteLocator {
|
||||
return RouteLocator { Flux.fromIterable(this.routes) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to return a composed [Predicate] that tests against this [Predicate] AND the [other] predicate
|
||||
*/
|
||||
infix fun <T> Predicate<T>.and(other: Predicate<T>) = this.and(other)
|
||||
|
||||
/**
|
||||
* A helper to return a composed [Predicate] that tests against this [Predicate] OR the [other] predicate
|
||||
*/
|
||||
infix fun <T> Predicate<T>.or(other: Predicate<T>) = this.or(other)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.cloud.gateway.route
|
||||
|
||||
import org.junit.Test
|
||||
import org.springframework.cloud.gateway.filter.factory.GatewayFilters.addResponseHeader
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest
|
||||
import org.springframework.mock.web.server.MockServerWebExchange
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
import reactor.test.StepVerifier
|
||||
import java.net.URI
|
||||
|
||||
class GatewayDslTests {
|
||||
|
||||
@Test
|
||||
fun testSampleRouteDsl() {
|
||||
val routeLocator = gateway {
|
||||
route {
|
||||
id("test")
|
||||
uri("http://httpbin.org:80")
|
||||
predicate(host("**.abc.org") and path("/image/png"))
|
||||
add(addResponseHeader("X-TestHeader", "foobar"))
|
||||
}
|
||||
|
||||
route {
|
||||
id("test2")
|
||||
uri("http://httpbin.org:80")
|
||||
predicate(path("/image/webp") or path("/image/anotherone"))
|
||||
add(addResponseHeader("X-AnotherHeader", "baz"))
|
||||
add(addResponseHeader("X-AnotherHeader-2", "baz-2"))
|
||||
}
|
||||
}
|
||||
|
||||
StepVerifier
|
||||
.create(routeLocator.routes)
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test" && r.filters.size == 1 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
|
||||
val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp")
|
||||
.header("Host", "test.abc.org").build())
|
||||
|
||||
val filteredRoutes = routeLocator.routes.filter({ r -> r.predicate.test(sampleExchange) })
|
||||
|
||||
StepVerifier.create(filteredRoutes)
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
}
|
||||
}
|
||||
@@ -1,85 +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>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gateway</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-gateway-kotlin-extensions</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Gateway Kotlin Extensions</name>
|
||||
<description>Spring Cloud Gateway Kotlin Extensions</description>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
<kotlin.version>1.1.4-3</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gateway-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jre8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>${kotlin.version}</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,56 +0,0 @@
|
||||
package org.springframework.cloud.gateway.route
|
||||
|
||||
import reactor.core.publisher.Flux
|
||||
import java.util.function.Predicate
|
||||
|
||||
/**
|
||||
* A Kotlin based DSL to configure a [RouteLocator]
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* val routeLocator = gateway {
|
||||
* route {
|
||||
* id("test")
|
||||
* uri("http://httpbin.org:80")
|
||||
* predicate(host("**.abc.org") and path("/image/png"))
|
||||
* add(addResponseHeader("X-TestHeader", "foobar"))
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
fun gateway(routeLocator: RouteLocatorDsl.() -> Unit) = RouteLocatorDsl().apply(routeLocator).build()
|
||||
|
||||
|
||||
/**
|
||||
* Provider for [RouteLocator] DSL functionality
|
||||
*/
|
||||
class RouteLocatorDsl {
|
||||
private val routes = mutableListOf<Route>()
|
||||
|
||||
/**
|
||||
* DSL to add a route to the [RouteLocator]
|
||||
*
|
||||
* @see [Route.Builder]
|
||||
*/
|
||||
fun route(init: Route.Builder.() -> Unit) {
|
||||
routes += Route.builder().apply(init).build()
|
||||
}
|
||||
|
||||
fun build(): RouteLocator {
|
||||
return RouteLocator { Flux.fromIterable(this.routes) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to return a composed [Predicate] that tests against this [Predicate] AND the [other] predicate
|
||||
*/
|
||||
infix fun <T> Predicate<T>.and(other: Predicate<T>) = this.and(other)
|
||||
|
||||
/**
|
||||
* A helper to return a composed [Predicate] that tests against this [Predicate] OR the [other] predicate
|
||||
*/
|
||||
infix fun <T> Predicate<T>.or(other: Predicate<T>) = this.or(other)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package org.springframework.cloud.gateway.route
|
||||
|
||||
import org.junit.Test
|
||||
import org.springframework.cloud.gateway.filter.factory.GatewayFilters.addResponseHeader
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest
|
||||
import org.springframework.mock.web.server.MockServerWebExchange
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
import reactor.test.StepVerifier
|
||||
import java.net.URI
|
||||
|
||||
class GatewayDslTests {
|
||||
|
||||
@Test
|
||||
fun testSampleRouteDsl() {
|
||||
val routeLocator = gateway {
|
||||
route {
|
||||
id("test")
|
||||
uri("http://httpbin.org:80")
|
||||
predicate(host("**.abc.org") and path("/image/png"))
|
||||
add(addResponseHeader("X-TestHeader", "foobar"))
|
||||
}
|
||||
|
||||
route {
|
||||
id("test2")
|
||||
uri("http://httpbin.org:80")
|
||||
predicate(path("/image/webp") or path("/image/anotherone"))
|
||||
add(addResponseHeader("X-AnotherHeader", "baz"))
|
||||
add(addResponseHeader("X-AnotherHeader-2", "baz-2"))
|
||||
}
|
||||
}
|
||||
|
||||
StepVerifier
|
||||
.create(routeLocator.routes)
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test" && r.filters.size == 1 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
|
||||
val sampleExchange: ServerWebExchange = MockServerWebExchange.from(MockServerHttpRequest.get("/image/webp")
|
||||
.header("Host", "test.abc.org").build())
|
||||
|
||||
val filteredRoutes = routeLocator.routes.filter({ r -> r.predicate.test(sampleExchange) })
|
||||
|
||||
StepVerifier.create(filteredRoutes)
|
||||
.expectNextMatches({ r ->
|
||||
r.id == "test2" && r.filters.size == 2 && r.uri == URI.create("http://httpbin.org:80")
|
||||
})
|
||||
.expectComplete()
|
||||
.verify()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user