app.cybrid.cybrid_api_id.client.infrastructure.ApiClient.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cybrid-api-id-kotlin Show documentation
Show all versions of cybrid-api-id-kotlin Show documentation
Auto-generated Cybrid SDK for Kotlin
package app.cybrid.cybrid_api_id.client.infrastructure
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder
import app.cybrid.cybrid_api_id.client.auth.OAuth
import app.cybrid.cybrid_api_id.client.auth.OAuth.AccessTokenListener
import app.cybrid.cybrid_api_id.client.auth.OAuthFlow
import app.cybrid.cybrid_api_id.client.auth.HttpBearerAuth
import okhttp3.Call
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Converter
import retrofit2.converter.scalars.ScalarsConverterFactory
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import retrofit2.converter.gson.GsonConverterFactory
class ApiClient(
private var baseUrl: String = defaultBasePath,
private val okHttpClientBuilder: OkHttpClient.Builder? = null,
private val serializerBuilder: GsonBuilder = Serializer.gsonBuilder,
private val callFactory : Call.Factory? = null,
private val converterFactory: Converter.Factory? = null,
) {
private val apiAuthorizations = mutableMapOf()
var logger: ((String) -> Unit)? = null
private val retrofitBuilder: Retrofit.Builder by lazy {
Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(serializerBuilder.create()))
.apply {
if (converterFactory != null) {
addConverterFactory(converterFactory)
}
}
}
private val clientBuilder: OkHttpClient.Builder by lazy {
okHttpClientBuilder ?: defaultClientBuilder
}
private val defaultClientBuilder: OkHttpClient.Builder by lazy {
OkHttpClient()
.newBuilder()
.addInterceptor(HttpLoggingInterceptor { message -> logger?.invoke(message) }
.apply { level = HttpLoggingInterceptor.Level.BODY }
)
}
init {
normalizeBaseUrl()
}
constructor(
baseUrl: String = defaultBasePath,
okHttpClientBuilder: OkHttpClient.Builder? = null,
serializerBuilder: GsonBuilder = Serializer.gsonBuilder,
authNames: Array
) : this(baseUrl, okHttpClientBuilder, serializerBuilder) {
authNames.forEach { authName ->
val auth = when (authName) {
"BearerAuth" -> HttpBearerAuth("bearer")"oauth2" -> OAuth(OAuthFlow.application, "", "https://id.production.cybrid.app/oauth/token", "organizations:write, organizations:read, organization_applications:execute, banks:write, banks:read, bank_applications:execute, users:read, users:execute, customers:write, customers:read, subscriptions:read, subscriptions:write, subscriptions:execute, subscription_events:read, subscription_events:execute")
else -> throw RuntimeException("auth name $authName not found in available auth names")
}
addAuthorization(authName, auth)
}
}
constructor(
baseUrl: String = defaultBasePath,
okHttpClientBuilder: OkHttpClient.Builder? = null,
serializerBuilder: GsonBuilder = Serializer.gsonBuilder,
authName: String,
bearerToken: String
) : this(baseUrl, okHttpClientBuilder, serializerBuilder, arrayOf(authName)) {
setBearerToken(bearerToken)
}
constructor(
baseUrl: String = defaultBasePath,
okHttpClientBuilder: OkHttpClient.Builder? = null,
serializerBuilder: GsonBuilder = Serializer.gsonBuilder,
authName: String,
clientId: String,
secret: String,
username: String,
password: String
) : this(baseUrl, okHttpClientBuilder, serializerBuilder, arrayOf(authName)) {
getTokenEndPoint()
?.setClientId(clientId)
?.setClientSecret(secret)
?.setUsername(username)
?.setPassword(password)
}
fun setCredentials(username: String, password: String): ApiClient {
apiAuthorizations.values.runOnFirst {
tokenRequestBuilder.setUsername(username).setPassword(password)
}
return this
}
fun setBearerToken(bearerToken: String): ApiClient {
apiAuthorizations.values.runOnFirst {
this.bearerToken = bearerToken
}
return this
}
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Token request builder
*/
fun getTokenEndPoint(): TokenRequestBuilder? {
var result: TokenRequestBuilder? = null
apiAuthorizations.values.runOnFirst {
result = tokenRequestBuilder
}
return result
}
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Authentication request builder
*/
fun getAuthorizationEndPoint(): AuthenticationRequestBuilder? {
var result: AuthenticationRequestBuilder? = null
apiAuthorizations.values.runOnFirst {
result = authenticationRequestBuilder
}
return result
}
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken Access token
* @return ApiClient
*/
fun setAccessToken(accessToken: String): ApiClient {
apiAuthorizations.values.runOnFirst {
setAccessToken(accessToken)
}
return this
}
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId Client ID
* @param clientSecret Client secret
* @param redirectURI Redirect URI
* @return ApiClient
*/
fun configureAuthorizationFlow(clientId: String, clientSecret: String, redirectURI: String): ApiClient {
apiAuthorizations.values.runOnFirst {
tokenRequestBuilder
.setClientId(clientId)
.setClientSecret(clientSecret)
.setRedirectURI(redirectURI)
authenticationRequestBuilder
?.setClientId(clientId)
?.setRedirectURI(redirectURI)
}
return this
}
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener Access token listener
* @return ApiClient
*/
fun registerAccessTokenListener(accessTokenListener: AccessTokenListener): ApiClient {
apiAuthorizations.values.runOnFirst {
registerAccessTokenListener(accessTokenListener)
}
return this
}
/**
* Adds an authorization to be used by the client
* @param authName Authentication name
* @param authorization Authorization interceptor
* @return ApiClient
*/
fun addAuthorization(authName: String, authorization: Interceptor): ApiClient {
if (apiAuthorizations.containsKey(authName)) {
throw RuntimeException("auth name $authName already in api authorizations")
}
apiAuthorizations[authName] = authorization
clientBuilder.addInterceptor(authorization)
return this
}
fun setLogger(logger: (String) -> Unit): ApiClient {
this.logger = logger
return this
}
fun createService(serviceClass: Class): S {
val usedCallFactory = this.callFactory ?: clientBuilder.build()
return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass)
}
private fun normalizeBaseUrl() {
if (!baseUrl.endsWith("/")) {
baseUrl += "/"
}
}
private inline fun Iterable.runOnFirst(callback: U.() -> Unit) {
for (element in this) {
if (element is U) {
callback.invoke(element)
break
}
}
}
companion object {
@JvmStatic
protected val baseUrlKey = "app.cybrid.cybrid_api_id.client.baseUrl"
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(baseUrlKey, "https://id.sandbox.cybrid.app")
}
}
}