Browse Source

Moves kotlin dsl to gateway-core (#96)

Fixes gh-95
pull/98/head
Biju Kunjummen 7 years ago committed by Spencer Gibb
parent
commit
c938a10e9b
  1. 2
      pom.xml
  2. 83
      spring-cloud-gateway-core/pom.xml
  3. 56
      spring-cloud-gateway-core/src/main/kotlin/org/springframework/cloud/gateway/route/GatewayDsl.kt
  4. 57
      spring-cloud-gateway-core/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt
  5. 85
      spring-cloud-gateway-kotlin-extensions/pom.xml
  6. 56
      spring-cloud-gateway-kotlin-extensions/src/main/kotlin/org/springframework/cloud/gateway/route/GatewayDsl.kt
  7. 57
      spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt

2
pom.xml

@ -51,6 +51,7 @@ @@ -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 @@ @@ -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>

83
spring-cloud-gateway-core/pom.xml

@ -66,6 +66,18 @@ @@ -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 @@ @@ -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 @@ @@ -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>

56
spring-cloud-gateway-core/src/main/kotlin/org/springframework/cloud/gateway/route/GatewayDsl.kt

@ -0,0 +1,56 @@ @@ -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)
}

57
spring-cloud-gateway-core/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt

@ -0,0 +1,57 @@ @@ -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()
}
}

85
spring-cloud-gateway-kotlin-extensions/pom.xml

@ -1,85 +0,0 @@ @@ -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>

56
spring-cloud-gateway-kotlin-extensions/src/main/kotlin/org/springframework/cloud/gateway/route/GatewayDsl.kt

@ -1,56 +0,0 @@ @@ -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)
}

57
spring-cloud-gateway-kotlin-extensions/src/test/kotlin/org/springframework/cloud/gateway/route/GatewayDslTests.kt

@ -1,57 +0,0 @@ @@ -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()
}
}
Loading…
Cancel
Save