See: Description
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.
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.
Use the ClientBuilder
class to build a CloudantClient
instance.
The CloudantClient
class is the starting point for
interacting
with Cloudant from Java.
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();
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();
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.
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)
.
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[])
.
CloudantClient
encapsulates the connection to the server and
provides access to server operations.
CloudantClient.database(String, boolean)
returns a
Database
object that provides access to database operations.
CRUD operations for documents in a database are achieved via the
Database
object.
Database.save(Object)
or
Database.post(Object)
Database.find(Class, String)
Database.save(Object)
or
Database.update(Object)
Database.remove(Object)
Database
also provides a bulk documents API for fetching or
modifying multiple documents in a single request.
Database.bulk(List)
AllDocsRequestBuilder
via
Database.getAllDocsRequestBuilder()
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.
Standalone attachment data is provided as an InputStream
. The attachment can
be
created and either referenced from an existing document or a new document.
Database.saveAttachment(java.io.InputStream,
java.lang.String, java.lang.String, java.lang.String, java.lang.String)
Database.saveAttachment(java.io.InputStream,
java.lang.String, java.lang.String)
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 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);
This feature interfaces with Cloudant's query functionality. See the Cloudant Query documentation for details.
Database.listIndexes()
Database.createIndex(java.lang.String)
Database.query(java.lang.String,
java.lang.Class)
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 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.
The ClientBuilder
provides access to additional advanced
configuration options for the server connection. For example customized SSL, proxies and
timeouts.
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();
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 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.
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.
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.
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.
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.
# "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:
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).
LogManager
.
LogManager manager = LogManager.getLogManager();
manager.readConfiguration(new FileInputStream("path/to/logging/config"));
// 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.
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.
This table provides a summary of the proxy configuration options.
Server type | HTTP | HTTPS |
---|---|---|
Proxy type | ||
HTTP (no authentication) |
|
|
HTTP (authentication) |
|
Default HttpURLConnection:
Using okhttp:
|
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.
|
Please visit the java-cloudant project page for more information.