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

com.finbourne.horizon.extensions.ApiClientBuilder Maven / Gradle / Ivy

There is a newer version: 2.0.463
Show newest version
package com.finbourne.horizon.extensions;

import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Credentials;

import com.finbourne.horizon.ApiClient;
import com.finbourne.horizon.extensions.auth.HttpFinbourneTokenProvider;
import com.finbourne.horizon.extensions.auth.RefreshingTokenProvider;
import com.finbourne.horizon.extensions.auth.FinbourneToken;
import com.finbourne.horizon.extensions.auth.FinbourneTokenException;

/**
* Utility class to build an ApiClient from a set of configuration
*/
public class ApiClientBuilder {

    /**
    * Builds an ApiClient implementation configured against a secrets file. Typically used
    * for communicating with horizon via the APIs
    *
    * ApiClient implementation enables use of REFRESH tokens (see https://support.finbourne.com/using-a-refresh-token)
    * and automatically handles token refreshing on expiry.
    *
    * @param apiConfiguration configuration to connect to horizon API
    * @return
    *
    * @throws FinbourneTokenException on failing to authenticate and retrieve an initial {@link FinbourneToken}
    */
    public ApiClient build(ApiConfiguration apiConfiguration) throws FinbourneTokenException {
        Builder httpBuilder = new Builder();
        httpBuilder.callTimeout(java.time.Duration.ofMillis(apiConfiguration.getTotalTimeoutMs()));
        httpBuilder.connectTimeout(java.time.Duration.ofMillis(apiConfiguration.getConnectTimeoutMs()));
        httpBuilder.readTimeout(java.time.Duration.ofMillis(apiConfiguration.getReadTimeoutMs()));
        httpBuilder.writeTimeout(java.time.Duration.ofMillis(apiConfiguration.getWriteTimeoutMs()));
        return this.build(apiConfiguration, httpBuilder);
    }

    /**
    * @deprecated Use {@link #build(ApiConfiguration)} instead, setting {@link ConfigurationOptions#RateLimitRetries}. 
    * Note that {@link ConfigurationOptions#RateLimitRetries} is the max number of retries whereas {@link #retryMaxAttempts} is the max total number of attempts.
    * {@link ConfigurationOptions#RateLimitRetries} should therefore be set to one less than the {@link #retryMaxAttempts} to keep the same behaviour.
    *
    * Builds an ApiClient implementation configured against a secrets file.
    * Typically used
    * for communicating with horizon via the APIs
    *
    * ApiClient implementation enables use of REFRESH tokens (see
    * https://support.finbourne.com/using-a-refresh-token)
    * and automatically handles token refreshing on expiry.
    *
    * @param apiConfiguration configuration to connect to lusid API
    * @param retryMaxAttempts number of times to try to make request when rate limited
    * @return
    *
    * @throws FinbourneTokenException on failing to authenticate and retrieve an
    *                                 initial {@link FinbourneToken}
    */
    @Deprecated
    public ApiClient build(ApiConfiguration apiConfiguration, int retryMaxAttempts) throws FinbourneTokenException {
        apiConfiguration.setRateLimitRetries(retryMaxAttempts - 1);
        return build(apiConfiguration);
    }

    /**
    * @deprecated Use {@link #build(ApiConfiguration, Builder)} instead, setting {@link ConfigurationOptions#RateLimitRetries}.
    * Note that {@link ConfigurationOptions#RateLimitRetries} is the max number of retries whereas {@link #retryMaxAttempts} is the max total number of attempts.
    * {@link ConfigurationOptions#RateLimitRetries} should therefore be set to one less than the {@link #retryMaxAttempts} to keep the same behaviour.
    * 
    * Builds an ApiClient implementation configured against a secrets file. Typically used
    * for communicating with horizon via the APIs
    *
    * ApiClient implementation enables use of REFRESH tokens (see https://support.finbourne.com/using-a-refresh-token)
    * and automatically handles token refreshing on expiry.
    *
    * @param apiConfiguration configuration to connect to horizon API
    * @param retryMaxAttempts number of times to try to make request when rate limited
    * @param httpClientBuilder {@link Builder} with some configuration already
    *                          set
    * @return
    *
    * @throws FinbourneTokenException on failing to authenticate and retrieve an initial {@link FinbourneToken}
    */
    public ApiClient build(ApiConfiguration apiConfiguration, int retryMaxAttempts, Builder httpClientBuilder) throws FinbourneTokenException {
        apiConfiguration.setRateLimitRetries(retryMaxAttempts - 1);
        return build(apiConfiguration, httpClientBuilder);
    }

    /**
    * Builds an ApiClient implementation configured against a secrets file. Typically used
    * for communicating with horizon via the APIs
    *
    * ApiClient implementation enables use of REFRESH tokens (see https://support.finbourne.com/using-a-refresh-token)
    * and automatically handles token refreshing on expiry.
    *
    * @param apiConfiguration configuration to connect to horizon API
    * @param httpClientBuilder {@link Builder} with some configuration already
    *                          set
    * @return
    *
    * @throws FinbourneTokenException on failing to authenticate and retrieve an initial {@link FinbourneToken}
    */
    public ApiClient build(ApiConfiguration apiConfiguration, Builder httpClientBuilder) throws FinbourneTokenException {
        // http client to use for api and auth calls
        httpClientBuilder = httpClientBuilder.addInterceptor(new RateLimitRetryInterceptor(apiConfiguration.getRateLimitRetries()));

        // use a proxy if given
        if (apiConfiguration.getProxyAddress() != null) {
            InetSocketAddress proxy = InetSocketAddress.createUnresolved(apiConfiguration.getProxyAddress(),
                    apiConfiguration.getProxyPort());

            httpClientBuilder = httpClientBuilder.proxy(new Proxy(Proxy.Type.HTTP, proxy))
                    .proxyAuthenticator((route, response) -> {
                        String credential = Credentials.basic(apiConfiguration.getProxyUsername(),
                                apiConfiguration.getProxyPassword());
                        return response.request().newBuilder()
                                .header("Proxy-Authorization", credential)
                                .build();
                    });
        }
        ApiClient defaultApiClient;
        FinbourneToken finbourneToken;
        if (apiConfiguration.getPersonalAccessToken() != null && apiConfiguration.getApiUrl() != null) {
            // use Personal Access Token
            finbourneToken = new FinbourneToken(apiConfiguration.getPersonalAccessToken(), null, null);

            defaultApiClient = new ApiClient(httpClientBuilder.build());
            defaultApiClient.setAccessToken(finbourneToken.getAccessToken());
        } else {
            // token provider to keep client authenticated with automated token refreshing
            RefreshingTokenProvider refreshingTokenProvider = new RefreshingTokenProvider(
                    new HttpFinbourneTokenProvider(apiConfiguration, httpClientBuilder.build()));
            finbourneToken = refreshingTokenProvider.get();
            // setup api client that managed submissions with the latest token

            httpClientBuilder = httpClientBuilder
                    .addInterceptor(new AuthenticationInterceptor(refreshingTokenProvider));

            defaultApiClient = new ApiClient(httpClientBuilder.build());

        }
        if (finbourneToken.getAccessToken() == null) {
            throw new FinbourneTokenException(
                    "Cannot construct an API client with a null authorisation header. Ensure " +
                            "finbourne token generated is valid");
        }
        if (apiConfiguration.getApplicationName() != null) {
            defaultApiClient.addDefaultHeader("X-LUSID-Application", apiConfiguration.getApplicationName());
        }
        defaultApiClient.setBasePath(apiConfiguration.getApiUrl());
        return defaultApiClient;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy