
com.bybutter.sisyphus.starter.grpc.transcoding.TranscodingRouterFunction.kt Maven / Gradle / Ivy
package com.bybutter.sisyphus.starter.grpc.transcoding
import com.bybutter.sisyphus.starter.webflux.EmptyRouterFunction
import io.grpc.Channel
import org.springframework.web.reactive.function.server.HandlerFunction
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
* Http request router based on Spring webflux function,
* provided Http+Json to gRpc+protobuf transcoding.
*/
class TranscodingRouterFunction constructor(
private val serviceRouters: List>,
private val transcodingChannel: Channel,
) : RouterFunction {
override fun route(request: ServerRequest): Mono> {
val oldAttributes = request.attributes().toMap()
// Set the channel attribute for creating gRPC proxy calls.
request.attributes()[TranscodingFunctions.GRPC_PROXY_CHANNEL_ATTRIBUTE] = transcodingChannel
// TODO: For performance considerations, we just found the first matched router,
// maybe we should choose the longest template for multiple matched.
return Flux.fromIterable(serviceRouters).concatMap {
it.route(request)
}.next().switchIfEmpty(
Mono.create> {
// Clear the attributes if we can't transcode current http request to gRPC.
request.attributes().clear()
request.attributes() += oldAttributes
it.success()
},
)
}
companion object {
operator fun invoke(
rules: Collection,
transcodingChannel: Channel,
): RouterFunction {
// Return empty router if no service routers created.
if (rules.isEmpty()) return EmptyRouterFunction
return TranscodingRouterFunction(
rules.map { TranscodingHttpRouterFunction(it) },
transcodingChannel,
)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy