Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ private constructor(
@get:JvmName("jsonMapper") val jsonMapper: JsonMapper,
@get:JvmName("clock") val clock: Clock,
@get:JvmName("baseUrl") val baseUrl: String,
@get:JvmName("apiKey") val apiKey: String?,
@get:JvmName("headers") val headers: ListMultimap<String, String>,
@get:JvmName("queryParams") val queryParams: ListMultimap<String, String>,
@get:JvmName("responseValidation") val responseValidation: Boolean,
@get:JvmName("maxRetries") val maxRetries: Int,
@get:JvmName("apiKey") val apiKey: String?,
) {

fun toBuilder() = Builder().from(this)
Expand All @@ -38,11 +38,11 @@ private constructor(
class Builder {

private var httpClient: HttpClient? = null
private var jsonMapper: JsonMapper? = null
private var jsonMapper: JsonMapper = jsonMapper()
private var clock: Clock = Clock.systemUTC()
private var baseUrl: String = PRODUCTION_URL
private var headers: MutableMap<String, MutableList<String>> = mutableMapOf()
private var queryParams: MutableMap<String, MutableList<String>> = mutableMapOf()
private var headers: ListMultimap<String, String> = ArrayListMultimap.create()
private var queryParams: ListMultimap<String, String> = ArrayListMultimap.create()
private var responseValidation: Boolean = false
private var maxRetries: Int = 2
private var apiKey: String? = null
Expand All @@ -53,14 +53,8 @@ private constructor(
jsonMapper = clientOptions.jsonMapper
clock = clientOptions.clock
baseUrl = clientOptions.baseUrl
headers =
clientOptions.headers.asMap().mapValuesTo(mutableMapOf()) { (_, value) ->
value.toMutableList()
}
queryParams =
clientOptions.queryParams.asMap().mapValuesTo(mutableMapOf()) { (_, value) ->
value.toMutableList()
}
headers = ArrayListMultimap.create(clientOptions.headers)
queryParams = ArrayListMultimap.create(clientOptions.queryParams)
responseValidation = clientOptions.responseValidation
maxRetries = clientOptions.maxRetries
apiKey = clientOptions.apiKey
Expand All @@ -70,47 +64,43 @@ private constructor(

fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper }

fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl }

fun clock(clock: Clock) = apply { this.clock = clock }

fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl }

fun headers(headers: Map<String, Iterable<String>>) = apply {
this.headers.clear()
putAllHeaders(headers)
}

fun putHeader(name: String, value: String) = apply {
this.headers.getOrPut(name) { mutableListOf() }.add(value)
}
fun putHeader(name: String, value: String) = apply { headers.put(name, value) }

fun putHeaders(name: String, values: Iterable<String>) = apply {
this.headers.getOrPut(name) { mutableListOf() }.addAll(values)
headers.putAll(name, values)
}

fun putAllHeaders(headers: Map<String, Iterable<String>>) = apply {
headers.forEach(this::putHeaders)
headers.forEach(::putHeaders)
}

fun removeHeader(name: String) = apply { this.headers.put(name, mutableListOf()) }
fun removeHeader(name: String) = apply { headers.removeAll(name) }

fun queryParams(queryParams: Map<String, Iterable<String>>) = apply {
this.queryParams.clear()
putAllQueryParams(queryParams)
}

fun putQueryParam(name: String, value: String) = apply {
this.queryParams.getOrPut(name) { mutableListOf() }.add(value)
}
fun putQueryParam(name: String, value: String) = apply { queryParams.put(name, value) }

fun putQueryParams(name: String, values: Iterable<String>) = apply {
this.queryParams.getOrPut(name) { mutableListOf() }.addAll(values)
queryParams.putAll(name, values)
}

fun putAllQueryParams(queryParams: Map<String, Iterable<String>>) = apply {
queryParams.forEach(this::putQueryParams)
queryParams.forEach(::putQueryParams)
}

fun removeQueryParam(name: String) = apply { this.queryParams.put(name, mutableListOf()) }
fun removeQueryParam(name: String) = apply { queryParams.removeAll(name) }

fun responseValidation(responseValidation: Boolean) = apply {
this.responseValidation = responseValidation
Expand All @@ -137,8 +127,8 @@ private constructor(
if (!apiKey.isNullOrEmpty()) {
headers.put("Authorization", "Bearer ${apiKey}")
}
this.headers.forEach(headers::replaceValues)
this.queryParams.forEach(queryParams::replaceValues)
this.headers.asMap().forEach(headers::replaceValues)
this.queryParams.asMap().forEach(queryParams::replaceValues)

return ClientOptions(
httpClient!!,
Expand All @@ -149,14 +139,14 @@ private constructor(
.maxRetries(maxRetries)
.build()
),
jsonMapper ?: jsonMapper(),
jsonMapper,
clock,
baseUrl,
apiKey,
headers.toUnmodifiable(),
queryParams.toUnmodifiable(),
headers.toImmutable(),
queryParams.toImmutable(),
responseValidation,
maxRetries,
apiKey,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,28 @@ package com.braintrustdata.api.core
import com.braintrustdata.api.errors.BraintrustInvalidDataException
import com.google.common.collect.ImmutableListMultimap
import com.google.common.collect.ListMultimap
import com.google.common.collect.Multimaps
import java.util.Collections
import java.util.SortedMap

@JvmSynthetic
internal fun <T : Any> T?.getOrThrow(name: String): T =
this ?: throw BraintrustInvalidDataException("`${name}` is not present")

@JvmSynthetic
internal fun <T> List<T>.toUnmodifiable(): List<T> {
if (isEmpty()) {
return Collections.emptyList()
}

return Collections.unmodifiableList(this)
}
internal fun <T> List<T>.toImmutable(): List<T> =
if (isEmpty()) Collections.emptyList() else Collections.unmodifiableList(toList())

@JvmSynthetic
internal fun <K, V> Map<K, V>.toUnmodifiable(): Map<K, V> {
if (isEmpty()) {
return Collections.emptyMap()
}

return Collections.unmodifiableMap(this)
}
internal fun <K, V> Map<K, V>.toImmutable(): Map<K, V> =
if (isEmpty()) Collections.emptyMap() else Collections.unmodifiableMap(toMap())

@JvmSynthetic
internal fun <K, V> ListMultimap<K, V>.toUnmodifiable(): ListMultimap<K, V> {
if (isEmpty()) {
return ImmutableListMultimap.of()
}
internal fun <K : Comparable<K>, V> SortedMap<K, V>.toImmutable(): SortedMap<K, V> =
if (isEmpty()) Collections.emptySortedMap()
else Collections.unmodifiableSortedMap(toSortedMap(comparator()))

return Multimaps.unmodifiableListMultimap(this)
}
@JvmSynthetic
internal fun <K, V> ListMultimap<K, V>.toImmutable(): ListMultimap<K, V> =
ImmutableListMultimap.copyOf(this)

internal interface Enum
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ private constructor(
override fun toString() = values.toString()

companion object {
@JsonCreator @JvmStatic fun of(values: List<JsonValue>) = JsonArray(values.toUnmodifiable())
@JsonCreator @JvmStatic fun of(values: List<JsonValue>) = JsonArray(values.toImmutable())
}
}

Expand All @@ -415,7 +415,7 @@ private constructor(
companion object {
@JsonCreator
@JvmStatic
fun of(values: Map<String, JsonValue>) = JsonObject(values.toUnmodifiable())
fun of(values: Map<String, JsonValue>) = JsonObject(values.toImmutable())
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.braintrustdata.api.core.http

import com.braintrustdata.api.core.toImmutable
import java.util.TreeMap

class Headers
private constructor(
private val map: Map<String, List<String>>,
@get:JvmName("size") val size: Int
) {

fun isEmpty(): Boolean = map.isEmpty()

fun names(): Set<String> = map.keys

fun values(name: String): List<String> = map[name].orEmpty()

fun toBuilder(): Builder = Builder().putAll(map)

companion object {

@JvmStatic fun builder() = Builder()
}

class Builder {

private val map: MutableMap<String, MutableList<String>> =
TreeMap(String.CASE_INSENSITIVE_ORDER)
private var size: Int = 0

fun put(name: String, value: String) = apply {
map.getOrPut(name) { mutableListOf() }.add(value)
size++
}

fun put(name: String, values: Iterable<String>) = apply { values.forEach { put(name, it) } }

fun putAll(headers: Map<String, Iterable<String>>) = apply { headers.forEach(::put) }

fun putAll(headers: Headers) = apply {
headers.names().forEach { put(it, headers.values(it)) }
}

fun remove(name: String) = apply { size -= map.remove(name).orEmpty().size }

fun removeAll(names: Set<String>) = apply { names.forEach(::remove) }

fun clear() = apply {
map.clear()
size = 0
}

fun replace(name: String, value: String) = apply {
remove(name)
put(name, value)
}

fun replace(name: String, values: Iterable<String>) = apply {
remove(name)
put(name, values)
}

fun replaceAll(headers: Map<String, Iterable<String>>) = apply {
headers.forEach(::replace)
}

fun replaceAll(headers: Headers) = apply {
headers.names().forEach { replace(it, headers.values(it)) }
}

fun build() =
Headers(
map.mapValuesTo(TreeMap(String.CASE_INSENSITIVE_ORDER)) { (_, values) ->
values.toImmutable()
}
.toImmutable(),
size
)
}

override fun hashCode(): Int = map.hashCode()

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}

return other is Headers && map == other.map
}

override fun toString(): String = "Headers{map=$map}"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.braintrustdata.api.core.http

import com.braintrustdata.api.core.toUnmodifiable
import com.braintrustdata.api.core.toImmutable
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
import com.google.common.collect.Multimap
Expand Down Expand Up @@ -83,8 +83,8 @@ private constructor(
HttpRequest(
checkNotNull(method) { "`method` is required but was not set" },
url,
pathSegments.toUnmodifiable(),
queryParams.toUnmodifiable(),
pathSegments.toImmutable(),
queryParams.toImmutable(),
headers,
body,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package com.braintrustdata.api.errors

import com.braintrustdata.api.core.JsonValue
import com.braintrustdata.api.core.NoAutoDetect
import com.braintrustdata.api.core.toUnmodifiable
import com.braintrustdata.api.core.toImmutable
import com.fasterxml.jackson.annotation.JsonAnyGetter
import com.fasterxml.jackson.annotation.JsonAnySetter
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
Expand Down Expand Up @@ -62,6 +62,6 @@ constructor(
this.additionalProperties.putAll(additionalProperties)
}

fun build(): BraintrustError = BraintrustError(additionalProperties.toUnmodifiable())
fun build(): BraintrustError = BraintrustError(additionalProperties.toImmutable())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.braintrustdata.api.core.JsonField
import com.braintrustdata.api.core.JsonMissing
import com.braintrustdata.api.core.JsonValue
import com.braintrustdata.api.core.NoAutoDetect
import com.braintrustdata.api.core.toUnmodifiable
import com.braintrustdata.api.core.toImmutable
import com.braintrustdata.api.errors.BraintrustInvalidDataException
import com.fasterxml.jackson.annotation.JsonAnyGetter
import com.fasterxml.jackson.annotation.JsonAnySetter
Expand Down Expand Up @@ -317,7 +317,7 @@ private constructor(
roleId,
_objectOrgId,
created,
additionalProperties.toUnmodifiable(),
additionalProperties.toImmutable(),
)
}

Expand Down
Loading