
kalix.springsdk.impl.WebClientProviderHolder.scala Maven / Gradle / Ivy
/*
* Copyright 2021 Lightbend Inc.
*
* 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
*
* http://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 kalix.springsdk.impl
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import akka.actor.ActorSystem
import akka.actor.ClassicActorSystemProvider
import akka.actor.ExtendedActorSystem
import akka.actor.Extension
import akka.actor.ExtensionId
import akka.actor.ExtensionIdProvider
import akka.annotation.InternalApi
import kalix.javasdk.impl.ProxyInfoHolder
import kalix.springsdk.WebClientProvider
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.client.ExchangeFilterFunctions
import org.springframework.web.reactive.function.client.WebClient
/**
* INTERNAL API
*/
@InternalApi
private[springsdk] object WebClientProviderHolder
extends ExtensionId[WebClientProviderHolder]
with ExtensionIdProvider {
override def get(system: ActorSystem): WebClientProviderHolder = super.get(system)
override def get(system: ClassicActorSystemProvider): WebClientProviderHolder = super.get(system)
override def createExtension(system: ExtendedActorSystem): WebClientProviderHolder =
new WebClientProviderHolder(system)
override def lookup: ExtensionId[_ <: Extension] = this
}
class WebClientProviderHolder(system: ExtendedActorSystem) extends Extension {
val webClientProvider = new WebClientProviderImpl(system)
}
/**
* INTERNAL API
*/
@InternalApi
private[springsdk] class WebClientProviderImpl(system: ExtendedActorSystem) extends WebClientProvider {
private val proxyInfoHolder = ProxyInfoHolder(system)
private val clients: ConcurrentMap[String, WebClient] = new ConcurrentHashMap()
private val MaxCrossServiceResponseContentLength =
system.settings.config.getBytes("kalix.cross-service.max-content-length").toInt
override def webClientFor(host: String): WebClient = {
clients.computeIfAbsent(
host,
_ => {
val remoteAddHeader = proxyInfoHolder.remoteIdentificationHeader
buildClient(host, 80, remoteAddHeader)
})
}
val localWebClient: WebClient = {
val localAddHeader = proxyInfoHolder.localIdentificationHeader
val clientOpt =
for {
host <- proxyInfoHolder.proxyHostname
port <- proxyInfoHolder.proxyPort
} yield buildClient(host, port, localAddHeader)
clientOpt.getOrElse {
throw new IllegalStateException(
"Service proxy hostname and/or port are not set by proxy at discovery, too old proxy version?")
}
}
private def buildClient(host: String, port: Int, identificationHeader: Option[(String, String)]) = {
val builder =
WebClient.builder
.baseUrl(s"http://$host:$port")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.filter(ExchangeFilterFunctions.limitResponseSize(MaxCrossServiceResponseContentLength))
identificationHeader.foreach { case (key, value) =>
builder.defaultHeader(key, value)
}
builder.build()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy