CHAPTER 8

MIGRATING COUCHBASE TO CASSANDRA

Couchbase server is one of the leading NoSQL databases, and is based on the JSON document model. Couchbase’s document model is different from Cassandra’s, as Cassandra is based on the flexible table (column family) data model. But, it is still feasible to migrate a Couchbase Server document to Cassandra. In this chapter, you will migrate a JSON document from Couchbase Server to Cassandra in the Eclipse IDE.

SETTING THE ENVIRONMENT

To set the environment, you must install the following software:

Images Couchbase Server Community Edition couchbase-server-community_x86_64_2.0.1. setup.exe from http://www.couchbase.com/download. Double-click the EXE file to launch the installer for Couchbase database and install it.

Images Couchbase Server Java SDK client library Couchbase-Java-Client-1.2.2.zip file from http://www.couchbase.com/develop/java/previousand extract to Couchbase-Java-Client-1.2.2 directory.

Images Eclipse IDE for Java EE developers from http://www.eclipse.org/downloads/.

Images Apache Commons BeanUtils 1.9.0 commons-beanutils-1.9.0-bin.zip file from http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi. Extract to the commons-beanutils-1.9.0-bin directory.

Images Apache Commons Collections 3.2.1 from http://archive.apache.org/dist/commons/collections/binaries/. Extract to the commons-collections-3.2.1-bin directory.

Images Apache Commons Lang 2.6 commons-lang-2.6-bin.zip from http://commons.apache.org/proper/commons-lang/download_lang.cgi. Extract to the commons-lang-2.6-bin directory.

Images Apache Commons Logging 1.1.3 from http://commons.apache.org/proper/commons-logging/. Extract to the commons-logging-1.1.3-bin directory.

Images Json-lib JAR json-lib-2.4-jdk15.jar from http://sourceforge.net/projects/json-lib/files/json-lib/.

Images EZMorph ezmorph-1.0.6.jar from http://sourceforge.net/projects/ezmorph/files/.

Images Hector Java client hector-core-1.1-4.jar or a later version from http://repo2.maven.org/maven2/org/hectorclient/hector-core/1.1-4/.

Images Apache Cassandra 2.04 or a later version from http://cassandra.apache.org/download/. Add C:Cassandraapache-cassandra-2.0.4into the PATH variable.

Start Apache Cassandra server with the following command:

>cassandraf

CREATING A JAVA PROJECT

You will migrate Couchbase Server to Cassandra using a Java application in the Eclipse IDE. To do so, create a Java project in Eclipse IDE. Follow these steps:

1. Select File > New > Other.

2. In the New dialog box, select Java > Java Project. Then click Next, as shown in Figure 8.1.

Figure 8.1
Selecting Java > Java Project.

Images

Source: Eclipse Foundation.

3. In the New Java Project wizard, specify a project name
(MigrateCouchbaseToCassandra), select JDK 1.7 as the JRE, and click Next, as shown in Figure 8.2.

Figure 8.2
Specifying the project name.

Images

Source: Eclipse Foundation.

4. In the Java Settings dialog box, select the Allow Output Folders checkbox and select the default output folder MigrateCouchbaseToCassandra/bin. Then click Finish, as shown in Figure 8.3.

Figure 8.3
Configuring Java settings.

Images

Source: Eclipse Foundation.

5. Next, add two Java classes to the Java project—one to create a JSON document in Couchbase and another to migrate the JSON document to Cassandra. To create the first class, select File > New > Other. Then, in the New dialog box, select Java > Class and click Next, as shown in Figure 8.4.

Figure 8.4
Selecting Java > Class.

Images

Source: Eclipse Foundation.

6. In the New Java Class wizard, specify a package (cassandra) and the class name (CreateCouchbaseJSON). Then click Finish, as shown in Figure 8.5.

Figure 8.5
Configuring a Java class to store a Couchbase document.

Images

Source: Eclipse Foundation.

7. Repeat steps 5 and 6 to create another Java class, CouchbaseToCassandra, as shown in Figure 8.6. The directory structure of the MigrateCouchbaseToCassandra Java project with the two classes is shown in Figure 8.7.

Figure 8.6
Configuring a Java class to migrate Couchbase to Cassandra.

Images

Source: Eclipse Foundation.

Figure 8.7
The directory structure of the MigrateCouchbaseToCassandra Java project.

Images

Source: Eclipse Foundation.

8. Next, you must add some JAR files to the project class path. Add the JAR files listed in Table 8.1, which are from the Cassandra server download, Couchbase Server download, Hector Java client for Cassandra, and some third-party JARs.

Table 8.1 JAR Files for Migration

Images
Images

To add the required JARs, right-click the project node in Package Explorer and select Properties. Then, in the Properties dialog box, select Java Build Path. Finally, click the Add External JARs button to add the external JAR files. The JARs added to the migration project are shown in Figure 8.8.

Figure 8.8
JAR files in the Java build path.

Images

Source: Eclipse Foundation.

CREATING A JSON DOCUMENT IN COUCHBASE

The com.couchbase.client.CouchbaseClient class is the client class for Couchbase Server and is the entry point to access the Couchbase cluster, which may consist of one or more servers. In the CreateCouchbaseJSON class, you will use the CouchbaseClient class to create and store a JSON document in Couchbase Server. The CouchbaseClient class provides three constructors to create an instance. You will use the constructor CouchbaseClient(java.util.List<java.net.URI> baseList,java.lang.String bucketName, java.lang.String pwd), in which baseList is the URI List of one or more servers in the Couchbase cluster. To obtain the server URIs, log in to the Couchbase Server cluster and select Server Nodes. Then click the Server Node Name link(s) to obtain the server name, as shown in Figure 8.9.

Figure 8.9
Couchbase server name.

Images

Source: Couchbase Inc.

The server name is 127.0.0.1:8091. By default, Couchbase Server uses http://localhost:8091/pools to connect to clients. Specify 127.0.0.1. or localhost in the connection URI. Alternatively, use the IPv4 address of the host obtained with the ipconfig / all command. Create a LinkedList<URI> object and add the URI to the List using the add() method:

List<URI> uris = new LinkedList<URI>();
uris.add(URI.create("http://192.168.1.71:8091/pools"));

Couchbase Server stores documents in data buckets. The bucketName parameter specifies the bucket name to use. The default data bucket is called "default". The default username for a data bucket is the same as the bucket name. The "default" bucket does not require a password. Specify password as an empty String.

CouchbaseClient couchbaseClient = new CouchbaseClient(uris, "default", "");
Couchbase server stores documents as JSON. Specify the JSON String to store.
String value = "{"journal":"Oracle Magazine","publisher":"Oracle
Publishing","edition":"March April 2013","title":"Engineering as a
Service","author":"David A. Kelly"}";

The CouchbaseClient class provides overloaded set methods to store/add documents to Couchbase Server. You will use the set(java.lang.String key,int exp,java.lang. Object value,PersistTo req) method. The first parameter key of type String is the document key. The second parameter exp of type int is the expiry time. A value of 0 for exp makes the document persistent without expiration. The value parameter of type Object is the JSON value to store. The req parameter of type PersistTo is the number of nodes the document should be persisted to.

OperationFuture<java.lang.Boolean> operationFuture =
couchbaseClient.set("catalog", 0, value, PersistTo.ONE);

The set method returns an OperationFuture<java.lang.Boolean> object that may be used to find if the document got stored or not.

if (operationFuture.get().booleanValue()) {
              System.out.println("Set Succeeded");
       } else {
              System.err.println("Set failed: " +
operationFuture.getStatus().getMessage());
}

Couchbase Server uses a view processor to process documents stored in the server. A view processor takes the unstructured or semi-structured data stored in Couchbase Server, extracts the fields from the document, and indexes the data. As a result, a view of the data stored in the Couchbase data store is created. A view makes it easier to iterate, select, and query the data stored in the server. The view processor relies on the data being stored in JSON format in Couchbase Server. Design documents are used to encapsulate one or more views. The com.couchbase.client.protocol.views.DesignDocument class represents a design document. Create a DesignDocument using a class constructor:

DesignDocument designDoc = new DesignDocument("JSONDocument");

The com.couchbase.client.protocol.views.ViewDesign class represents a view to be stored and retrieved from the Couchbase data store. The ViewDesign class provides two constructors, both of which take a view name and a map() function as arguments. One of the constructors also takes a reduce() function as an argument. Specify a view name.

String viewName = "by_name";

A mapping function, map(), must be supplied to map the JSON data stored in Couchbase Server and the output results of the view. The first argument to the map() function is the JSON document and the second argument is the metadata associated with the JSON document, such as the document name and type. The map() function emits rows (zero or more) of information using the invocations of the emit() function.

String mapFunction = "   function(doc,meta) {
"
       + "   if (meta.type == 'json') {
"
       + "   emit(doc.name, doc);
"
+ "   }
" + "}";

Create a ViewDesign object using the view name and the map() function:

ViewDesign viewDesign = new ViewDesign(viewName, mapFunction);

Add the ViewDesign object to the DesignDocument class invoking the getViews() method on the DesignDocument object to obtain the list of ViewDesigns and subsequently invoking the add method on the List object.

designDoc.getViews().add(viewDesign);

Store the DesignDocument class in the cluster using the asyncCreateDesignDoc (DesignDocument doc) method in the CouchbaseClient class:

HttpFuture<java.lang.Boolean> httpFuture = couchbaseClient.asyncCreateDesignDoc(designDoc);

You can use the HttpFuture object returned to determine whether the design document got stored:

if (httpFuture.get().booleanValue()) {
       System.out.println("Design Document Store Succeeded");
} else {
       System.err.println("Design Document Store failed: "
       + httpFuture.getStatus().getMessage());
}

The CreateCouchbaseJSON class appears in Listing 8.1.

Listing 8.1 The CreateCouchbaseJSON Class

package cassandra;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import net.spy.memcached.PersistTo;
import net.spy.memcached.internal.OperationFuture;
import com.couchbase.client.CouchbaseClient;
import com.couchbase.client.internal.HttpFuture;
import com.couchbase.client.protocol.views.DesignDocument;
import com.couchbase.client.protocol.views.Query;
import com.couchbase.client.protocol.views.Stale;
import com.couchbase.client.protocol.views.View;
import com.couchbase.client.protocol.views.ViewDesign;
import com.couchbase.client.protocol.views.ViewResponse;
 
public class CreateCouchbaseJSON {
       private static CouchbaseClient couchbaseClient;
       public static void main(String[] args) {
              try{
              List<URI> uris = new LinkedList<URI>();
               uris.add(URI.create("http://192.168.1.71:8091/pools"));
              CouchbaseClient couchbaseClient = new CouchbaseClient(uris,
"default", "");
              String value = "{"journal":"Oracle Magazine","publisher":
"Oracle Publishing","edition":"March April 2013","title":"Engineering
as a Service","author":"David A. Kelly"}";
              OperationFuture<java.lang.Boolean> operationFuture =
couchbaseClient
                            .set("catalog", 0, value, PersistTo.ONE);
              if (operationFuture.get().booleanValue()) {
                     System.out.println("Set Succeeded");
              } else {
                     System.err.println("Set failed: "
                            + operationFuture.getStatus().getMessage());
              }
              DesignDocument designDoc = new DesignDocument("JSONDocument");
              String viewName = "by_name";
              String mapFunction = "  function(doc,meta) {
"
                            + "   if (meta.type == 'json') {
"
                            + "   emit(doc.name, doc);
"
                            + "   }
" + "}";
              ViewDesign viewDesign = new ViewDesign(viewName, mapFunction);
              designDoc.getViews().add(viewDesign);
                     HttpFuture<java.lang.Boolean> httpFuture = couchbaseClient
                     .asyncCreateDesignDoc(designDoc);
                     if (httpFuture.get().booleanValue()) {
                             System.out.println("Design Document Store
Succeeded");
                     } else {
                             System.err.println("Design Document Store failed: "
                     + httpFuture.getStatus().getMessage());
                     }
             } catch (UnsupportedEncodingException e) {
                     e.printStackTrace();
             } catch (InterruptedException e) {
                     e.printStackTrace();
             } catch (ExecutionException e) {
                     e.printStackTrace();
             } catch (IOException e) {
                    e.printStackTrace();
             }
       }
}

To create the JSON document in Couchbase Server, run the CreateCouchbaseJSON.java source file. Right-click the CreateCouchbaseJSON.java file in Package Explorer and select Run As > Java Application, as shown in Figure 8.10. The output from the application, shown in Figure 8.11, indicates that the JSON document is stored in the Couchbase Server and the design document is also stored.

Figure 8.10
Running the CreateCouchbaseJSON application.

Images

Source: Eclipse Foundation.

Figure 8.11
Output from the CreateCouchbaseJSON application.

Images

Source: Eclipse Foundation.

Log in to the Couchbase Server Administration Console. Then click Data Buckets and select the default bucket. The documents for the default bucket are listed. The JSON document with the ID catalog is also listed. Click the Edit Document button to edit or display the document, as shown in Figure 8.12. The JSON for the catalog ID documents is displayed, as shown in Figure 8.13.

Figure 8.12
The document with the ID catalog in the Couchbase Server Administration Console.

Images

Source: Couchbase Inc.

Figure 8.13
Displaying the JSON document added to Couchbase Server in the Couchbase Server Administration Console.

Images

Source: Couchbase Inc.

The by_name view is also created. Click Views in the Couchbase Administration Console (see Figure 8.14) to list the by_name view. The by_name view is displayed.

Figure 8.14
Selecting Views in the Couchbase Administration Console.

Images

Source: Couchbase Inc.

Click the Show button to list the view’s map() and reduce() functions, as shown in Figure 8.15. The view code, including the map() function, is listed, as shown in Figure 8.16.

Figure 8.15
Selecting Views > by_name > Show in Couchbase Administration Console.

Images

Source: Couchbase Inc.

Figure 8.16
The view code for the by_name view.

Images

Source: Couchbase Inc.

MIGRATING THE COUCHBASE DOCUMENT TO CASSANDRA

In this section, you will query the JSON document stored earlier in Couchbase Server and migrate the JSON document to the Apache Cassandra database. You will use the CouchbaseToCassandra class to migrate the JSON document from Couchbase Server to the Cassandra database. You added a view encapsulated in a design document to Couchbase Server; you can use this view to query Couchbase Server. The CouchbaseClient class provides the query(AbstractView view, Query query) method to query the server. AbstractView is the abstract superclass to the View class. The Query type parameter represents the type of query to run. But first, you must create an instance of View and an instance of Query to supply as arguments to the query() method. Create an instance of CouchbaseClient as discussed when storing a JSON document in Couchbase Server.

List<URI> uris = new LinkedList<URI>();
uris.add(URI.create("http://192.168.1.71:8091/pools"));
CouchbaseClient couchbaseClient = new CouchbaseClient(uris, "default", "");

Get access to the view stored in the design document in Couchbase Server using the getView(java.lang.String designDocumentName, java.lang.String viewName) method, which takes the design document name and view name as arguments.

View view = couchbaseClient.getView("JSONDocument", "by_name");

Create an instance of Query and invoke the setIncludeDocs(boolean include) method to include full documents in the result. Optionally, set a limit on the number of documents returned using the setLimit(int limit) method.

Query query = new Query();
query.setIncludeDocs(true).setLimit(20);
query.setStale(Stale.FALSE);

To disallow results from a stale view, invoke the setStale(Stale stale) method with the argument as Stale.FALSE. Invoke the query(AbstractView view, Query query) method using the View instance and Query instance to obtain a result as a ViewResponse object.

ViewResponse result = couchbaseClient.query(view, query);

Get a Map of key/value records in the ViewResponse using the getMap() method:

java.util.Map<java.lang.String, java.lang.Object> map = result.getMap();

Next, you will migrate the resulting Map to the Cassandra database. As discussed in Chapter 1, “Using Cassandra with Hector,” the me.prettyprint.hector.api.Cluster interface represents a cluster of Cassandra hosts. To access a Cassandra cluster, first you need to create a Cluster instance for a Cassandra cluster. Create a Cluster instance using the getOrCreateCluster(String clusterName, String hostIp) method as follows:

Cluster cluster = HFactory.getOrCreateCluster("migration-cluster",
"localhost:9160");

Next, create a schema if not already defined. A schema consists of a column family definition and a keyspace definition. Use the describeKeyspace method in Cluster to obtain a KeyspaceDefinition object for MigrationKeyspace keyspace. If the keyspace definition object is null, invoke a createSchema() method to create a schema.

KeyspaceDefinition keyspaceDef = cluster.describeKeyspace("MigrationKeyspace");
       if (keyspaceDef == null) {
       createSchema();
}

As discussed in Chapter 1, add a createSchema() method to create a column family definition and a keyspace definition for the schema. Create a column family definition for a column family named "catalog", a keyspace named MigrationKeyspace, and a comparator named ComparatorType.BYTESTYPE.

ColumnFamilyDefinition cfDef = HFactory.createColumnFamilyDefinition(
"MigrationKeyspace", "catalog", ComparatorType.BYTESTYPE);

Using a replicationFactor of 1, create a KeyspaceDefinition instance from the preceding column family definition. Specify the strategy class as org.apache.cassandra. locator.SimpleStrategy using the constant ThriftKsDef.DEF_STRATEGY_CLASS.

int replicationFactor = 1;
KeyspaceDefinition keyspace = HFactory.createKeyspaceDefinition(
"MigrationKeyspace", ThriftKsDef.DEF_STRATEGY_CLASS,
replicationFactor, Arrays.asList(cfDef));

Add the keyspace definition to the Cluster instance. With blockUntilComplete set to true, the method blocks until schema agreement is received.

cluster.addKeyspace(keyspace, true);

Adding a keyspace definition to a Cluster instance does not create a keyspace. Having added a keyspace definition, you need to create a keyspace. Add a createKeyspace() method to create a keyspace and invoke the method from the main method. A keyspace is represented with the me.prettyprint.hector.api.Keyspace interface. The HFactory class provides static methods to create a Keyspace instance from a Cluster instance to which a keyspace definition has been added. Invoke the method createKeyspace (String keyspace, Cluster cluster) to create a Keyspace instance with the name MigrationKeyspace.

private static void createKeyspace() {
       keyspace = HFactory.createKeyspace("MigrationKeyspace", cluster);
}

Next, create a template and add a createTemplate() method to it. Invoke the method from the main method. Templates provide reusable constructs containing the fields common to all Hector client operations. Create an instance of ThriftColumnFamilyTemplate using a class constructor ThriftColumnFamilyTemplate(Keyspace keyspace, String columnFamily, Serializer<K> keySerializer, Serializer<N> topSerializer). Use the Keyspace instance created earlier and specify the column family name as "catalog".

ThriftColumnFamilyTemplate template = new ThriftColumnFamilyTemplate<String,
String>(keyspace,"catalog", StringSerializer.get(), StringSerializer.get());

Next, you will migrate the data retrieved from Couchbase Server to the column family "catalog" in the keyspace MigrationKeyspace. Add a method called migrate() and invoke it from the main method. In the migrate() method, you will migrate the Map object retrieved from the Couchbase JSON document to Cassandra. In the Hector API, the Mutator class is used to add data. First, you need to create an instance of Mutator using the static method createMutator(Keyspace keyspace,Serializer<K> keySerializer) in HFactory. Supply the Keyspace instance previously created and also supply a StringSerializer instance.

Mutator<String> mutator = HFactory.createMutator(keyspace,
StringSerializer.get());

Next, iterate over the JSON document result Map obtained earlier using an enhanced for loop.

for (java.util.Map.Entry<String, Object> entry : map.entrySet()) {
}

Next, add code within the for loop. Output the key/value pair(s) in the Map using the java.util.Map.Entry.getKey() and corresponding getValue() methods.

System.out.println(entry.getKey());
System.out.println(entry.getValue());

An unordered collection of name/value pairs, which constitute a JSON document, is represented by the net.sf.json.JSONObject class. Its format is a string enclosing a JSON name/value pair using {}, with , separating the name/value pairs. The values in name/value pairs may be of one of the following types: String, Boolean, JSONArray, JSONObject, Number, or JSONNull. Create a JSONObject instance from the JSON object in the result Map using the JSON-lib. The net.sf.json.JSONSerializer class is used to transform Java objects to JSON and back. Invoke the toJSON(Object object) method to create a JSONObject instance from the JSON object in the result Map.

JSONObject json = (JSONObject) JSONSerializer.toJSON(entry
.getValue().toString());

Obtain a Set object from the JSONObject and create an Iterator from the Set object.

Set set = json.keySet();
Iterator iter = set.iterator();

The Mutator class provides the addInsertion(K key, String cf, HColumn<N, V> c) method to add an HColumn instance and return the Mutator instance, which may be used again to add another HColumn instance. You can add a series of HColumn instances by invoking the Mutator instance sequentially. Using the Iterator obtained from the result Map from Couchbase JSON document, you will add multiple columns to a Mutator instance using addInsertion invocations in series.

Using the Iterator and the hasNext() method, obtain the JSON document as an Object. Obtain the key for the JSON document from the MapEntry object by invoking the getKey().toString() methods. The column family name is "catalog". Using the while loop, add multiple columns to a Mutator instance using addInsertion invocations in series. Add HColumn<String,String> instances, which represent columns using the static method createStringColumn(String name, String value). By iterating over the key set, obtain the column names using the obj.toString() method. Obtain the corresponding column values from the JSONObject instance created from the JSON document using the json.get(obj.toString()).toString()) method invocation.

while (iter.hasNext()) {
       Object obj = iter.next();
       mutator = mutator.addInsertion(
       entry.getKey().toString(),
       "catalog",
       HFactory.createStringColumn(obj.toString(),
       json.get(obj.toString()).toString()));
}

The mutations added to the Mutator instance are not sent to the Cassandra server until the execute() method is invoked.

System.out.println(mutator.execute().getHostUsed());

The JSON document from Couchbase Server is migrated to Cassandra. To find the table data created in Cassandra from the Couchbase JSON document, add a retrieveTableData() method and invoke it from the main method. In the retrieveTableData() method, use the ThriftColumnFamilyTemplate instance to query multiple columns with the queryColumns (K key) method, which queries the columns in the row corresponding to the provided Key value ColumnFamilyResult instance. Using the template, query the columns in the row corresponding to the "catalog" key.

ColumnFamilyResult<String, String> res = template.queryColumns("catalog");

Obtain and output the String column values in the ColumnFamilyResult instance obtained from the preceding query.

String journal = res.getString("journal");
String publisher = res.getString("publisher");
String edition = res.getString("edition");
String title = res.getString("title");
String author = res.getString("author");
System.out.println(journal);
System.out.println(publisher);
System.out.println(edition);
System.out.println(title);
System.out.println(author);

The CouchbaseToCassandra class appears in Listing 8.2.

Listing 8.2 The CouchbaseToCassandra Class

package cassandra;
 
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import me.prettyprint.hector.api.Keyspace;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.cassandra.service.ThriftKsDef;
import me.prettyprint.cassandra.service.template.ColumnFamilyResult;
import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;
import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
import me.prettyprint.hector.api.Cluster;
import com.couchbase.client.CouchbaseClient;
import com.couchbase.client.protocol.views.Query;
import com.couchbase.client.protocol.views.Stale;
import com.couchbase.client.protocol.views.View;
import com.couchbase.client.protocol.views.ViewResponse;
import me.prettyprint.hector.api.ddl.ColumnFamilyDefinition;
import me.prettyprint.hector.api.ddl.ComparatorType;
import me.prettyprint.hector.api.ddl.KeyspaceDefinition;
import me.prettyprint.hector.api.exceptions.HectorException;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
 
public class CouchbaseToCassandra {
       private static CouchbaseClient couchbaseClient;
       private static Cluster cluster;
       private static Keyspace keyspace;
       private static ColumnFamilyTemplate<String, String> template;
       private static java.util.Map<java.lang.String, java.lang.Object> map;
       public static void main(String[] args) {
              List<URI> uris = new LinkedList<URI>();
              uris.add(URI.create("http://192.168.1.71:8091/pools"));
              try {
                     couchbaseClient = new CouchbaseClient(uris, "default", "");
                     View view = couchbaseClient.getView("JSONDocument",
"by_name");
                     Query query = new Query();
                     query.setIncludeDocs(true).setLimit(20);
                     query.setStale(Stale.FALSE);
                     ViewResponse result = couchbaseClient.query(view, query);
                       map = result.getMap();
                     cluster = HFactory.getOrCreateCluster("migration-cluster",
                     "localhost:9160");
                     KeyspaceDefinition keyspaceDef = cluster
                     .describeKeyspace("MigrationKeyspace");
                     if (keyspaceDef == null) {
                     createSchema();
                     }
                     createKeyspace();
                     createTemplate();
                      migrate();
                      retrieveTableData();
             } catch (IOException e) {
                     e.printStackTrace();
             }
      }
      private static void migrate() {
             Mutator<String> mutator = HFactory.createMutator(keyspace,
                    StringSerializer.get());
             for (java.util.Map.Entry<String, Object> entry : map.entrySet()) {
                    System.out.println(entry.getKey());
 
                    System.out.println(entry.getValue());
                    JSONObject json = (JSONObject) JSONSerializer.toJSON(entry
                    .getValue().toString());
                    Set set = json.keySet();
                    Iterator iter = set.iterator();
                    while (iter.hasNext()) {
                            Object obj = iter.next();
                            mutator = mutator.addInsertion(
                                   entry.getKey().toString(),
                                   "catalog",
                                   HFactory.createStringColumn(obj.toString(),
                                   json.get(obj.toString()).toString()));
                     }
              }
       System.out.println(mutator.execute().getHostUsed());
       }
       private static void createSchema() {
              int replicationFactor = 1;
              ColumnFamilyDefinition cfDef = HFactory.createColumnFamily
Definition(
                     "MigrationKeyspace", "catalog", ComparatorType.BYTESTYPE);
              KeyspaceDefinition keyspace = HFactory.createKeyspaceDefinition(
                     "MigrationKeyspace", ThriftKsDef.DEF_STRATEGY_CLASS,
                            replicationFactor, Arrays.asList(cfDef));
              cluster.addKeyspace(keyspace, true);
       }
       private static void createKeyspace() {
              keyspace = HFactory.createKeyspace("MigrationKeyspace", cluster);
       }
       private static void createTemplate() {
              template = new ThriftColumnFamilyTemplate<String, String>
(keyspace,
                             "catalog", StringSerializer.get(),
StringSerializer.get());
       }
       private static void retrieveTableData() {
              try {
                      ColumnFamilyResult<String, String> res = template
                      .queryColumns("catalog");
                      String journal = res.getString("journal");
                      String publisher = res.getString("publisher");
                      String edition = res.getString("edition");
                      String title = res.getString("title");
                      String author = res.getString("author");
                      System.out.println(journal);
                      System.out.println(publisher);
                      System.out.println(edition);
                      System.out.println(title);
                      System.out.println(author);
                } catch (HectorException e) {
                }
        }
}

Run the CouchbaseToCassandra application in the Eclipse IDE. Right-click CouchbaseToCassandra and select Run As > Java Application, as shown in Figure 8.17.

Figure 8.17
Running the CouchbaseToCassandra application.

Images

Source: Eclipse Foundation.

The JSON document from Couchbase Server is migrated to Cassandra. Subsequently, the Cassandra table created for the migrated JSON document is output in the Eclipse IDE, as shown in Figure 8.18.

Figure 8.18
JSON data migrated from Couchbase to Cassandra.

Images

Source: Eclipse Foundation.

SUMMARY

In this chapter, you migrated a JSON document from Couchbase Server to a Cassandra database table. First you created a JSON document in Couchbase. Then you used a Java client for Couchbase to access the Couchbase database and get the JSON document. Finally, you used the Hector Java client to connect to Cassandra and transfer the JSON data got from Couchbase to the Cassandra database. The next chapter discusses using Cassandra with Kundera.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.144.248