Skip navigation links

cloudant-client 2.20.0 API

DEPRECATED: This library is now deprecated, the replacement is cloudant-java-sdk.

See: Description

Packages 
Package Description
com.cloudant.client.api
This package provides the objects for interacting with Cloudant
com.cloudant.client.api.model
This package provides additional objects for interacting with Cloudant
com.cloudant.client.api.query
This package provides access to the query API.
com.cloudant.client.api.scheduler  
com.cloudant.client.api.views
This package provides access to the view API.
com.cloudant.client.org.lightcouch  

DEPRECATED: This library is now deprecated, the replacement is cloudant-java-sdk.

Contents

  1. Compatibility
  2. Initialization
    1. Cloudant service example
    2. Cloudant Local example
  3. Authentication
    1. Cookie authentication
    2. IAM authentication
    3. Custom authentication
  4. Capabilities
    1. Server Operations
    2. Database Operations
    3. Document Operations
      1. Single document CRUD
      2. Bulk document CRU
      3. Document revisions
    4. Attachments
      1. Standalone Attachments
      2. Inline Attachments
    5. Design Documents
    6. Using Views
    7. Cloudant Query
    8. Cloudant Search
  5. Partitioned Databases
  6. Advanced Configuration
    1. Connection options
    2. Resource sharing
      1. Thread safety
      2. Connection pooling
        1. Default pooling
        2. With OkHttp
    3. J2EE
    4. Logging
    5. Replays
    6. Proxies
  7. Project

Compatibility

This library can be used with the following databases

Note that some features are Cloudant specific.

The library is compiled with Java 1.6 compatibility, but it is recommended to run with the latest available Java version.

Initialization

Use the ClientBuilder class to build a CloudantClient instance. The CloudantClient class is the starting point for interacting with Cloudant from Java.

Cloudant service example

When using the managed service at cloudant.com, initialize your Cloudant connection by using ClientBuilder.account(String) supplying the account to connect to. Set additional options for the API key or username and passphrase.

    
    CloudantClient client = ClientBuilder.account("yourCloudantAccount")
            .username("yourAPIKey")
            .password("yourAPIKeyPassphrase")
            .build();
    

Cloudant Local example

When using Cloudant Local, initialize your Cloudant connection by using ClientBuilder.url(URL) supplying the URL of the Cloudant Local. Again set additional options for the user name or API key and passphase.

    
    CloudantClient client = ClientBuilder.url(new URL("https://192.0.2.0"))
            .username("yourAPIKey")
            .password("yourAPIKeyPassphrase")
            .build();
    

Authentication

Using the ClientBuilder.username(String) and ClientBuilder.password(String) options uses cookie authentication for the CloudantClient connection. The supplied credentials are used to request a session with the server and the session is renewed automatically if the cookie expires. If the credentials become invalid then a new instance of a CloudantClient needs to be created.

Note that if your database is configured with require_valid_user=true the _session request to obtain a cookie will fail unless it is itself authenticated. This authentication can be added through the use of an additional interceptor such as a com.cloudant.http.interceptors.BasicAuthInterceptor. See also custom authentication.

IAM authentication

IBM Cloud Identity & Access Management enables you to securely authenticate users and control access to all cloud resources.

See IBM Cloud Identity and Access Management for more information.

The production IAM token service at https://iam.cloud.ibm.com/identity/token is used by default. You can set a com.cloudant.client.iamserver system property to override this.

An example using IAM Authentication is shown in the javadoc for ClientBuilder.iamApiKey(String iamApiKey).

Custom authentication

If cookie authentication is not desired then it is possible to build the CloudantClient without credentials and use a HttpConnectionInterceptor to customize the HTTP request with the desired authentication mechanism.

An example using Basic Authentication is shown in the javadoc for ClientBuilder.interceptors(HttpConnectionInterceptor[]).

Capabilities

Server Operations

CloudantClient encapsulates the connection to the server and provides access to server operations.

Database Operations

CloudantClient.database(String, boolean) returns a Database object that provides access to database operations.

Document Operations

Single document CRUD

CRUD operations for documents in a database are achieved via the Database object.

Bulk document CRU

Database also provides a bulk documents API for fetching or modifying multiple documents in a single request.

Document revisions

This library does not modify the Java objects passed to the Database.save(Object), Database.post(Object), Database.update(Object), or Database.bulk(List) methods. As such once the server write completes the Java object(s) will be out of sync with the database server regarding the document revision. For any of these methods the new document revision should be obtained from the server's Response as shown here.

    
    Foo foo = new Foo();
    Response response = db.save(foo);
    foo.setRevision(response.getRevision());
    

Note that storing the revision from a server response means the object has the latest server revision only at the point in time the write was completed. The server document may be subsequently updated from another source at which point the revision in the object will no longer be the most recent. The newest revision can be retrieved, for example, by calling Database.find(Class, String).

Documents retrieved from the server, for example using the Database.find(Class, String) method, are deserialized into objects that will contain the revision as long as the type being deserialized into has a _rev field or an appropriate custom serializer to ensure that the _rev is mapped to another field.

Using the correct revision is required for the Database.update(Object) and Database.remove(Object) methods, as well as when performing bulk updates or deletions via the Database.bulk(List) method. If the latest revision is not used then the server will reject the change and send a 409 conflict response. This results in either a DocumentConflictException being thrown or in the case of the Database.bulk(List) method the corresponding response object in the returned list will return the "conflict" error string when Response.getError() is called. In this situation retrieve the latest revision and update the object to be written accordingly before retrying.

Attachments

See the Cloudant documentation for more information about attachments.

Standalone Attachments

Standalone attachment data is provided as an InputStream. The attachment can be created and either referenced from an existing document or a new document.

Inline Attachments

Inline attachments enclose the attachment data, Base64 encoded, within the document body. The Attachment class represents an inline attachment. Classes that extend Document automatically inherit support for inline attachments.

Example usage of inline attachment, using Apache Commons Codec for Base64 encoding:

    
        Attachment attachment = new Attachment();
        attachment.setData(Base64.encodeBase64String("attachment test string".getBytes()));
        attachment.setContentType("text/plain");
        Foo foo = new Foo(); // Foo extends Document
        foo.addAttachment("attachment.txt", attachment);
        db.save(foo);
    

Note that attachment data is not included by default when reading documents. To retrieve inline attachment data use Params.attachments(). See Database.find(java.lang.Class, java.lang.String, com.cloudant.client.api.model.Params) for an example.

Design Documents

Design documents are used to define server side operations, including querying the database using map-reduce views, Cloudant Search, and Cloudant Query. The results can be retrieved by the client. It is recommend to read the Cloudant design document documentation before working with design documents to gain an understanding of the available parameters and functions.

The DesignDocument class encapsulates a design document in a Java object.

See DesignDocumentManager.get(java.lang.String, java.lang.String) for an example of retrieving a design document from the sever.

Example of creating a view (map-reduce index) using Map to generate the JSON for the design document

    
    // Uploads the design document with view index:
    // {
    //   "_id": "_design/name",
    //   "views": {
    //     "view1": {
    //       "map":"function(doc){emit(doc.field, 1)}",
    //       "reduce": "function(key, value, rereduce){return sum(values)}"
    //     }
    //   }
    // }

    Map<String, Object> view1 = new HashMap<>();
    view1.put("map", "function(doc){emit(doc.field, 1)}");
    view1.put("reduce", "function(key, value, rereduce){return sum(values)}");

    Map<String, Object> views = new HashMap<>();
    views.put("view1", view1);

    Map<String, Object> view_ddoc = new HashMap<>();
    view_ddoc.put("_id", "_design/name");
    view_ddoc.put("views", views);

    db.save(view_ddoc);
    

Using Views

For background information about views please refer to the Cloudant views documentation . Refer to the com.cloudant.client.api.views package for information about and examples of using this library to query a view.

Cloudant Query

This feature interfaces with Cloudant's query functionality. See the Cloudant Query documentation for details.

This feature interfaces with Cloudant's full text search functionality. See the Cloudant Search documentation for details. Searches are based on index functions in design documents.

To create a search index, upload a design document containing the index:

    
    // Uploads the search index:
    // {
    //   "_id": "_design/views101",
    //   "indexes": {
    //     "animals": {
    //       "index": "function(doc){ index(\"default\", doc._id); }"
    //     }
    //   }
    // }

    Map<String, Object> animals = new HashMap<>();
    animals.put("index", "function(doc){ index(\"default\", doc._id); }");

    Map<String, Object> indexes = new HashMap<>();
    indexes.put("animals", animals);

    Map<String, Object> ddoc = new HashMap<>();
    ddoc.put("_id", "_design/searchindex");
    ddoc.put("indexes", indexes);

    db.save(ddoc);
    

To query this index, use an instance of Search by calling Database.search(java.lang.String).

Partitioned Databases

Partitioned databases introduce the ability for a user to create logical groups of documents called partitions by providing a partition key with each document. A partitioned database offers significant performance and cost advantages but requires you to specify a logical partitioning of your data. IBM Cloudant strongly recommends using partitioned database where the data model allows for logical partitioning of documents.

Creating a new partitioned database (see CloudantClient.createPartitionedDB(String)):

    
    CloudantClient client = ClientBuilder.account("example")
                                         .username("exampleUser")
                                         .password("examplePassword")
                                         .build();

    client.createPartitionedDB("myPartitionedDb");
    

A partitioned database offers both partitioned and global querying. Partitioned querying takes advantage of the data layout within the database cluster to deliver improved and more scalable query performance. In addition, partition queries are often cheaper than global queries.

Executing a partition view query (see SettableViewParameters.Common.partition(String):

    
    Database db = client.database("myPartitionedDb", false);

    ViewRequest<String, String> viewRequest = db.getViewRequestBuilder(ddocId, "myView")
                                                .newRequest(Key.Type.STRING, String.class)
                                                .partition("partitionKey-123456")
                                                .build();
    

See Database.query(String, String, Class) and Database.search(String, String) for executing partitioned IBM Cloudant Query and Search queries, respectively.

For more information see the IBM Cloud Docs.

Advanced Configuration

Connection options

The ClientBuilder provides access to additional advanced configuration options for the server connection. For example customized SSL, proxies and timeouts.

Custom GSON serialization

Internally the Gson library is used to serialize/deserialize JSON to/from Java objects. You can supply your own GsonBuilder instance to customize configuration, for example registering custom de-serializers.

Example setting the date/time format Gson uses:

    
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    CloudantClient client = ClientBuilder.account("example").username("user").password("password)
            .gsonBuilder(builder).build();
    

Resource sharing

Thread safety

CloudantClient objects are thread-safe. All methods can be called from any thread, meaning CloudantClient objects can and should be shared across threads. The Database object is thread-safe and a single Database object may be shared across threads.

Connection pooling

Connection pooling behaviour differs depending on whether the optional OkHttp dependency is included. Note that idle connections within the pool may be terminated by the server, so will not remain open indefinitely meaning that this will not completely remove the overhead of creating new connections.

Default pooling

By default the underlying HttpURLConnection will use the JVM wide connection pool configuration (via the http.maxConnections property). Under these circumstances the pool is shared between all applications in the VM and between all CloudantClient instances.

With OkHttp

When the OkHttp dependency is included then connection pools are managed per CloudantClient instance. The default size of the connection pool is 6. Use ClientBuilder.maxConnections(int) to configure the maximum connections in the pool.

J2EE

This library can be used in J2EE environments, but currently does not implement any J2EE standards or provide wrappers for them. As such there is no built-in support for JCA connection management or JNDI lookups of CloudantClient instances.

To get JNDI support would require a javax.naming.spi.ObjectFactory implementation and configuration of your JNDI provider to register this factory and reference this library.

Logging

This library uses the java.util.logging package. Classes that log will register a Logger under their fully qualified class name. By default java-cloudant does not apply any logging configuration so the system defaults will be used.

There are two ways to configure java.util.logging. It can be configured via a properties file or programmatically. These examples show configuration for writing to the console for FINE level and above for all com.cloudant* classes. The JVM documentation contains more information about java.util.logging and many other logging libraries are also able to integrate with it. Note that java.util.logging uses logging levels for both loggers and handlers and that both levels need to be set appropriately.

  1. Configuring using a properties file (see also this heavily commented example logging.properties file).

                
                # "handlers" specifies a comma separated list of log Handler
                # classes. For this example it will use only the Console Handler
                # however there a other handlers such as FileHandler
                # see http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html
                # for a list of handlers provided by the JDK.
                handlers=java.util.logging.ConsoleHandler
    
                # Limit the messages that are printed on the console to FINE and above.
                # Full list of levels http://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html
                java.util.logging.ConsoleHandler.level=FINE
    
                # Set the formatter for this handler, there are several default formatter classes
                # available, or you can create your own custom formatter.
                java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
    
                # Set com.cloudant classes to log at level FINE
                com.cloudant.level=FINE
                
            
    The properties file must be loaded using either:
    1. via the java.util.logging.config.file system property (e.g. using a command line argument like -Djava.util.logging.config.file=/path/to/logging/config when running the application).
    2. programmatically via the LogManager.
                              
                              LogManager manager = LogManager.getLogManager();
                              manager.readConfiguration(new FileInputStream("path/to/logging/config"));
                              
                          
  2. Configuring the log manager programmatically
                
                // Create a handler in this case a ConsoleHandler
                Handler consoleHandler = new ConsoleHandler();
                // Set the console handler to print FINE level and above
                consoleHandler.setLevel(Level.FINE);
    
                // Get the target logger, in this case "com.cloudant" domain logger
                Logger logger = Logger.getLogger("com.cloudant");
                // Add the handler to the logger
                logger.addHandler(consoleHandler);
    
                // Set the logger to log messages with FINE level and above
                logger.setLevel(Level.FINE);
                
            

Enabling logging for com.cloudant.http classes will provide debug information about HTTP requests and responses. FINE logging will include request and response URLs and status codes. FINER level logging will include request and response HTTP headers. Note that this logging may include sensitive information such as encoded credentials in HTTP headers.

Whilst com.cloudant.http logging should meet most HTTP logging needs it may on occasion be useful to also log from the underlying HTTP implementation. The name of the logger for this will vary depending on the JVM and HTTP provider in use. It is possible to use the property .level=ALL to set the default log level to ALL to catch log messages from some JVM HttpURLConnection implementations. The optional okhttp dependency does not use java.util.logging and at this time it is not possible to enable any additional logging for that provider.

Replays

The library can make use of optionally added interceptors to replay failed requests.

For example in the case of a 429 Too Many Requests response a Replay429Interceptor can intercept the 429 response and replay the request after a delay. If the number of replays is exceeded before a successful response then the expected TooManyRequestsException is thrown as would be the case if no interceptor was configured.

Proxies

This table provides a summary of the proxy configuration options.

Server type HTTP HTTPS
Proxy type
HTTP (no authentication)
        
          ClientBuilder.url("http://myserver.example")
            .proxyURL(new URL("http://myproxy.example"))
        
        
      
        ClientBuilder.url("https://myserver.example") // or .account("exampleAccount")
          .proxyURL(new URL("http://myproxy.example"))
      
      
HTTP (authentication)
          
            ClientBuilder.url("http://myserver.example")
              .proxyURL(new URL("http://myproxy.example"))
              .proxyUser("exampleProxyUser")
              .proxyPassword("exampleProxyPass")
          
          

Default HttpURLConnection:

      
        ClientBuilder.url("https://myserver.example") // or .account("exampleAccount")
          .proxyURL(new URL("http://myproxy.example"))

        // Configure the JVM Authenticator:
        // The library does not do this automatically because it applies JVM wide.
        // This is an example Authenticator. You should ensure that your Authenticator class does
        // not provide any other credentials to your proxy as they will be in the clear. For newer
        // JVM versions you may need to set the property jdk.http.auth.tunneling.disabledSchemes
        // to an appropriate value to allow proxy Basic authentication with HTTPS tunneling.
        // See CVE-2016-5597 and the documentation for jdk.http.auth.tunneling.disabledSchemes for
        // more information.
        Authenticator.setDefault(new Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {
              if (getRequestorType() == RequestorType.PROXY) {
                return new PasswordAuthentication("exampleProxyUser", "exampleProxyPassword".toCharArray());
              } else {
                  return null;
              }
            }
        });
      
      

Using okhttp:

      
        ClientBuilder.url("https://myserver.example") // or .account("exampleAccount")
          .proxyURL(new URL("http://myproxy.example"))
          .proxyUser("exampleProxyUser")
          .proxyPassword("exampleProxyPass")
      
      
HTTPS SSL proxies are not supported by the Proxy. This means that proxy authentication always happens in the clear. Note that client requests to a HTTPS server are always encrypted because a SSL tunnel is established through a HTTP proxy.
SOCKS SOCKS proxies are not supported internally by the CloudantClient. It may be possible to use a JVM or system level proxy configuration, but this is untested.

Project

Please visit the java-cloudant project page for more information.

Skip navigation links