All Downloads are FREE. Search and download functionalities are using the official Maven repository.

util.Request.kt Maven / Gradle / Ivy

The newest version!
package com.amplitude.experiment.util

import com.amplitude.experiment.LIBRARY_VERSION
import kotlinx.serialization.decodeFromString
import okhttp3.Call
import okhttp3.Callback
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.sse.EventSource
import okhttp3.sse.EventSourceListener
import okhttp3.sse.EventSources
import okio.IOException
import java.util.concurrent.CompletableFuture

internal inline fun  OkHttpClient.request(
    request: Request,
): CompletableFuture {
    val future = CompletableFuture()
    val call = newCall(request)
    call.enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response) {
            try {
                val result = response.use {
                    if (!response.isSuccessful) {
                        throw IOException("$request - error response: $response")
                    }
                    val body = response.body?.string() ?: throw IOException("$request - null response body")
                    json.decodeFromString(body)
                }
                future.complete(result)
            } catch (e: Exception) {
                future.completeExceptionally(e)
            }
        }

        override fun onFailure(call: Call, e: IOException) {
            future.completeExceptionally(e)
        }
    })
    return future
}

internal open class HttpErrorResponseException(
    val code: Int,
) : IOException("Request resulted error response $code")

private fun OkHttpClient.submit(
    request: Request,
): CompletableFuture {
    val future = CompletableFuture()
    val call = newCall(request)
    call.enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response) {
            future.complete(response)
        }

        override fun onFailure(call: Call, e: IOException) {
            future.completeExceptionally(e)
        }
    })
    return future
}

internal fun newGet(
    serverUrl: HttpUrl,
    path: String? = null,
    headers: Map? = null,
    queries: Map? = null,
): Request {
    val url = serverUrl.newBuilder().apply {
        if (path != null) {
            addPathSegments(path)
        }
        queries?.forEach {
            addQueryParameter(it.key, it.value)
        }
    }.build()
    val builder = Request.Builder().get().url(url)
    headers?.forEach {
        builder.addHeader(it.key, it.value)
    }
    builder.addHeader("X-Amp-Exp-Library", "experiment-jvm-server/$LIBRARY_VERSION")
    return builder.build()
}

internal inline fun  OkHttpClient.get(
    serverUrl: HttpUrl,
    path: String? = null,
    headers: Map? = null,
    queries: Map? = null,
    crossinline block: (Response) -> Unit,
): CompletableFuture {
    val request = newGet(serverUrl, path, headers, queries)
    return submit(request).thenApply {
        it.use { response ->
            block(response)
            val body = response.body?.string() ?: throw IOException("null response body")
            json.decodeFromString(body)
        }
    }
}

internal inline fun  OkHttpClient.get(
    serverUrl: HttpUrl,
    path: String? = null,
    headers: Map? = null,
    queries: Map? = null,
): CompletableFuture {
    return this.get(serverUrl, path, headers, queries) { response ->
        if (!response.isSuccessful) {
            throw HttpErrorResponseException(response.code)
        }
    }
}

internal fun OkHttpClient.newEventSource(request: Request, eventSourceListener: EventSourceListener): EventSource {
    // Creates an event source and immediately returns it. The connection is performed async.
    return EventSources.createFactory(this).newEventSource(request, eventSourceListener)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy