This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"securities":{ | |
"security":[ | |
{ | |
"symbol":"PHYS", | |
"exchange":"Q", | |
"type":"stock", | |
"description":"Sprott Physical Gold Trust ETV" | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Indicates an endpoint wraps a response in a JSON Object. | |
* When deserializing the response we should only return | |
* what's inside the outer most object. | |
*/ | |
@Retention(RUNTIME) | |
@JsonQualifier | |
@Target(FUNCTION, CLASS) | |
internal annotation class Enveloped |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Complements @Enveloped by performing custom deserialization | |
* for a response that is wrapped in a JSON Object. | |
*/ | |
internal class EnvelopeFactory : JsonAdapter.Factory { | |
companion object { | |
val INSTANCE = EnvelopeFactory() | |
} | |
override fun create( |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface TradierApi { | |
@Enveloped | |
@GET("markets/lookup") | |
fun lookup(@Query("q") symbol: String): Single<Securities> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Provides | |
fun retrofit(okHttpClient: Lazy<OkHttpClient>) = Retrofit.Builder() | |
.baseUrl("https://sandbox.tradier.com/v1/") | |
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io())) | |
.callFactory { okHttpClient.get().newCall(it) } | |
.build() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Module | |
abstract class AppModule { | |
@Module | |
companion object { | |
private const val HTTP_RESPONSE_CACHE = (10 * 1024 * 1024).toLong() | |
@AppScope @Provides @JvmStatic | |
fun httpClient(cache: Cache): OkHttpClient { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Authenticator that attempts to refresh the client's access token. | |
* In the event that a refresh fails and a new token can't be issued an error | |
* is delivered to the caller. This authenticator blocks all requests while a token | |
* refresh is being performed. In-flight requests that fail with a 401 are | |
* automatically retried. | |
*/ | |
class AccessTokenAuthenticator( | |
private val tokenProvider: AccessTokenProvider | |
) : Authenticator { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Provides an access token for request authorization. | |
*/ | |
interface AccessTokenProvider { | |
/** | |
* Returns an access token. In the event that you don't have a token return null. | |
*/ | |
fun token(): String? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AccessTokenInterceptor( | |
private val tokenProvider: AccessTokenProvider | |
) : Interceptor { | |
override fun intercept(chain: Interceptor.Chain): Response { | |
val token = tokenProvider.token() | |
return if (token == null) { | |
chain.proceed(chain.request()) | |
} else { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
authApi.getTokens() | |
.subscribe({ response: Response<AccessToken> -> | |
when { | |
response.isSuccessful && response.body() != null -> { | |
// Case 1: Success. We got a response with a body. | |
} | |
response.errorBody() != null -> { | |
// Case 2: Failure. We got an error from the backend, deserialize it. | |
val error = moshi.adapter(Error::class.java).fromJson(errorBody.source()) | |
} |