Skip to content

cleverlzc/java-cloudant

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cloudant Java Client

Build Status

This is the official Cloudant library for Java

Installation and Usage

Maven:

<dependency>
  <groupId>com.cloudant</groupId>
  <artifactId>cloudant-client</artifactId>
  <version>1.1.2</version>
</dependency>

Gradle:

dependencies {
    compile group: 'com.cloudant', name: 'cloudant-client', version:'1.1.2'
}

Alternately download the dependencies cloudant.jar HttpClient 4.3.3 HttpCore 4.3.2 Commons Codec 1.6 Commons Logging 1.1.3 Gson 2.2.4

Getting Started

Now it's time to begin doing real work with Cloudant and Java. For working code samples of any of the API's please go to our Test suite.

Initialize your Cloudant connection by constructing a com.cloudant.client.api.CloudantClient . If you are connecting the managed service on cloudant.com, supply the account to connect to, api key ( if using an API key, otherwise pass in the account for this parameter also) and password. If you are connecting to Cloudant Local supply its URL, the userName or Apikey and password

Connecting to the managed service at cloudant.com example

String password = System.getProperty("cloudant_password");
CloudantClient client = new CloudantClient("mdb","mdb",password);

System.out.println("Connected to Cloudant");
System.out.println("Server Version: " + client.serverVersion());

List<String> databases = client.getAllDbs();
System.out.println("All my databases : ");
for ( String db : databases ) {
	System.out.println(db);
}

Connecting to Cloudant Local example

String password = System.getProperty("cloudant_password");
CloudantClient client = new CloudantClient("https://9.149.23.12","mdb",password);

System.out.println("Connected to Cloudant");
System.out.println("Server Version: " + client.serverVersion());

List<String> databases = client.getAllDbs();
System.out.println("All my databases : ");
for ( String db : databases ) {
	System.out.println(db);
}

Output:

Connected to cloudant
Server version = 1.0.2
All my databases: example_db, jasons_stuff, scores

When you instaniate a CloudantClient, you are authenticating with cloudant using the cookie authentication functionality.

Complete example

Here is simple but complete example of working with data:

String password = System.getProperty("cloudant_password");
CloudantClient client = new CloudantClient("mdb","mdb",password);

// Clean up the database we created previously.
client.deleteDB("alice");

// Create a new database.
client.createDB("alice");

// specify the database we are going to use
Database db = client.database("alice", false);

// and insert a document in it
db.save(new Rabbit(true));
System.out.println("You have inserted the Rabbit");
Rabbit r = db.find(Rabbit.class,"rabbit");
System.out.println(r);

   ...
public class Rabbit {
	private boolean crazy;
	private String _id = "rabbit";

	public Rabbit(boolean isCrazy) {
		crazy = isCrazy;
	}

	public String toString() {
		return " { id : " + _id + ", rev : " + _rev + ", crazy : " + crazy + "}";
	}
}

If you run this example, you will see:

you have inserted the rabbit.
{ crazy: true,
  id: rabbit,
  rev: 1-6e4cb465d49c0368ac3946506d26335d
}

API Reference

Initialization

When using the managed service at cloudant.com, initialize your Cloudant connection by constructing a CloudantClient supplying the account to connect to, api key ( if using an API key, otherwise pass in the account for this parameter also) and password (And see the security note about placing your password into your source code.

String password = System.getProperty("cloudant_password");
CloudantClient client = new CloudantClient("mdb","mdb",password);

System.out.println("Connected to Cloudant");

  /*
   * The rest of my code goes here.
   */
})

When using Cloudant Local, initialize your Cloudant connection by constructing a CloudantClient supplying the URL of the Cloudant Local along with userName or Apikey and password (And see the security note about placing your password into your source code.

String password = System.getProperty("cloudant_password");
CloudantClient client = new CloudantClient("https://9.123.45.64","mdb",password);

System.out.println("Connected to Cloudant");

  /*
   * The rest of my code goes here.
   */
})

Authorization

This feature interfaces with the Cloudant authorization API

Use the authorization feature to generate new API keys to access your data. An API key is basically a username/password pair for granting others access to your data, without giving them the keys to the castle.

Generate an API key.

ApiKey key = client.generateApiKey();
System.out.println(key);

Output:

key: isdaingialkyciffestontsk password: XQiDHmwnkUu4tknHIjjs2P64

Next, set access roles for this API key:

// Set read-only access for this key.
Database db = client.database("alice", false);
db.setPermissions(key.getKey(), EnumSet.<Permissions>of(Permissions._reader));
System.out.println(key.getKey() + " now has read-only access to alice")

Server Functions

Once CloudantClient is initialized without errors, the returned object is representing your connection to the server. To work with databases, use these database functions. (To work with data inside the databases, see below.)

com.cloudant.client.api.CloudantClient.createDB(name)

Create a Cloudant database with the given name.

client.createDB("alice");

com.cloudant.client.api.CloudantClient.database(name,create)

Get a Database reference

Database db = client.database("alice", false);
System.out.println("Database Name:" + db.info().getDbName() );

com.cloudant.client.api.CloudantClient.deleteDB(name)

Destroy database named name.

client.deleteDB("alice");

com.cloudant.client.api.CloudantClient.getAllDbs()

List all the databases in Cloudant server.

List<String> databases = client.getAllDbs();
System.out.println("All my databases : ");
for ( String db : databases ) {
	System.out.println(db);
}

com.cloudant.client.api.CloudantClient.getMembership()

getMembership() returns the list of nodes in a cluster

	Membership membership = client.getMembership();

com.cloudant.client.api.CloudantClient.getActiveTasks()

getActiveTasks() returns all active tasks

	List<Task> tasks = client.getActiveTasks();

com.cloudant.client.api.CloudantClient.replicator()

replicator() provides access to Cloudant com.cloudant.client.api.Replicator APIs

Replicator replicator = client.replicator()

com.cloudant.client.api.CloudantClient.replication()

Replicates source to target. target must exist, add createTarget(true) to create it prior to replication.

ReplicationResult result = client.replication()
					.createTarget(true)
					.source(db1.getDBUri().toString())
					.target(db2.getDBUri().toString())
					.trigger();
List<ReplicationHistory> histories = result.getHistories();

com.cloudant.client.api.CloudantClient.executeRequest()

This API enables extending Cloudant internal API by allowing a user-defined raw HTTP request to execute against a cloudant client.

HttpHead head = new HttpHead(dbClient.getDBUri() + "doc-id");
HttpResponse response = dbClient.executeRequest(head);
String revision = response.getFirstHeader("ETAG").getValue();
HttpClientUtils.closeQuietly(response);

com.cloudant.client.api.CloudantClient.uuids()

uuids() request cloudant to send a list of UUIDs.

	List<String> uuids = client.uuids(count);

com.cloudant.client.api.CloudantClient.getServerVersion()

getServerVersion() returns Cloudant Server version.

	String serverVersion = client.serverVersion();

Database Functions

com.cloudant.client.api.Database.changes()

com.cloudant.client.api.Database.changes().getChanges() asks for the changes feed on the specified database. includeDocs(true) and limit(1) sets additional properties to the query string.

ChangesResult changes = db.changes()
				.includeDocs(true)
				.limit(1)
				.getChanges();

List<ChangesResult.Row> rows = changes.getResults();

for (Row row : rows) {
	List<ChangesResult.Row.Rev> revs = row.getChanges();
	String docId = row.getId();
	JsonObject doc = row.getDoc();
}

com.cloudant.client.api.Database.changes().continuousChanges() asks for the continuous changes feed on the specified database. since(since), includeDocs(true) and limit(1) sets additional properties to the query string.

CouchDbInfo dbInfo = db.info();
String since = dbInfo.getUpdateSeq();
Changes changes = db.changes()
				.includeDocs(true)
				.since(since)
				.heartBeat(30000)
				.continuousChanges();

while (changes.hasNext()) {
	ChangesResult.Row feed = changes.next();
	final JsonObject feedObject = feed.getDoc();
	final String docId = feed.getId();
	changes.stop();
}

com.cloudant.client.api.Database.getShard(documentId)

getShard(documentId) gets info about the shard this document belongs to .

	Shard s = db.getShard("snipe");

getShards()get info about the shards in the database.

	List<Shard> shards = db.getShards();

com.cloudant.client.api.Database.Database.info()

.info() returns the DB info for this db.

	DbInfo dbInfo = db.info();

com.cloudant.client.api.Database.setPermissions()

.setPermissions() sets the permissions for a user/apiKey on the DB.

ApiKey key = client.generateApiKey();
EnumSet<Permissions> p = EnumSet.<Permissions>of( Permissions._writer, Permissions._reader);
db.setPermissions(key.getKey(), p);

com.cloudant.client.api.Database.ensureFullCommit()

Requests the database commits any recent changes to disk

db.ensureFullCommit();

Document Functions

Once you run com.cloudant.client.api.CloudantClient.database(name,create), use the returned object to work with documents in the database.

com.cloudant.client.api.Database.save(object)

Saves an object in the database, using HTTP PUT request.If the object doesn't have an _id value, we will assign a UUID as the document id.

Database db = dbClient.database("alice", true);
JsonObject json = new JsonObject();
json.addProperty("_id", "test-doc-id-2");
json.add("json-array", new JsonArray());
Response response =db.save(json);

Insert pojo in the database. The parameter object can be a pojo.

Database db = dbClient.database("alice", true);
Foo foo = new Foo();
Response response = db.save(foo);

Insert map in the database. The parameter object can be a map having key value presentation of a document.

Database db = dbClient.database("alice", true);
Map<String, Object> map = new HashMap<>();
map.put("_id", "test-doc-id-1");
map.put("title", "test-doc");
Response response =db.save(map);

com.cloudant.client.api.Database.save(object,writeQuorum)

Saves an object in the database, using HTTP PUT request, with specified write quorum .If the object doesn't have an _id value, we will assign a UUID as the document id.

Database db = dbClient.database("alice", true);
Response response = db.save(new Animal("human"), 2);

com.cloudant.client.api.Database.post(object)

Saves an object in the database using HTTP POST request.The database will be responsible for generating the document id.

Database db = dbClient.database("alice", true);
Response response = db.post(new Foo());

com.cloudant.client.api.Database.post(object,writeQuorum)

Saves an object in the database using HTTP POST request with specificied write quorum.The database will be responsible for generating the document id.

Database db = dbClient.database("alice", true);
db.post(new Animal("test"), 2);
Animal h = db.find(Animal.class, "test",
				new com.cloudant.client.api.model.Params().readQuorum(3));

com.cloudant.client.api.Database.saveAttachment(inputStream,name,contentType)

Saves an attachment to a new document with a generated UUID as the document id.

byte[] bytesToDB = "binary data".getBytes();
ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain");

com.cloudant.client.api.Database.saveAttachment(inputStream,name,contentType,docId,docRev)

Saves an attachment to an existing document given both a document id and revision, or save to a new document given only the id, and rev as null.

byte[] bytesToDB = "binary data".getBytes();
ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain","abcd12345",null);

com.cloudant.client.api.Database.batch(object)

Saves a document with batch. You can write documents to the database at a higher rate by using the batch option. This collects document writes together in memory (on a user-by-user basis) before they are committed to disk. This increases the risk of the documents not being stored in the event of a failure, since the documents are not written to disk immediately.

Database db = dbClient.database("alice", true);
db.batch(new Foo());

com.cloudant.client.api.Database.find(doc-id)

Finds a document based on the provided doc-id and return the result as InputStream. Make sure you close the stream when done, else you could lock up the client easily

Database db = dbClient.database("alice", true);
Response response = db.save(new Foo());
InputStream inputStream = db.find(response.getId());

// do stuff and finally dont forget to close the stream
inputStream.close();

com.cloudant.client.api.Database.find(doc-id,rev)

Finds a document based on the provided doc-id and rev,return the result as InputStream. Make sure you close the stream when done, else you could lock up the client easily

Database db = dbClient.database("alice", true);
Response response = db.save(new Foo());
InputStream inputStream = db.find(response.getId(),response.getRev());

// do stuff and finally dont forget to close the stream
inputStream.close();

com.cloudant.client.api.Database.find(class,doc-id)

Retrieve the pojo from database by providing doc_id .

Database db = dbClient.database("alice", true);
Foo foo = db.find(Foo.class, "doc-id");

com.cloudant.client.api.Database.find(class,doc-id,rev-id)

Retrieve the pojo from database by providing doc_idand rev-id .

Database db = dbClient.database("alice", true);
Foo foo = db.find(Foo.class, "doc-id", "rev-id");

com.cloudant.client.api.Database.find(class,doc-id,params)

Finds an Object of the specified type by providing doc_id.Extra query parameters can be specified via params argument

Database db = dbClient.database("alice", true);
Response response = db.save(new Foo());
Foo foo = db.find(Foo.class, response.getId(), new Params().revsInfo());

com.cloudant.client.api.Database.findAny(class,uri)

This method finds any document given a URI.The URI must be URI-encoded.

Database db = dbClient.database("alice", true);
Foo foo = db.findAny(Foo.class,
				"https://mdb.cloudant.com/alice/03c6a4619b9e42d68db0e592757747fe");

com.cloudant.client.api.Database.contains(doc-id)

returns true if the document exists with given doc-id

Database db = dbClient.database("alice", true);
boolean found = db.contains("doc-id");

com.cloudant.client.api.Database.update(object)

Updates an object in the database, the object must have the correct _id and _rev values.

Database db = dbClient.database("alice", true);
String idWithSlash = "a/" + generateUUID();
Response response = db.save(new Bar(idWithSlash));

Bar bar = db.find(Bar.class, response.getId());
Response responseUpdate = db.update(bar);

com.cloudant.client.api.Database.update(object,writeQuorum)

Updates an object in the database, the object must have the correct _id and _rev values. The second argument is the write quorum for the update.

db.save(new Animal("human"), 2);
Animal h = db.find(Animal.class, "human",
				new com.cloudant.client.api.model.Params().readQuorum(2));
db.update(h.setClass("inhuman"), 2);

com.cloudant.client.api.Database.remove(object)

The API removes the object from database. The object should contain _id and _rev .

Database db = dbClient.database("alice", true);
Response response = db.remove(foo);

com.cloudant.client.api.Database.remove(doc-id,rev-id)

Database db = dbClient.database("alice", true);
Response response = db.remove("doc-id", "doc-rev");

com.cloudant.client.api.Database.invokeUpdateHandler(updateHandlerUri,docId,query)

Invokes an Update Handler.Use this method in particular when the docId contain special characters such as slashes (/). The updateHandlerUri should be in the format: designDoc/update1.

final String oldValue = "foo";
final String newValue = "foo bar";
Response response = db.save(new Foo(null, oldValue));
String query = "field=title&value=" + newValue;
String output = db.invokeUpdateHandler("example/example_update", response.getId(), query);

com.cloudant.client.api.Database.invokeUpdateHandler(updateHandlerUri,docId,params)

This method can be used if the query is generated using Params API.

final String oldValue = "foo";
final String newValue = "foo bar";
Response response = db.save(new Foo(null, oldValue));
Params params = new Params()
				.addParam("field", "title")
				.addParam("value", newValue);
String output = db.invokeUpdateHandler("example/example_update", response.getId(), params);

Bulk Documents

Bulk documents API performs two operations: Modify & Fetch for bulk documents.

Insert/Update docs

List<Object> newDocs = new ArrayList<Object>();
newDocs.add(new Foo());
newDocs.add(new JsonObject());
List<Response> responses = db.bulk(newDocs);

Fetch all/multiple documents

List all the docs in the database with optional query string additions params.

List<Foo> docs = dbClient.view("_all_docs")
					  .includeDocs(true)
					  .query(Foo.class);

List multiple documents specified by docID's in the database .

List<String> keys = Arrays.asList(new String[]{"doc-id-1", "doc-id-2"});
List<Foo> docs = dbClient.view("_all_docs")
					  .includeDocs(true)
					  .keys(keys)
					  .query(Foo.class);

Attachment Functions

Inline attachment

com.cloudant.client.api.model.Attachment represents an inline attachment enclosed in a document.

The base64 data of an attachment may be encoded utilizing the included dependency on Apache Codec Base64.encodeBase64String(bytes).

Model classes that extend com.cloudant.client.api.model.Document inherit the support for inline attachments.

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);

To retrieve the base64 data of an attachment, include a parameter to the find()

Foo foo = db.find(Foo.class, "doc-id", new Params().attachments());
String attachmentData = foo.getAttachments().get("attachment.txt").getData();

Standalone Attachments

Standalone attachments could be saved to an existing, or to a new document. The attachment data is provided as InputStream

byte[] bytesToDB = "binary attachment data".getBytes();
ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesToDB);
Response response = db.saveAttachment(bytesIn, "foo.txt", "text/plain");
InputStream in = db.find( "doc_id/foo.txt");

Design Document Functions

These functions are for working with views and design documents, including querying the database using map-reduce views, Cloudant Search, and Cloudant Query.

query on a view

Call a view of the specified design to get the list of documents.

List<Foo> foos = db.view("example/foo")
			        .includeDocs(true)
				.query(Foo.class);

If you're looking to filter the view results by key(s), pass multiple keys as the argument of key() function

List<Foo> foos = db.view("example/foo")
				.includeDocs(true)
				.key("key-1","key-2")
				.query(Foo.class);

If you're looking to filter the view results by a range of keys, call startKey(key) and endKey(key) method

List<Foo> foos = db.view("example/foo")
				.startKey("key-1")
				.endKey("key-2")
				.includeDocs(true)
				.query(Foo.class);

To get the primitive value call the scalar methods e.g queryForInt() or queryForLong()

int count = dbClient.view("example/by_tag").key("cloudantdb").queryForInt();

retrieving the design doc from server

call getFromDb(design-doc) to retrieve the server copy .

DesignDocument designDoc = db.design().getFromDb("_design/example");

Creating a View (Map-Reduce Index)

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

// 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);

Take a look at the CouchDB wiki for possible query paramaters and more information on show functions.

Cloudant Query

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

when working with a database (as opposed to the root server), call the .database() method.

Database db = dbClient.database("movies-demo", false);

To see all the indexes in a database, call the database .listIndices() method .

List<Index> indices = db.listIndices();

To create an index, use .createIndex() method

db.createIndex("Person_name", "Person_name", null,
				new IndexField[]{
					new IndexField("Person_name",SortOrder.asc),
					new IndexField("Movie_year",SortOrder.asc)});
db.createIndex("Movie_year", "Movie_year", null,
				new IndexField[]{
				       new IndexField("Movie_year",SortOrder.asc)});

To query using the index, use the .findByIndex() method.

List<Movie> movies = db.findByIndex("{
                     \"Movie_year\": {\"$gt\": 1960}, \"Person_name\": \"Alec Guinness\"
                     }",
					Movie.class,
					new FindByIndexOptions()
						.sort(new IndexField("Movie_year", SortOrder.desc))
						.fields("Movie_name").fields("Movie_year"));

Cloudant Search

This feature interfaces with Cloudant's search functionality. See the Cloudant Search documentation for details.

First, when working with a database (as opposed to the root server), call the .database() method.

Database db = dbClient.database("movies-demo", false);

Creating a search index

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, create instance of com.cloudant.client.api.Search by calling the database .search() method. The argument of .search() method is the design document name. The other criterion can be set by calling different methods on search object.

Search search = db.search("views101/animals");
SearchResult<Animal> rslt= search.limit(10)
				                       .includeDocs(true)
                                 			.counts(new String[] {"class","diet"})
				                        .querySearchResult("l*", Animal.class);

Cookie Authentication

Cloudant supports making requests using Cloudant's cookie authentication functionality. there's a step-by-step guide here, but essentially you just:

 CloudantClient client = new CloudantClient("cloudant.account",
							 "cloudant.username",
							 "cloudant.password"));
String cookie = client.getCookie() ;

To reuse a cookie:

// Make a new connection with the cookie.
CloudantClient cookieBasedClient = new
                          CloudantClient("cloudant.account", cookie);

Advanced Configuration

Besides the account and password options, you can add an optional com.cloudant.client.api.model.ConnectOptions value, which will initialize HttpClient (the underlying HTTP library) as you need it.

ConnectOptions connectOptions = new ConnectOptions()
                                        .setSocketTimeout(50)
                                        .setConnectionTimeout(50)
                                        .setMaxConnections(100)
                                        .setProxyHost("http://localhost")
                                        .setProxyPort(8080)
                                        .setSSLAuthenticationDisabled(true);
 CloudantClient client = new CloudantClient("cloudant.com","test","password",
                                                  connectOptions );

java-cloudant internally uses the Gson library to serialize/deserialize JSON to/from Java objects. You can register your custom de-serializers by providing the CloudantClient instance by with your own GsonBuilder instance

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

CloudantClient account = new CloudantClient(cloudantaccount,userName,password);
account.setGsonBuilder(builder);

tests

The test suite needs access to cloudant account(s) to run. To run the test suite first edit the cloudant properties. Copy the files src/test/resources/cloudant-sample.properties and src/test/resources/cloudant-2-sample.properties to src/test/resources/cloudant.properties and src/test/resources/cloudant-2.properties, and then provide values for the following properties:

cloudant.account=myCloudantAccount
cloudant.username=testuser
cloudant.password=testpassword

Once all the required properties are provided in the properties file run the com.cloudant.test.main.CloudantTestSuite test class.

License

Copyright 2014-2015 Cloudant, an IBM company.

Licensed under the apache license, version 2.0 (the "license"); you may not use this file except in compliance with the license. you may obtain a copy of the license at

http://www.apache.org/licenses/LICENSE-2.0.html

Unless required by applicable law or agreed to in writing, software distributed under the license is distributed on an "as is" basis, without warranties or conditions of any kind, either express or implied. See the license for the specific language governing permissions and limitations under the license.

[issues]: https://github.com/cloudant/java-cloudant /issues [follow]: https://github.com/iriscouch/follow [request]: https://github.com/mikeal/request

About

A Java client for Cloudant

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 99.4%
  • JavaScript 0.6%