Apache Cassandra Learning Step (5): Actual Jtwissandra Project-it

Source: Internet
Author: User
Keywords Nbsp; fact name lowe java

After completing the four basic learning steps of Apache Cassandra, you can try the actual code.

If necessary, we suggest a brief review:

Apache Cassandra Learning Step with step (1)

Apache Cassandra Learning Step by Step (2): Core Concepts

Apache Cassandra Learning Step by Step (3): Samples ABC

Apache Cassandra Learning Step by Step (4): Data Modeling

Based on the 4th model of thinking, the next thing we have to do is to build a real project called Jtwissandra, is the so-called Java version of the Twissandra.

The goal is to use Twitter as a hypothetical object, using the simplest (or straightforward) modeling and implementation, expressed the use of Apache Cassandra as a nosql platform of the basic implementation process.

Jtwissandra Basic Coding Environment:

1. Maven to manage

2. JUnit to test

3. Java clients based on Hector client as Apache Cassandra

You can directly clone out the latest code through the following GitHub links:

Jtwissandra:https://github.com/itstarting/jtwissandra

Also welcome everyone fork or here directly to the brick--anyway, I am a novice in NoSQL, thick-skinned point does not matter:

1. First you need a hfactoryhelper to initialize and establish the Cassandra Client connection pool and the necessary objects:

Import java.io.IOException;

Import java.util.Properties;

Import Me.prettyprint.cassandra.model.ConfigurableConsistencyLevel;

Import Me.prettyprint.hector.api.Cluster;

Import Me.prettyprint.hector.api.HConsistencyLevel;

Import Me.prettyprint.hector.api.Keyspace;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;

/**

* Helper for Cassandra initialization

*

* @author Bright_zheng

*

*/

public class Hfactoryhelper {

private static Logger Logger = Loggerfactory.getlogger (Hfactoryhelper.class);

private static Cluster Cluster;

private static Keyspace Keyspace = Initkeyspace ();

private static properties properties;

Private Hfactoryhelper () {}

public static Keyspace Getkeyspace () {

return keyspace;

}

private static Keyspace Initkeyspace () {

Properties = new properties ();

try {

Properties.load (HFactoryHelper.class.getResourceAsStream ("/config.properties"));

catch (IOException IoE) {

Ioe.printstacktrace ();

}

String cluster_name = Properties.getproperty ("Cluster.name", "Test cluster");

Logger.debug ("cluster.name={}", cluster_name);

String cluster_hosts = Properties.getproperty ("cluster.hosts", "127.0.0.1:9160");

Logger.debug ("cluster.hosts={}", cluster_hosts);

String active_keyspace = Properties.getproperty ("Keyspace", "Jtwissandra");

Logger.debug ("keyspace={}", Active_keyspace);

Cluster = Hfactory.getorcreatecluster (cluster_name, cluster_hosts);

Configurableconsistencylevel CCL = new Configurableconsistencylevel ();

Ccl.setdefaultreadconsistencylevel (Hconsistencylevel.one);

Return Hfactory.createkeyspace (

Active_keyspace,

Cluster,

CCL);

}

}

2. Establish the base class Baseservice of various business services.

Import Java.util.UUID;

Import Me.prettyprint.cassandra.serializers.LongSerializer;

Import Me.prettyprint.cassandra.serializers.StringSerializer;

Import me.prettyprint.cassandra.service.clock.MicrosecondsClockResolution;

Import Me.prettyprint.cassandra.utils.TimeUUIDUtils;

Import me.prettyprint.hector.api.ClockResolution;

Import Me.prettyprint.hector.api.Keyspace;

Import Me.prettyprint.hector.api.beans.HColumn;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;

Import Bright.zheng.jtwissandra.HFactoryHelper;

/**

* Base service abound all business services should extend

*

* @author Bright_zheng

*

*/

public class Baseservice {

protected Logger Logger = Loggerfactory.getlogger (GetClass ());

protected static Keyspace Keyspace = Hfactoryhelper.getkeyspace ();

Protected static final String Cf_user = "USER";

Protected static final String cf_friend = "FRIEND";

Protected static final String Cf_follower = "FOLLOWER";

Protected static final String Cf_tweet = "TWEET";

Protected static final String Cf_timeline = "TIMELINE";

Protected static final Stringserializer serializer_string

= Stringserializer.get ();

Protected static final Longserializer Serializer_long

= Longserializer.get ();

protected static final int tweets_limit_default = 10;

protected static final int tweets_limit_max = 50;

Protected Hcolumn<string, string> createcolumn (string name, String value) {

Return Hfactory.createcolumn (name, value, serializer_string, serializer_string);

}

Protected Hcolumn<string, long> createcolumn (String name, Long value) {

Return Hfactory.createcolumn (name, value, serializer_string, Serializer_long);

}

Protected Hcolumn<long, string> createcolumn (Long name, String value) {

Return Hfactory.createcolumn (name, value, Serializer_long, serializer_string);

}

/**

* Ref:http://wiki.apache.org/cassandra/faq#working_with_timeuuid_in_java

*

* @return UUID

*/

Public UUID Getuuid () {

Todo:which UUID should we make throaty it's unique?

Clockresolution Clock = new Microsecondsclockresolution ();

return timeuuidutils.gettimeuuid (clock);

return Timeuuidutils.getuniquetimeuuidinmillis ();

}

Protected Long Gettimestamp (uuid uuid) {

return Uuid.timestamp ();

return Timeuuidutils.gettimefromuuid (UUID);

}

Protected Long Generatetimestamp () {

Return Gettimestamp (Getuuid ());

}

}

3. The following are the business service codes:

3.1 UserService

Package bright.zheng.jtwissandra.service;

Import Java.util.UUID;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Me.prettyprint.hector.api.mutation.Mutator;

Import Bright.zheng.jtwissandra.bean.User;

/**

* User Service

*

* @author Bright_zheng

*

*/

public class UserService extends baseservice{

/**

* Sample CLI cmd:

* Set user[' 550e8400-e29b-41d4-a716-446655440000 ' [' user_name '] = ' itstarting ';

* Set user[' 550e8400-e29b-41d4-a716-446655440000 ' [' password '] = ' 111222 ';

* Set user[' 550e8400-e29b-41d4-a716-446655440000 ' [' create_timestamp '] = 1329836819890000;

*

* @param user

*/

Public String addUser (user user) {

mutator<string> Mutator = Hfactory.createmutator (

Keyspace, serializer_string);

UUID uuid = This.getuuid ();

String User_uuid = uuid.tostring ();

Long Create_timestamp = This.gettimestamp (UUID);

Logger.debug ("user_uuid={}", User_uuid);

Logger.debug ("user_name={}", User.getuser_name ());

Logger.debug ("password={}", User.getuser_password ());

Logger.debug ("create_timestamp={}", Create_timestamp);

Mutator.addinsertion (User_uuid, Cf_user,

This.createcolumn ("user_name", User.getuser_name ());

Mutator.addinsertion (User_uuid, Cf_user,

This.createcolumn ("Password", User.getuser_password ());

Mutator.addinsertion (User_uuid, Cf_user,

This.createcolumn ("Create_timestamp", Create_timestamp));

Mutator.execute ();

Return the generated UUID

return user_uuid;

}

}

3.2 Friendservice

Package bright.zheng.jtwissandra.service;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Me.prettyprint.hector.api.mutation.MutationResult;

Import Me.prettyprint.hector.api.mutation.Mutator;

/**

* Friend Service

*

* @author Bright_zheng

*

*/

public class Friendservice extends baseservice{

/**

* Adding a friend super-delegates nonblank business logic:

* 1. Add the friend ' s UUID to the friend CF under my UUID

* 2. Add my uuid to the friend ' s UUID as follower

*

* Set friend[' 550e8400-e29b-41d4-a716-446655440000 ' [' 1329836819859000 ']

* = ' 550e8400-e29b-41d4-a716-446655440001;

*

* Set follower[' 550e8400-e29b-41d4-a716-446655440001 '] [' 1329836819859000 ']

* = ' 550e8400-e29b-41d4-a716-446655440000;

*

* @param me

* @param friend

*/

Public Mutationresult Followfriend (string me, string friend) {

mutator<string> Mutator = Hfactory.createmutator (

Keyspace, serializer_string);

Long timestamp = This.generatetimestamp ();

Logger.debug ("timestamp={}", timestamp);

Mutator.addinsertion (Me, Cf_friend,

This.createcolumn (timestamp, friend));

Mutator.addinsertion (friend, Cf_follower,

This.createcolumn (timestamp, ME));

return Mutator.execute ();

}

}

3.3 Timelineservice

Package bright.zheng.jtwissandra.service;

Import java.util.ArrayList;

Import Java.util.Iterator;

Import java.util.List;

Import Me.prettyprint.hector.api.beans.ColumnSlice;

Import Me.prettyprint.hector.api.beans.HColumn;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Me.prettyprint.hector.api.query.QueryResult;

Import Me.prettyprint.hector.api.query.SliceQuery;

Import Bright.zheng.jtwissandra.bean.Timeline;

/**

* Timeline Service

*

* @author Bright_zheng

*

*/

public class Timelineservice extends baseservice{

/**

* Get specified user ' s Timeline

*

* @param user_uuid

* @return

*/

Public Timelinewrapper gettimeline (String user_uuid) {

Return Gettimeline (User_uuid, 0L, Tweets_limit_default);

}

/**

* Get specified user's Timeline with the start point

*

* @param user_uuid

* @param start

* @return

*/

Public Timelinewrapper gettimeline (String user_uuid, long start) {

Return Gettimeline (User_uuid, start, tweets_limit_default);

}

/**

* Get specified user's Timeline with the start point and limit

*

* @param user_uuid

* @param start

* @param limit

* @return

*/

Public Timelinewrapper gettimeline (String user_uuid, long start, int limit) {

if (start<0) start = 0;

if (limit<0) limit = Tweets_limit_default;

if (limit>tweets_limit_max) limit = Tweets_limit_max;

Slicequery<string, Long, string> slicequery =

Hfactory.createslicequery (Keyspace, serializer_string, Serializer_long, serializer_string);

Slicequery.setcolumnfamily (Cf_timeline);

Slicequery.setkey (USER_UUID);

Slicequery.setrange (Start, Long.max_value, False, limit+1);

Queryresult<columnslice<long, string>> result = Slicequery.execute ();

List<hcolumn<long, string>> list = Result.get (). GetColumns ();

Long next = 0L;

if (list==null) {

return new Timelinewrapper (null, next);

}else if (list.size () <=limit) {

return new Timelinewrapper (Converttotimeline (list), 0L);

}else{

Hcolumn<long,string> last = List.get (List.size ()-1);

Next = Last.getname (); The name is the timestamp as the "next" start

List.remove (List.size ()-1);

Return to New Timelinewrapper (Converttotimeline (list), next);

}

}

Private list<timeline> Converttotimeline (list<hcolumn<long,string>> cols) {

Iterator<hcolumn<long,string>> it = Cols.iterator ();

list<timeline> result = new arraylist<timeline> ();

while (It.hasnext ()) {

hcolumn<long,string> col = It.next ();

Result.add (New Timeline (Col.getvalue (), Col.getname ()));

}

return result;

}

public class timelinewrapper{

Private list<timeline> timelines;

Private long nexttimeline;

Public Timelinewrapper (list<timeline> timelines, long Nexttimeline) {

This.timelines = timelines;

This.nexttimeline = Nexttimeline;

}

Public long Getnexttimeline () {

return nexttimeline;

}

Public list<timeline> Gettimelines () {

return timelines;

}

}

}

3.4 Tweetservice

Package bright.zheng.jtwissandra.service;

Import java.util.ArrayList;

Import Java.util.Iterator;

Import java.util.List;

Import Java.util.UUID;

Import Me.prettyprint.hector.api.beans.ColumnSlice;

Import Me.prettyprint.hector.api.beans.HColumn;

Import Me.prettyprint.hector.api.beans.Row;

Import Me.prettyprint.hector.api.beans.Rows;

Import Me.prettyprint.hector.api.factory.HFactory;

Import Me.prettyprint.hector.api.mutation.Mutator;

Import Me.prettyprint.hector.api.query.MultigetSliceQuery;

Import Me.prettyprint.hector.api.query.QueryResult;

Import Me.prettyprint.hector.api.query.SliceQuery;

Import Bright.zheng.jtwissandra.bean.Tweet;

/**

* Tweet Service

*

* @author Bright_zheng

*

*/

public class Tweetservice extends baseservice{

/**

* Adding a tweet super-delegates following logic:

* 1. Save the tweet to CF

* 2. Add the new tweet to my TIMELINE

* 3. Add the new tweet to all my followers ' TIMELINE

*

* @param me

* @param friend

*/

public string Addtweet (string user_uuid, String tweet_content) {

mutator<string> Mutator = Hfactory.createmutator (

Keyspace, serializer_string);

The tweet UUID

UUID uuid = This.getuuid ();

String Tweet_uuid = uuid.tostring ();

Logger.debug ("tweet_uuid={}", Tweet_uuid);

The timestamp to build the timeline

Long timestamp = This.gettimestamp (UUID);

Logger.debug ("timestamp={}", timestamp);

Mutator.addinsertion (Tweet_uuid, Cf_tweet,

This.createcolumn ("User_uuid", User_uuid));

Mutator.addinsertion (Tweet_uuid, Cf_tweet,

This.createcolumn ("Tweet_content", tweet_content));

Mutator.addinsertion (User_uuid, Cf_timeline,

This.createcolumn (timestamp, tweet_uuid));

Get follower and insert the tweets to his/her TIMELINE

Slicequery<string, Long, string> slicequery =

Hfactory.createslicequery (Keyspace, serializer_string, Serializer_long, serializer_string);

Slicequery.setcolumnfamily (Cf_follower);

Slicequery.setkey (USER_UUID);

Slicequery.setrange (Long.min_value, Long.max_value, false, 500); Todo:500 followers hard code here?

Queryresult<columnslice<long, string>> result = Slicequery.execute ();

Iterator<hcolumn<long, string>> followers = Result.get (). GetColumns (). iterator ();

while (Followers.hasnext ()) {

Hcolumn<long, string> follower = Followers.next ();

String Follower_uuid = Follower.getvalue ();

Logger.debug ("Follower ' s uuid={}", Follower_uuid);

Logger.debug ("timestamp={}", Follower.getname ());

Insert the tweet to the follower ' s TIMELINE

Mutator.addinsertion (Follower_uuid, Cf_timeline,

This.createcolumn (timestamp, tweet_uuid));

}

Mutator.execute ();

Return the new generated tweet ' s UUID

return tweet_uuid;

}

/**

* Should We add this service?

*

* @param tweet_uuid

* @return

*/

Public Tweet Gettweet (String tweet_uuid) {

return null;

}

Public list<tweet> gettweets (list<string> tweet_uuids) {

Multigetslicequery<string, String, string> multigetslicesquery =

Hfactory.createmultigetslicequery (Keyspace, serializer_string, serializer_string, SERIALIZER_STRING);

Multigetslicesquery.setcolumnfamily (Cf_tweet);

Multigetslicesquery.setcolumnnames ("User_uuid", "tweet_content");

Multigetslicesquery.setkeys (Tweet_uuids);

Queryresult<rows<string, String, string>> results = Multigetslicesquery.execute ();

Return Convertrowstotweets (Results.get ());

}

Private list<tweet> convertrowstotweets (rows<string, String, string> Rows) {

list<tweet> list = new arraylist<tweet> ();

Iterator<row<string, String, string>> iterator = Rows.iterator ();

while (Iterator.hasnext ()) {

Row<string, String, string> row = Iterator.next ();

columnslice<string, String> cs = Row.getcolumnslice ();

List.add (New Tweet (Row.getkey),

Cs.getcolumnbyname ("Tweet_content"). GetValue (),

Cs.getcolumnbyname ("User_uuid"). GetValue ());

}

return list;

}

}

4. Of course, there are junit test cases:

Package Bright.zheng.jtwissandra;

Import java.util.ArrayList;

Import Java.util.Iterator;

Import java.util.List;

Import Junit.framework.Assert;

Import Org.junit.AfterClass;

Import Org.junit.BeforeClass;

Import Org.junit.Test;

Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;

Import Bright.zheng.jtwissandra.bean.Timeline;

Import Bright.zheng.jtwissandra.bean.Tweet;

Import Bright.zheng.jtwissandra.bean.User;

Import Bright.zheng.jtwissandra.service.FriendService;

Import Bright.zheng.jtwissandra.service.TimelineService;

Import Bright.zheng.jtwissandra.service.TimelineService.TimelineWrapper;

Import Bright.zheng.jtwissandra.service.TweetService;

Import Bright.zheng.jtwissandra.service.UserService;

/**

* Test cases for all services currently provided.

* Please drop and create schema-I-then run all cases as one round

* the ' Me ' and ' friend ' would be created each round dynamically for easier testing

*

* @author Bright_zheng

*

*/

public class servicetest{

Logger Logger = Loggerfactory.getlogger (Servicetest.class);

private static UserService Service_user = new UserService ();

private static Friendservice Service_friend = new Friendservice ();

private static Tweetservice Service_tweet = new Tweetservice ();

private static Timelineservice Service_timeline = new Timelineservice ();

private static String me;

private static String friend;

private static long nexttimeline = 0L;

@BeforeClass

public static void SetUp () {

//

}

@Test

public void AddUser () {

Logger.debug ("=====================adduser{====================");

Add User 1

me = Service_user.adduser (new USER ("itstarting", "1234"));

Logger.debug ("This round of Tesing, me={}", ME);

Assert.assertnotnull (Me);

Add User 2

Friend = Service_user.adduser (new USER ("Test1", "1234"));

Logger.debug ("This round of Tesing, friend={}", FRIEND);

Assert.assertnotnull (friend);

Logger.debug ("=====================}//adduser====================");

}

/**

* I ' m following a friend

*/

@Test

public void Followfriend () {

Logger.debug ("=====================followfriend{====================");

Service_friend.followfriend (Me, FRIEND);

Logger.debug ("=====================}//followfriend====================");

}

/**

* I ' m followed by a follower

*/

@Test

public void Followedbyfollower () {

Logger.debug ("=====================followedbyfollower{====================");

Service_friend.followfriend (FRIEND, ME);

Logger.debug ("=====================}//followedbyfollower====================");

}

/**

* I ' m twittering

*/

@Test

public void Addtweetbyme () {

Logger.debug ("=====================addtweetbyme{====================");

for (int i=0; i<100; i++) {

String Tweet_uuid = Service_tweet.addtweet (Me, "Hellow Jtwissandra-by itstarting:" + i);

Assert.assertnotnull (TWEET_UUID);

}

Logger.debug ("=====================}//addtweetbyme====================");

}

/**

* My friend is Twittering

*

*/

@Test

public void Addtweetbyfriend () {

Logger.debug ("=====================addtweetbyfriend{====================");

for (int i=0; i<100; i++) {

String tweet_uuid = Service_tweet.addtweet (friend, "Hellow Jtwissandra-by test1:" + i);

Assert.assertnotnull (TWEET_UUID);

}

Logger.debug ("=====================}//addtweetbyfriend====================");

}

/**

* Get Twitter for me

*/

@Test

public void Gettweetsbyme () {

Logger.debug ("=====================gettweetsbyme{====================");

Gettweets (me, 0);

Logger.debug ("=====================}//gettweetsbyme====================");

}

/**

* Get tweets in next Timeline (if any)

*/

@Test

public void Gettweetsbymefornexttimeline () {

Logger.debug ("=====================gettweetsbymefornexttimeline{====================");

if (nexttimeline>0l) {

Gettweets (Me, nexttimeline);

}

Logger.debug ("=====================}//gettweetsbymefornexttimeline====================");

}

/**

* Get Twitter for my friend

*/

@Test

public void Gettweetsbymyfriend () {

Logger.debug ("=====================gettweetsbymyfriend{====================");

Gettweets (friend, 0);

Logger.debug ("=====================}//gettweetsbymyfriend====================");

}

/**

*

*/

@Test

public void Gettweetsbymyfriendfornexttimeline () {

Logger.debug ("=====================gettweetsbymyfriendfornexttimeline{====================");

Gettweets (friend, Nexttimeline);

Logger.debug ("=====================}//gettweetsbymyfriendfornexttimeline====================");

}

private void Gettweets (String user_uuid, long start) {

Timelinewrapper wrappers = Service_timeline.gettimeline (User_uuid, start);

Assert.assertnotnull (wrappers);

list<timeline> list = Wrapper.gettimelines ();

list<string> tweet_uuids = new arraylist<string> ();

for (Timeline timeline:list) {

String Tweet_uuid = Timeline.gettweet_uuid ();

Logger.debug ("From timeline:tweet_uuid={}, tweet_timestamp={}",

Tweet_uuid, Timeline.gettweet_timestamp ());

Tweet_uuids.add (TWEET_UUID);

}

list<tweet> tweets = service_tweet.gettweets (tweet_uuids);

Iterator<tweet> it = Tweets.iterator ();

while (It.hasnext ()) {

Tweet = It.next ();

Logger.debug ("From tweet:tweet_uuid={}, tweet_content={}, user_uuid={}",

New Object[]{tweet.gettweet_uuid (),

Tweet.gettweet_content (),

Tweet.getuser_uuid ()

});

}

if (Wrapper.getnexttimeline () > 0L) {

Logger.debug ("The Start Timeline of next page is: {}", Wrapper.getnexttimeline ());

Nexttimeline = Wrapper.getnexttimeline ();

}else{

Logger.debug ("No next page available");

Nexttimeline = 0L;

}

}

@AfterClass

public static void shutdown () {

Cluster.getconnectionmanager (). Shutdown ();

}

}

This is a Yiguoduan test case, run all at once to cover almost any business service logic.

5. Finally, don't forget to create the necessary schema before running:

Drop Keyspace Jtwissandra;

Create Keyspace Jtwissandra

with placement_strategy = ' org.apache.cassandra.locator.SimpleStrategy '

and strategy_options = [{replication_factor:1}];

Use Jtwissandra;

Create Column Accessibility USER

With comparator = Utf8type

and Key_validation_class = Utf8type

and Default_validation_class = Utf8type

and Column_metadata = [

{column_name:user_name, Validation_class:utf8type,

Index_name:user_name_idx, Index_type:keys}

{Column_name:user_password, Validation_class:utf8type}

{Column_name:create_timestamp, Validation_class:longtype,

Index_name:create_timestamp_idx, Index_type:keys}

];

Create Column Accessibility FRIEND

With comparator = Longtype

and Key_validation_class = Utf8type

and default_validation_class = Utf8type;

Create Column Accessibility FOLLOWER

With comparator = Longtype

and Key_validation_class = Utf8type

and default_validation_class = Utf8type;

Create Column Accessibility TWEET

With comparator = Utf8type

and Key_validation_class = Utf8type

and Default_validation_class = Utf8type

and Column_metadata = [

{Column

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.