AiConfig.kt
package org.openapitools.config
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.context.Context
import okhttp3.ConnectionPool
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import org.openapitools.internal.client.HelpServiceApi
import org.openapitools.internal.client.RecipeServiceApi
import org.openapitools.security.InternalHmacInterceptor
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import java.util.concurrent.TimeUnit
private class TracePropagationInterceptor(
private val openTelemetry: OpenTelemetry,
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
openTelemetry.propagators.textMapPropagator.inject(Context.current(), builder) { b, key, value ->
b!!.header(key, value)
}
return chain.proceed(builder.build())
}
}
@Configuration
class AiConfig(
private val openTelemetry: OpenTelemetry,
) {
@Value("\${ai.recipe.service.url:http://localhost:8090}")
private lateinit var aiRecipeServiceUrl: String
@Value("\${ai.help.service.url:http://localhost:8091}")
private lateinit var aiHelpServiceUrl: String
@Value("\${ai.hmac.secret}")
private lateinit var internalAuthSecret: String
private fun createBaseHttpClient(): OkHttpClient =
OkHttpClient
.Builder()
.connectionPool(ConnectionPool(5, 2, TimeUnit.SECONDS))
.readTimeout(60, TimeUnit.SECONDS) // Time allowed for Python to process and stream back data
.callTimeout(60, TimeUnit.SECONDS)
.addInterceptor(TracePropagationInterceptor(openTelemetry))
.addInterceptor(InternalHmacInterceptor(internalAuthSecret))
.build()
private val moshi =
Moshi
.Builder()
.addLast(KotlinJsonAdapterFactory())
.build()
@Bean
fun aiHelpServiceApi(): HelpServiceApi {
val retrofit =
Retrofit
.Builder()
.baseUrl(aiHelpServiceUrl.let { if (it.endsWith("/")) it else "$it/" })
.client(createBaseHttpClient())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
return retrofit.create(HelpServiceApi::class.java)
}
@Bean
fun aiRecipeServiceApi(): RecipeServiceApi {
val retrofit =
Retrofit
.Builder()
.baseUrl(aiRecipeServiceUrl.let { if (it.endsWith("/")) it else "$it/" })
.client(createBaseHttpClient())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
return retrofit.create(RecipeServiceApi::class.java)
}
}