#1213 - Add support for Kotlin co-routines.
The ReactiveRepresentationModelAssembler and SimpleRepresentationModelAssembler both accept Flux inputs for entities. This change adds support for Kotlin co-routines to the same inputs. Related pull request: #1258.
This commit is contained in:
29
pom.xml
29
pom.xml
@@ -85,6 +85,8 @@
|
||||
<spring.version>5.2.5.RELEASE</spring.version>
|
||||
<spring-plugin.version>2.0.0.RELEASE</spring-plugin.version>
|
||||
<kotlin.version>1.3.71</kotlin.version>
|
||||
<kotlinx-coroutines.version>1.3.5</kotlinx-coroutines.version>
|
||||
<mockk.version>1.9.3</mockk.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
@@ -704,6 +706,20 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-bom</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-coroutines-bom</artifactId>
|
||||
<version>${kotlinx-coroutines.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -713,13 +729,16 @@
|
||||
<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.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-coroutines-reactor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -728,6 +747,12 @@
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.mockk</groupId>
|
||||
<artifactId>mockk</artifactId>
|
||||
<version>${mockk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.hateoas.server.reactive
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.reactive.awaitFirst
|
||||
import kotlinx.coroutines.reactor.asFlux
|
||||
import org.springframework.hateoas.CollectionModel
|
||||
import org.springframework.hateoas.RepresentationModel
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
|
||||
/**
|
||||
* Add support for Kotlin co-routines.
|
||||
*
|
||||
* @author Juergen Zimmerman
|
||||
* @author Greg Turnquist
|
||||
* @since 1.1
|
||||
*/
|
||||
suspend fun <T : Any, D : RepresentationModel<D>> ReactiveRepresentationModelAssembler<T, D>.toCollectionModel(
|
||||
entities: Flow<T>,
|
||||
exchange: ServerWebExchange): CollectionModel<D> = toCollectionModel(entities.asFlux(), exchange).awaitFirst()
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.hateoas.server.reactive
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.reactive.awaitFirst
|
||||
import kotlinx.coroutines.reactor.asFlux
|
||||
import org.springframework.hateoas.CollectionModel
|
||||
import org.springframework.hateoas.EntityModel
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
|
||||
/**
|
||||
* Add support for Kotlin co-routines.
|
||||
*
|
||||
* @author Juergen Zimmerman
|
||||
* @author Greg Turnquist
|
||||
* @since 1.1
|
||||
*/
|
||||
suspend fun <T : Any> SimpleReactiveRepresentationModelAssembler<T>.toCollectionModel(
|
||||
entities: Flow<T>,
|
||||
exchange: ServerWebExchange): CollectionModel<EntityModel<T>> = toCollectionModel(entities.asFlux(), exchange).awaitFirst()
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.server.reactive
|
||||
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.hateoas.EntityModel
|
||||
import org.springframework.hateoas.Link
|
||||
import org.springframework.hateoas.LinkRelation
|
||||
import org.springframework.hateoas.TestUtils
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
/**
|
||||
* @author Greg Turnquist
|
||||
* @since 1.1
|
||||
*/
|
||||
class ReactiveRepresentationModelAssemblerBuilderDslUnitTest : TestUtils() {
|
||||
|
||||
private val EMPLOYEES_RELATION = LinkRelation.of("employees")
|
||||
|
||||
private val employees = flow {
|
||||
emit(Employee("Frodo"))
|
||||
emit(Employee("Bilbo"))
|
||||
}
|
||||
|
||||
@Test // #1213
|
||||
fun `Kotlin Flows should render as CollectionModels`() {
|
||||
|
||||
val testResourceAssembler = TestResourceAssembler()
|
||||
val exchange = mockk<ServerWebExchange>()
|
||||
|
||||
runBlocking {
|
||||
val collectionModel = testResourceAssembler.toCollectionModel(employees, exchange)
|
||||
|
||||
assertThat(collectionModel.content.flatMap { entityModel -> entityModel.links })
|
||||
.containsExactlyInAnyOrder(Link.of("/employees", EMPLOYEES_RELATION), Link.of("/employees", EMPLOYEES_RELATION))
|
||||
}
|
||||
}
|
||||
|
||||
class TestResourceAssembler : ReactiveRepresentationModelAssembler<Employee, EntityModel<Employee>> {
|
||||
override fun toModel(entity: Employee, exchange: ServerWebExchange): Mono<EntityModel<Employee>> {
|
||||
return Mono.just(EntityModel.of(entity, Link.of("/employees", LinkRelation.of("employees"))))
|
||||
}
|
||||
}
|
||||
|
||||
data class Employee(val name: String)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.server.reactive
|
||||
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.hateoas.*
|
||||
import org.springframework.web.server.ServerWebExchange
|
||||
|
||||
/**
|
||||
* @author Greg Turnquist
|
||||
* @since 1.1
|
||||
*/
|
||||
class SimpleReactiveRexpresentationModelAssemblerBuilderDslUnitTest : TestUtils() {
|
||||
|
||||
private val employees = flow {
|
||||
emit(Employee("Frodo"))
|
||||
emit(Employee("Bilbo"))
|
||||
}
|
||||
|
||||
@Test // #1213
|
||||
fun `Kotlin Flows should render as CollectionModels`() {
|
||||
|
||||
val testResourceAssembler = SimpleTestResourceAssembler()
|
||||
val exchange = mockk<ServerWebExchange>()
|
||||
|
||||
runBlocking {
|
||||
val collectionModel = testResourceAssembler.toCollectionModel(employees, exchange)
|
||||
|
||||
assertThat(collectionModel.links).containsExactly(Link.of("/employees"))
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleTestResourceAssembler : SimpleReactiveRepresentationModelAssembler<Employee> {
|
||||
override fun addLinks(resources: CollectionModel<EntityModel<Employee>>, exchange: ServerWebExchange): CollectionModel<EntityModel<Employee>> {
|
||||
resources.add(Link.of("/employees"))
|
||||
return resources
|
||||
}
|
||||
}
|
||||
|
||||
data class Employee(val name: String)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user