com.lithic.api.services.Handlers.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lithic-kotlin-core Show documentation
Show all versions of lithic-kotlin-core Show documentation
The Lithic Developer API is designed to provide a predictable programmatic
interface for accessing your Lithic account through an API and transaction
webhooks. Note that your API key is a secret and should be treated as such.
Don't share it with anyone, including us. We will never ask you for it.
@file:JvmName("Handlers")
package com.lithic.api.services
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
import com.google.common.collect.ListMultimap
import com.lithic.api.core.http.BinaryResponseContent
import com.lithic.api.core.http.HttpResponse
import com.lithic.api.core.http.HttpResponse.Handler
import com.lithic.api.errors.BadRequestException
import com.lithic.api.errors.InternalServerException
import com.lithic.api.errors.LithicError
import com.lithic.api.errors.LithicException
import com.lithic.api.errors.NotFoundException
import com.lithic.api.errors.PermissionDeniedException
import com.lithic.api.errors.RateLimitException
import com.lithic.api.errors.UnauthorizedException
import com.lithic.api.errors.UnexpectedStatusCodeException
import com.lithic.api.errors.UnprocessableEntityException
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.io.OutputStream
internal fun emptyHandler(): Handler = EmptyHandler
private object EmptyHandler : Handler {
override fun handle(response: HttpResponse): Void? = null
}
internal fun stringHandler(): Handler = StringHandler
internal fun binaryHandler(): Handler = BinaryHandler
private object StringHandler : Handler {
override fun handle(response: HttpResponse): String {
return response.body().readBytes().toString(Charsets.UTF_8)
}
}
private object BinaryHandler : Handler {
override fun handle(response: HttpResponse): BinaryResponseContent {
return object : BinaryResponseContent {
override fun contentType(): String? =
response.headers().get("Content-Type").firstOrNull()
override fun body(): InputStream = response.body()
override fun close() = response.close()
override fun writeTo(outputStream: OutputStream) {
response.body().copyTo(outputStream)
}
}
}
}
internal inline fun jsonHandler(jsonMapper: JsonMapper): Handler {
return object : Handler {
override fun handle(response: HttpResponse): T {
try {
return jsonMapper.readValue(response.body(), jacksonTypeRef())
} catch (e: Exception) {
throw LithicException("Error reading response", e)
}
}
}
}
internal fun errorHandler(jsonMapper: JsonMapper): Handler {
val handler = jsonHandler(jsonMapper)
return object : Handler {
override fun handle(response: HttpResponse): LithicError {
try {
return handler.handle(response)
} catch (e: Exception) {
return LithicError.builder().build()
}
}
}
}
internal fun Handler.withErrorHandler(errorHandler: Handler): Handler {
return object : Handler {
override fun handle(response: HttpResponse): T {
when (val statusCode = response.statusCode()) {
in 200..299 -> {
return [email protected](response)
}
400 -> {
val buffered = response.buffered()
throw BadRequestException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
401 -> {
val buffered = response.buffered()
throw UnauthorizedException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
403 -> {
val buffered = response.buffered()
throw PermissionDeniedException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
404 -> {
val buffered = response.buffered()
throw NotFoundException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
422 -> {
val buffered = response.buffered()
throw UnprocessableEntityException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
429 -> {
val buffered = response.buffered()
throw RateLimitException(
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
in 500..599 -> {
val buffered = response.buffered()
throw InternalServerException(
statusCode,
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
else -> {
val buffered = response.buffered()
throw UnexpectedStatusCodeException(
statusCode,
buffered.headers(),
StringHandler.handle(buffered),
errorHandler.handle(buffered),
)
}
}
}
}
}
private fun HttpResponse.buffered(): HttpResponse {
val body = body().readBytes()
return object : HttpResponse {
override fun statusCode(): Int {
return [email protected]()
}
override fun headers(): ListMultimap {
return [email protected]()
}
override fun body(): InputStream {
return ByteArrayInputStream(body)
}
override fun close() {
[email protected]()
}
}
}