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

com.sanctionco.thunder.ThunderClientBuilder Maven / Gradle / Ivy

The newest version!
package com.sanctionco.thunder;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;

import okhttp3.OkHttpClient;
import okhttp3.Request;

import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Provides methods to build a new instance of {@link ThunderClient}.
 *
 * @see ThunderClient
 */
public class ThunderClientBuilder {
  private String endpoint;
  private OkHttpClient httpClient;

  /**
   * Constructs a new builder instance that can be configured to build a {@link ThunderClient}.
   */
  public ThunderClientBuilder() {
  }

  /**
   * Sets the endpoint to use when making calls to Thunder.
   *
   * @param endpoint the base URL of the API endpoint to connect to
   * @return this
   */
  public ThunderClientBuilder endpoint(String endpoint) {
    Objects.requireNonNull(endpoint);

    this.endpoint = ensureTrailingSlashExists(endpoint);

    return this;
  }

  /**
   * Sets basic authentication information for this client to use.
   *
   * @param apiUser the basic authentication username to use when connecting to the endpoint
   * @param apiSecret the basic authentication secret to use when connecting to the endpoint
   * @return this
   */
  public ThunderClientBuilder authentication(String apiUser, String apiSecret) {
    Objects.requireNonNull(apiUser);
    Objects.requireNonNull(apiSecret);

    String authHeader = "Basic " + Base64.getEncoder().encodeToString(
        String.format("%s:%s", apiUser, apiSecret).getBytes(StandardCharsets.UTF_8));

    this.httpClient = buildHttpClient(authHeader);

    return this;
  }

  /**
   * Sets OAuth Bearer authentication information for this client to use.
   *
   * @param accessToken the OAuth access token to use when connecting to the endpoint
   * @return this
   */
  public ThunderClientBuilder authentication(String accessToken) {
    Objects.requireNonNull(accessToken);

    String authHeader = "Bearer " + accessToken;

    this.httpClient = buildHttpClient(authHeader);

    return this;
  }

  /**
   * Builds an instance of {@link ThunderClient}.
   *
   * @return the new {@link ThunderClient} instance
   */
  public ThunderClient build() {
    Objects.requireNonNull(endpoint,
        "You must provide an endpoint with the ThunderClientBuilder.endpoint() method"
            + " in order to build a ThunderClient.");
    Objects.requireNonNull(httpClient,
        "You must provide an authentication mechanism with the"
            + " ThunderClientBuilder.authentication() method in order to build a ThunderClient.");

    var retrofit = new Retrofit.Builder()
        .baseUrl(endpoint)
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(JacksonConverterFactory.create())
        .client(httpClient)
        .build();

    return retrofit.create(ThunderClient.class);
  }

  /**
   * Creates a new HttpClient that injects basic authorization into incoming requests.
   *
   * @param authToken the value to set as the Authorization header for all requests
   * @return the built OkHttpClient
   */
  private OkHttpClient buildHttpClient(String authToken) {
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor((chain) -> {
      Request original = chain.request();

      // Add the authorization header
      Request request = original.newBuilder()
          .header("Authorization", authToken)
          .method(original.method(), original.body())
          .build();

      return chain.proceed(request);
    });

    return httpClient.build();
  }

  /**
   * Ensures that the given URL ends with a trailing slash ('/').
   *
   * @param url the url to verify contains a trailing slash
   * @return the original url with a trailing slash added if necessary
   */
  static String ensureTrailingSlashExists(String url) {
    return url.endsWith("/")
        ? url
        : url + "/";
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy