
main.java.com.cloudant.client.api.ClientBuilder Maven / Gradle / Ivy
package com.cloudant.client.api;
import com.cloudant.client.api.model.Index;
import com.cloudant.client.api.model.Permissions;
import com.cloudant.client.api.model.Shard;
import com.cloudant.client.api.views.Key;
import com.cloudant.client.internal.util.IndexDeserializer;
import com.cloudant.client.internal.util.SecurityDeserializer;
import com.cloudant.client.internal.util.ShardDeserializer;
import com.cloudant.client.org.lightcouch.CouchDbException;
import com.cloudant.client.org.lightcouch.CouchDbProperties;
import com.cloudant.http.HttpConnectionInterceptor;
import com.cloudant.http.HttpConnectionRequestInterceptor;
import com.cloudant.http.HttpConnectionResponseInterceptor;
import com.cloudant.http.interceptors.CookieInterceptor;
import com.cloudant.http.interceptors.ProxyAuthInterceptor;
import com.cloudant.http.interceptors.SSLCustomizerInterceptor;
import com.cloudant.http.interceptors.TimeoutCustomizationInterceptor;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLSocketFactory;
/**
* This class builds new {@link CloudantClient} instances.
*
* Create a new CloudantClient instance for a Cloudant account
*
* {@code
* CloudantClient client = ClientBuilder.account("yourCloudantAccount")
* .username("yourUsername")
* .password("yourPassword")
* .build();
* }
*
*
* Create a new CloudantClient instance for a Cloudant Local
*
* {@code
* CloudantClient client = ClientBuilder.url(new URL("https://yourCloudantLocalAddress.example"))
* .username("yourUsername")
* .password("yourPassword")
* .build();
* }
*
*
* Examples creating instances with additional options
* Configure a proxy server
*
* {@code
* CloudantClient client = ClientBuilder.account("yourCloudantAccount")
* .username("yourUsername")
* .password("yourPassword")
* .proxyURL(new URL("https://yourProxyServerAddress.example"))
* .proxyUser(yourProxyUser)
* .proxyPassword(yourProxyPass)
* .build();
* }
*
*
* Client with a custom SSL socket factory
*
* {@code
* CloudantClient client = ClientBuilder.account("yourCloudantAccount")
* .username("yourUsername")
* .password("yourPassword")
* .customSSLSocketFactory(...)
* .build();
* }
*
*
* Client with custom connection and read timeouts
*
* {@code
* CloudantClient client = ClientBuilder.account("yourCloudantAccount")
* .username("yourUsername")
* .password("yourPassword")
* .connectTimeout(1, TimeUnit.MINUTES)
* .readTimeout(1, TimeUnit.MINUTES)
* .build();
* }
*
*
* @since 2.0.0
*/
public class ClientBuilder {
/**
* Default max of 6 connections
**/
public static final int DEFAULT_MAX_CONNECTIONS = 6;
/**
* Connection timeout defaults to 5 minutes
**/
public static final long DEFAULT_CONNECTION_TIMEOUT = 5l;
/**
* Read timeout defaults to 5 minutes
**/
public static final long DEFAULT_READ_TIMEOUT = 5l;
private List requestInterceptors = new ArrayList
();
private List responseInterceptors = new ArrayList
();
private String password;
private String username;
private URL url;
private GsonBuilder gsonBuilder;
/**
* Defaults to {@link #DEFAULT_MAX_CONNECTIONS}
**/
private int maxConnections = DEFAULT_MAX_CONNECTIONS;
private URL proxyURL;
private String proxyUser;
private String proxyPassword;
private boolean isSSLAuthenticationDisabled;
private SSLSocketFactory authenticatedModeSSLSocketFactory;
private long connectTimeout = DEFAULT_CONNECTION_TIMEOUT;
private TimeUnit connectTimeoutUnit = TimeUnit.MINUTES;
private long readTimeout = DEFAULT_READ_TIMEOUT;
private TimeUnit readTimeoutUnit = TimeUnit.MINUTES;
/**
* Constructs a new ClientBuilder for building a CloudantClient instance to connect to the
* Cloudant server with the specified account.
*
* @param account the Cloudant account name to connect to e.g. "example" is the account name
* for the "example.cloudant.com" endpoint
* @return a new ClientBuilder for the account
* @throws IllegalArgumentException if the specified account name forms an invalid endpoint URL
*/
public static ClientBuilder account(String account) {
try {
URL url = new URL(String.format("https://%s.cloudant.com", account));
return ClientBuilder.url(url);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Could not generate url from account name.", e);
}
}
/**
* Constructs a new ClientBuilder for building a CloudantClient instance to connect to the
* Cloudant server with the specified URL.
*
* @param url server URL e.g. "https://yourCloudantLocalAddress.example"
* @return a new ClientBuilder for the account
*/
public static ClientBuilder url(URL url) {
return new ClientBuilder(url);
}
private ClientBuilder(URL url) {
String urlProtocol = url.getProtocol();
String urlHost = url.getHost();
//Check if port exists
int urlPort = url.getPort();
if (urlPort < 0) {
urlPort = url.getDefaultPort();
}
if (url.getUserInfo() != null) {
//Get username and password and replace credential variables
this.username = url.getUserInfo().substring(0, url
.getUserInfo()
.indexOf(":"));
this.password = url.getUserInfo().substring(url
.getUserInfo()
.indexOf(":") + 1);
}
try {
//Remove user credentials from url
this.url = new URL(urlProtocol
+ "://"
+ urlHost
+ ":"
+ urlPort);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* Build the {@link CloudantClient} instance based on the endpoint used to construct this
* client builder and the options that have been set on it before calling this method.
*
* @return the {@link CloudantClient} instance for the specified end point and options
*/
public CloudantClient build() {
//Build properties and couchdb client
CouchDbProperties props = new CouchDbProperties(url);
//Create cookie interceptor
if (this.username != null && this.password != null) {
//make interceptor if both username and password are not null
//Create cookie interceptor and set in HttpConnection interceptors
CookieInterceptor cookieInterceptor = new CookieInterceptor(username, password);
props.addRequestInterceptors(cookieInterceptor);
props.addResponseInterceptors(cookieInterceptor);
} else {
//If username or password is null, throw an exception
if (username != null || password != null) {
//Username and password both have to contain values
throw new CouchDbException("Either a username and password must be provided, or " +
"both values must be null. Please check the credentials and try again.");
}
}
//If setter methods for read and connection timeout are not called, default values are used.
props.addRequestInterceptors(new TimeoutCustomizationInterceptor(connectTimeout,
connectTimeoutUnit, readTimeout, readTimeoutUnit));
//Set connect options
props.setMaxConnections(maxConnections);
props.setProxyURL(proxyURL);
if (proxyUser != null) {
//if there was proxy auth information create an interceptor for it
props.addRequestInterceptors(new ProxyAuthInterceptor(proxyUser,
proxyPassword));
}
if (isSSLAuthenticationDisabled) {
props.addRequestInterceptors(SSLCustomizerInterceptor
.SSL_AUTH_DISABLED_INTERCEPTOR);
}
if (authenticatedModeSSLSocketFactory != null) {
props.addRequestInterceptors(new SSLCustomizerInterceptor(
authenticatedModeSSLSocketFactory
));
}
//Set http connection interceptors
if (requestInterceptors != null) {
for (HttpConnectionRequestInterceptor requestInterceptor : requestInterceptors) {
props.addRequestInterceptors(requestInterceptor);
}
}
if (responseInterceptors != null) {
for (HttpConnectionResponseInterceptor responseInterceptor : responseInterceptors) {
props.addResponseInterceptors(responseInterceptor);
}
}
//if no gsonBuilder has been provided, create a new one
if (gsonBuilder == null) {
gsonBuilder = new GsonBuilder();
}
//always register additional TypeAdapaters for derserializing some Cloudant specific
// types before constructing the CloudantClient
gsonBuilder.registerTypeAdapter(new TypeToken>() {
}.getType(), new ShardDeserializer())
.registerTypeAdapter(new TypeToken>() {
}.getType(), new IndexDeserializer())
.registerTypeAdapter(new TypeToken
© 2015 - 2025 Weber Informatics LLC | Privacy Policy