Created
November 15, 2011 23:36
-
-
Save randysecrist/1368756 to your computer and use it in GitHub Desktop.
java client - secondary index integration test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.util.List; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import junit.framework.TestCase; | |
import com.basho.riak.client.IRiakObject; | |
import com.basho.riak.client.builders.RiakObjectBuilder; | |
import com.basho.riak.client.query.indexes.BinIndex; | |
import com.basho.riak.client.raw.RawClient; | |
import com.basho.riak.client.raw.RiakResponse; | |
import com.basho.riak.client.raw.StoreMeta; | |
import com.basho.riak.client.raw.query.indexes.BinRangeQuery; | |
import com.basho.riak.client.raw.query.indexes.IndexQuery; | |
public class SecondaryIndexIntegTest extends TestCase { | |
protected static Logger log; | |
protected RawClient raw_client = null; | |
static { | |
log = LoggerFactory.getLogger(SecondaryIndexIntegTest.class); | |
} | |
protected void setUp() throws Exception { | |
super.setUp(); | |
String host = "127.0.0.1"; | |
/* PB Stats (2I using M/R) | |
INFO 2011-11-16 10:03:26,773 (SecondaryIndexIntegTest.java:testRiak:90)[main] ~Insert Time: 0:01:53, seconds | |
INFO 2011-11-16 10:03:26,774 (SecondaryIndexIntegTest.java:testRiak:91)[main] ~Query Time: 0:00:14, seconds | |
INFO 2011-11-16 10:03:26,774 (SecondaryIndexIntegTest.java:testRiak:92)[main] ~Delete Time: 0:02:40, seconds | |
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 289.11 sec | |
int port = 8081; | |
com.basho.riak.pbc.RiakClient r_client = new com.basho.riak.pbc.RiakClient(host, port); | |
raw_client = new com.basho.riak.client.raw.pbc.PBClientAdapter(r_client); | |
*/ | |
/* HTTP Stats (2I using HTTP API) | |
INFO 2011-11-16 10:14:53,312 (SecondaryIndexIntegTest.java:testRiak:95)[main] ~Insert Time: 0:04:42, seconds | |
INFO 2011-11-16 10:14:53,313 (SecondaryIndexIntegTest.java:testRiak:96)[main] ~Query Time: 0:00:00, seconds | |
INFO 2011-11-16 10:14:53,313 (SecondaryIndexIntegTest.java:testRiak:97)[main] ~Delete Time: 0:05:30, seconds | |
*/ | |
int port = 8091; | |
raw_client = new com.basho.riak.client.raw.http.HTTPClientAdapter("http://" + host + ":" + port + "/riak"); | |
} | |
protected void tearDown() throws Exception { | |
super.tearDown(); | |
} | |
/* Use this in the event that the query results don't match up to the | |
* inputs, and the bucket is not deleted. (Can use this to fine too a 2I | |
* query). | |
* | |
public void testQuery() throws IOException { | |
String bucket = "test6"; | |
String index = "execution_time"; | |
long range = 50000; | |
long decrementor = 60000; | |
// INFO 2011-11-11 16:38:14,213 (KeyTest.java:testRiak:82)[main] ~Insert / Query Time: 2011-11-11 16:38:14.205 MST::1321054694205 | |
Time query_time = new Time(1321052101640L); | |
List<String> results = queryIndex(range, query_time.add(-(decrementor * range)), bucket, index, raw_client); | |
for (int i = 0; i < results.size(); i++) { | |
log.info("Result: " + i + "::" + results.get(i)); | |
} | |
} | |
*/ | |
public void testRiak() throws IOException { | |
String bucket = "test"; | |
String index = "execution_time"; | |
long range = 50000; | |
long decrementor = 60000; | |
Time start = new Time(); Time insert_time = new Time(start); Time query_time = new Time(start); | |
log.info("Insert / Query Time:\t" + insert_time.toString() + "::" + insert_time.toOrderableString()); | |
for (int i = 0; i < range; i++) { | |
insertKey(i, bucket, index, insert_time.add(-(i * decrementor)), raw_client); | |
} | |
long inserts_finish = System.currentTimeMillis(); | |
List<String> results = queryIndex(range, query_time.add(-(decrementor * range)), bucket, index, raw_client); | |
long query_finish = System.currentTimeMillis(); | |
assertNotNull(results); | |
assertEquals(range, results.size()); | |
for (String s : results) { | |
log.info("Deleting Query Match: " + s); | |
raw_client.delete(bucket, s); | |
} | |
long delete_finish = System.currentTimeMillis(); | |
String insert_result = Time.getTimeString(inserts_finish - start.getTime(), Time.SECONDS); | |
String query_result = Time.getTimeString(query_finish - inserts_finish, Time.SECONDS); | |
String delete_result = Time.getTimeString(delete_finish - query_finish, Time.SECONDS); | |
log.info("Insert Time: " + insert_result + ", seconds"); | |
log.info("Query Time: " + query_result + ", seconds"); | |
log.info("Delete Time: " + delete_result + ", seconds"); | |
} | |
public void testFetchKey() throws IOException { | |
String bucket = "test"; | |
String key = "foo"; String value = "bar"; | |
IRiakObject riakObject = RiakObjectBuilder.newBuilder(bucket, key) | |
.withValue(value) | |
.withContentType("text/plain").build(); | |
raw_client.store(riakObject); | |
RiakResponse fetched = raw_client.fetch(bucket, key); | |
IRiakObject result = null; | |
if (fetched.hasValue()) { | |
if (fetched.hasSiblings()) { | |
//do what you must to resolve conflicts | |
throw new RuntimeException("Unhandled conflict!"); | |
} | |
else { | |
result = fetched.getRiakObjects()[0]; | |
} | |
} | |
assertEquals("bar", result.getValueAsString()); | |
raw_client.delete(bucket, "foo"); | |
} | |
private List<String> queryIndex(long range, Time then, String bucket, String index, RawClient client) throws IOException { | |
BinIndex b_index = BinIndex.named(index); | |
Time now = new Time(); | |
String from = then.toOrderableString(); | |
String to = now.toOrderableString(); | |
IndexQuery q = new BinRangeQuery(b_index, bucket, from, to); | |
List<String> results = client.fetchIndex(q); | |
return results; | |
} | |
private void insertKey(int i, String bucket, String index, Time t, RawClient client) throws IOException { | |
String key = "k" + i; | |
String value = "v" + i; | |
IRiakObject riakObject = RiakObjectBuilder.newBuilder(bucket, key) | |
.withValue(value) | |
.withContentType("text/plain").build(); | |
// Add Indexes | |
riakObject.addIndex(index, t.toOrderableString()); | |
log.info("Adding Key: " + i + ",\t" + t); | |
client.store(riakObject, new StoreMeta(1, 1, 0, false, false, false, false)); | |
} | |
} | |
import java.lang.ref.SoftReference; | |
import java.math.BigInteger; | |
import java.text.DateFormat; | |
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
import java.util.GregorianCalendar; | |
import java.util.Locale; | |
import java.util.TimeZone; | |
public class Time extends Date { | |
/** | |
* The Serial Ver UID | |
*/ | |
private static final long serialVersionUID = 3618696383679641145L; | |
public static final long NANO = 1L; | |
public static final long NANO_MILI = NANO * 1000000; | |
public static final long MILI = 1L; | |
public static final long SECONDS = MILI * 1000; | |
public static final long MINUTES = 60L * SECONDS; | |
public static final long HOURS = 60L * MINUTES; | |
public static final long DAYS = 24L * HOURS; | |
public static final long WEEKS = 7L * DAYS; | |
public static final String FORMAT = "yyyy-MM-dd HH:mm:ss.SSS z"; | |
/** | |
* Caches for the DateFormatters used by toString method. | |
*/ | |
private static SoftReference<DateFormat> simpleFormatter; | |
/** | |
* Always set the time to the current System Time. | |
*/ | |
public Time() { | |
this.setTime(System.currentTimeMillis()); | |
} | |
public Time(Date d) { | |
if (d != null) { | |
this.setTime(d.getTime()); | |
} | |
} | |
public Time(long millis) { | |
setTime(millis); | |
} | |
/** | |
* Returns a new instance of Time where x milliseconds | |
* have been added. | |
* | |
* @param x The number of milliseconds to add to the Time. | |
* @return A new Time object offset by x milliseconds. | |
*/ | |
public Time add(long x) { | |
return new Time(getTime() + x); | |
} | |
/** | |
* Returns a new instance of Time where x Gregorian calendar months | |
* have been added. | |
* | |
* @param months The number of months to add to the Time. | |
* @return A new Time object offset by x months. | |
*/ | |
public Time addMonths(int months) { | |
GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(); | |
cal.setTime(this); | |
cal.add(GregorianCalendar.MONTH, months); | |
Time newTime = new Time(cal.getTime()); | |
return newTime; | |
} | |
/** | |
* Increments the current Time by x milliseconds. | |
* @param x The number of milliseconds to increase the current time by. | |
* @return The current time + x milliseconds. | |
*/ | |
public Time increment(long x) { | |
setTime(getTime() + x); | |
return this; | |
} | |
/** | |
* Decrements the current Time by x milliseconds. | |
* @param x The number of milliseconds to decrease the current time by. | |
* @return The current time - x milliseconds. | |
*/ | |
public Time decrement(long x) { | |
setTime(getTime() - x); | |
return this; | |
} | |
/** | |
* Converts this <code>Time</code> object to a <code>String</code> | |
* of the form: | |
* <blockquote><pre> | |
* yyyy-MM-dd HH:mm:ss.S z</pre></blockquote> | |
* where:<ul> | |
* | |
* <li><tt>yyyy</tt> is the year, as four decimal digits. | |
* <li><tt>MM</tt> month within the year (<tt>0</tt> through | |
* <tt>12</tt>), as two decimal digits. | |
* <li><tt>dd</tt> is the day of the month (<tt>01</tt> through | |
* <tt>31</tt>), as two decimal digits. | |
* <li><tt>HH</tt> is the hour of the day (<tt>00</tt> through | |
* <tt>23</tt>), as two decimal digits. | |
* <li><tt>mm</tt> is the minute within the hour (<tt>00</tt> through | |
* <tt>59</tt>), as two decimal digits. | |
* <li><tt>ss</tt> is the second within the minute (<tt>00</tt> through | |
* <tt>61</tt>, as two decimal digits. | |
* <li><tt>S</tt> is the milisecondsecond within the second (<tt>000</tt> through | |
* <tt>999</tt>, as three decimal digits. | |
* <li><tt>z</tt> is the time zone (and may reflect daylight saving | |
* time). Standard time zone abbreviations include those | |
* recognized by the method <tt>parse</tt>. If time zone | |
* information is not available, then <tt>zzz</tt> is empty - | |
* that is, it consists of no characters at all. | |
* </ul> | |
* | |
* @return a string representation of this time. | |
*/ | |
public String toString() { | |
DateFormat formatter = null; | |
if (simpleFormatter != null) { | |
formatter = (DateFormat) simpleFormatter.get(); | |
} | |
if (formatter == null) { | |
/* No cache yet, or cached formatter GC'd */ | |
formatter = new SimpleDateFormat(FORMAT, Locale.US); | |
simpleFormatter = new SoftReference<DateFormat>(formatter); | |
} | |
synchronized (formatter) { | |
formatter.setTimeZone(TimeZone.getDefault()); | |
return formatter.format(this); | |
} | |
} | |
public String toOrderableString() { | |
return Long.toString(getTime()); | |
} | |
public boolean isLaterThan(Time time) { | |
return getTime() > time.getTime(); | |
} | |
public boolean isLaterThanOrEqualTo(Time time) { | |
return getTime() >= time.getTime(); | |
} | |
public boolean isEarlierThan(Time time) { | |
return getTime() < time.getTime(); | |
} | |
public boolean isEarlierThanOrEqualTo(Time time) { | |
return getTime() <= time.getTime(); | |
} | |
public boolean isLaterThan(long ms) { | |
return getTime() > ms; | |
} | |
public boolean isLaterThanOrEqualTo(long ms) { | |
return getTime() >= ms; | |
} | |
public boolean isEarlierThan(long ms) { | |
return getTime() < ms; | |
} | |
public boolean isEarlierThanOrEqualTo(long ms) { | |
return getTime() <= ms; | |
} | |
public boolean equals(Time t) { | |
return getTime() == t.getTime(); | |
} | |
public boolean equals(long ms) { | |
return getTime() == ms; | |
} | |
public int hashCode() { | |
return super.hashCode(); | |
} | |
/** | |
* Converts a time-span represented in miliseconds into a human readable format with variable degrees of precision. | |
* | |
* @parameter millis a long representing the number of miliseconds in the time-span. | |
* @parameter precisionLevel Determines how percise the resulting string is. Possible values: (minutes | seconds | miliseconds). | |
* @returns a human readable string indicating the length of time represented by millis | |
*/ | |
public static String getTimeString(long millis, long precision) { | |
// I admit it this is an ugly time string. I, or you, will make it pretty later. | |
StringBuffer buffer = new StringBuffer(); | |
BigInteger biggie = new BigInteger(String.valueOf(millis)); | |
BigInteger hour = biggie.divide(new BigInteger("3600000")); | |
biggie = biggie.mod(new BigInteger("3600000")); | |
BigInteger minutes = biggie.divide(new BigInteger("60000")); | |
biggie = biggie.mod(new BigInteger("60000")); | |
BigInteger seconds = biggie.divide(new BigInteger("1000")); | |
biggie = biggie.mod(new BigInteger("1000")); | |
// no matter what they get hours and minutes | |
buffer.append(hour.toString()); | |
if (precision == HOURS) { | |
return buffer.toString(); | |
} | |
buffer.append(":"); | |
if (minutes.intValue() < 10) { | |
buffer.append("0"); | |
} | |
buffer.append(minutes.toString()); | |
if ((precision == SECONDS) || (precision == MILI)) { | |
buffer.append(":"); | |
if (seconds.intValue() < 10) { | |
buffer.append("0"); | |
} | |
buffer.append(seconds.toString()); | |
} | |
if (precision == MILI) { | |
buffer.append(":"); | |
if (biggie.intValue() < 100) { | |
buffer.append("0"); | |
} | |
if (biggie.intValue() < 10) { | |
buffer.append("0"); | |
} | |
buffer.append(biggie.toString()); | |
} | |
return buffer.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment