diff --git a/bin/bindings.properties b/bin/bindings.properties
index 231a3a24..a2aeb9a6 100644
--- a/bin/bindings.properties
+++ b/bin/bindings.properties
@@ -1,69 +1,70 @@
#
# Copyright (c) 2012 - 2016 YCSB contributors. All rights reserved.
#
# 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
#
# 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. See accompanying
# LICENSE file.
#
#DATABASE BINDINGS
#
# Available bindings should be listed here in the form of
# name:class
#
# - the name must start in column 0.
# - the name is also the directory where the class can be found.
# - if the directory contains multiple versions with different classes,
# use a dash with the version. (e.g. cassandra-7, cassandra-cql)
#
accumulo:com.yahoo.ycsb.db.accumulo.AccumuloClient
aerospike:com.yahoo.ycsb.db.AerospikeClient
asynchbase:com.yahoo.ycsb.db.AsyncHBaseClient
arangodb:com.yahoo.ycsb.db.ArangoDBClient
arangodb3:com.yahoo.ycsb.db.arangodb.ArangoDB3Client
azuretablestorage:com.yahoo.ycsb.db.azuretablestorage.AzureClient
basic:com.yahoo.ycsb.BasicDB
cassandra-cql:com.yahoo.ycsb.db.CassandraCQLClient
cassandra2-cql:com.yahoo.ycsb.db.CassandraCQLClient
cloudspanner:com.yahoo.ycsb.db.cloudspanner.CloudSpannerClient
couchbase:com.yahoo.ycsb.db.CouchbaseClient
couchbase2:com.yahoo.ycsb.db.couchbase2.Couchbase2Client
azuredocumentdb:com.yahoo.ycsb.db.azuredocumentdb.AzureDocumentDBClient
dynamodb:com.yahoo.ycsb.db.DynamoDBClient
elasticsearch:com.yahoo.ycsb.db.ElasticsearchClient
geode:com.yahoo.ycsb.db.GeodeClient
googlebigtable:com.yahoo.ycsb.db.GoogleBigtableClient
googledatastore:com.yahoo.ycsb.db.GoogleDatastoreClient
hbase094:com.yahoo.ycsb.db.HBaseClient
hbase098:com.yahoo.ycsb.db.HBaseClient
hbase10:com.yahoo.ycsb.db.HBaseClient10
+hbase12:com.yahoo.ycsb.db.hbase12.HBaseClient12
hypertable:com.yahoo.ycsb.db.HypertableClient
infinispan-cs:com.yahoo.ycsb.db.InfinispanRemoteClient
infinispan:com.yahoo.ycsb.db.InfinispanClient
jdbc:com.yahoo.ycsb.db.JdbcDBClient
kudu:com.yahoo.ycsb.db.KuduYCSBClient
mapkeeper:com.yahoo.ycsb.db.MapKeeperClient
memcached:com.yahoo.ycsb.db.MemcachedClient
mongodb:com.yahoo.ycsb.db.MongoDbClient
mongodb-async:com.yahoo.ycsb.db.AsyncMongoDbClient
nosqldb:com.yahoo.ycsb.db.NoSqlDbClient
orientdb:com.yahoo.ycsb.db.OrientDBClient
rados:com.yahoo.ycsb.db.RadosClient
redis:com.yahoo.ycsb.db.RedisClient
rest:com.yahoo.ycsb.webservice.rest.RestClient
riak:com.yahoo.ycsb.db.riak.RiakKVClient
s3:com.yahoo.ycsb.db.S3Client
solr:com.yahoo.ycsb.db.solr.SolrClient
solr6:com.yahoo.ycsb.db.solr6.SolrClient
tarantool:com.yahoo.ycsb.db.TarantoolClient
voldemort:com.yahoo.ycsb.db.VoldemortClient
diff --git a/bin/ycsb b/bin/ycsb
index d454c6cb..7fb75180 100755
--- a/bin/ycsb
+++ b/bin/ycsb
@@ -1,302 +1,303 @@
#!/usr/bin/env python
#
# Copyright (c) 2012 - 2015 YCSB contributors. All rights reserved.
#
# 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
#
# 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. See accompanying
# LICENSE file.
#
import errno
import fnmatch
import io
import os
import shlex
import sys
import subprocess
try:
mod = __import__('argparse')
import argparse
except ImportError:
print >> sys.stderr, '[ERROR] argparse not found. Try installing it via "pip".'
exit(1)
BASE_URL = "https://github.com/brianfrankcooper/YCSB/tree/master/"
COMMANDS = {
"shell" : {
"command" : "",
"description" : "Interactive mode",
"main" : "com.yahoo.ycsb.CommandLine",
},
"load" : {
"command" : "-load",
"description" : "Execute the load phase",
"main" : "com.yahoo.ycsb.Client",
},
"run" : {
"command" : "-t",
"description" : "Execute the transaction phase",
"main" : "com.yahoo.ycsb.Client",
},
}
DATABASES = {
"accumulo" : "com.yahoo.ycsb.db.accumulo.AccumuloClient",
"aerospike" : "com.yahoo.ycsb.db.AerospikeClient",
"arangodb" : "com.yahoo.ycsb.db.ArangoDBClient",
"arangodb3" : "com.yahoo.ycsb.db.arangodb.ArangoDB3Client",
"asynchbase" : "com.yahoo.ycsb.db.AsyncHBaseClient",
"basic" : "com.yahoo.ycsb.BasicDB",
"cassandra-cql": "com.yahoo.ycsb.db.CassandraCQLClient",
"cassandra2-cql": "com.yahoo.ycsb.db.CassandraCQLClient",
"cloudspanner" : "com.yahoo.ycsb.db.cloudspanner.CloudSpannerClient",
"couchbase" : "com.yahoo.ycsb.db.CouchbaseClient",
"couchbase2" : "com.yahoo.ycsb.db.couchbase2.Couchbase2Client",
"azuredocumentdb" : "com.yahoo.ycsb.db.azuredocumentdb.AzureDocumentDBClient",
"dynamodb" : "com.yahoo.ycsb.db.DynamoDBClient",
"elasticsearch": "com.yahoo.ycsb.db.ElasticsearchClient",
"geode" : "com.yahoo.ycsb.db.GeodeClient",
"googlebigtable" : "com.yahoo.ycsb.db.GoogleBigtableClient",
"googledatastore" : "com.yahoo.ycsb.db.GoogleDatastoreClient",
"hbase094" : "com.yahoo.ycsb.db.HBaseClient",
"hbase098" : "com.yahoo.ycsb.db.HBaseClient",
"hbase10" : "com.yahoo.ycsb.db.HBaseClient10",
+ "hbase12" : "com.yahoo.ycsb.db.hbase12.HBaseClient12",
"hypertable" : "com.yahoo.ycsb.db.HypertableClient",
"infinispan-cs": "com.yahoo.ycsb.db.InfinispanRemoteClient",
"infinispan" : "com.yahoo.ycsb.db.InfinispanClient",
"jdbc" : "com.yahoo.ycsb.db.JdbcDBClient",
"kudu" : "com.yahoo.ycsb.db.KuduYCSBClient",
"mapkeeper" : "com.yahoo.ycsb.db.MapKeeperClient",
"memcached" : "com.yahoo.ycsb.db.MemcachedClient",
"mongodb" : "com.yahoo.ycsb.db.MongoDbClient",
"mongodb-async": "com.yahoo.ycsb.db.AsyncMongoDbClient",
"nosqldb" : "com.yahoo.ycsb.db.NoSqlDbClient",
"orientdb" : "com.yahoo.ycsb.db.OrientDBClient",
"rados" : "com.yahoo.ycsb.db.RadosClient",
"redis" : "com.yahoo.ycsb.db.RedisClient",
"rest" : "com.yahoo.ycsb.webservice.rest.RestClient",
"riak" : "com.yahoo.ycsb.db.riak.RiakKVClient",
"s3" : "com.yahoo.ycsb.db.S3Client",
"solr" : "com.yahoo.ycsb.db.solr.SolrClient",
"solr6" : "com.yahoo.ycsb.db.solr6.SolrClient",
"tarantool" : "com.yahoo.ycsb.db.TarantoolClient",
"voldemort" : "com.yahoo.ycsb.db.VoldemortClient"
}
OPTIONS = {
"-P file" : "Specify workload file",
"-p key=value" : "Override workload property",
"-s" : "Print status to stderr",
"-target n" : "Target ops/sec (default: unthrottled)",
"-threads n" : "Number of client threads (default: 1)",
"-cp path" : "Additional Java classpath entries",
"-jvm-args args" : "Additional arguments to the JVM",
}
def usage():
output = io.BytesIO()
print >> output, "%s command database [options]" % sys.argv[0]
print >> output, "\nCommands:"
for command in sorted(COMMANDS.keys()):
print >> output, " %s %s" % (command.ljust(14),
COMMANDS[command]["description"])
print >> output, "\nDatabases:"
for db in sorted(DATABASES.keys()):
print >> output, " %s %s" % (db.ljust(14), BASE_URL +
db.split("-")[0])
print >> output, "\nOptions:"
for option in sorted(OPTIONS.keys()):
print >> output, " %s %s" % (option.ljust(14), OPTIONS[option])
print >> output, """\nWorkload Files:
There are various predefined workloads under workloads/ directory.
See https://github.com/brianfrankcooper/YCSB/wiki/Core-Properties
for the list of workload properties."""
return output.getvalue()
# Python 2.6 doesn't have check_output. Add the method as it is in Python 2.7
# Based on https://github.com/python/cpython/blob/2.7/Lib/subprocess.py#L545
def check_output(*popenargs, **kwargs):
r"""Run command with arguments and return its output as a byte string.
If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
The arguments are the same as for the Popen constructor. Example:
>>> check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
The stdout argument is not allowed as it is used internally.
To capture standard error in the result, use stderr=STDOUT.
>>> check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
'ls: non_existent_file: No such file or directory\n'
"""
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
error = subprocess.CalledProcessError(retcode, cmd)
error.output = output
raise error
return output
def debug(message):
print >> sys.stderr, "[DEBUG] ", message
def warn(message):
print >> sys.stderr, "[WARN] ", message
def error(message):
print >> sys.stderr, "[ERROR] ", message
def find_jars(dir, glob='*.jar'):
jars = []
for (dirpath, dirnames, filenames) in os.walk(dir):
for filename in fnmatch.filter(filenames, glob):
jars.append(os.path.join(dirpath, filename))
return jars
def get_ycsb_home():
dir = os.path.abspath(os.path.dirname(sys.argv[0]))
while "LICENSE.txt" not in os.listdir(dir):
dir = os.path.join(dir, os.path.pardir)
return os.path.abspath(dir)
def is_distribution():
# If there's a top level pom, we're a source checkout. otherwise a dist artifact
return "pom.xml" not in os.listdir(get_ycsb_home())
# Run the maven dependency plugin to get the local jar paths.
# presumes maven can run, so should only be run on source checkouts
# will invoke the 'package' goal for the given binding in order to resolve intra-project deps
# presumes maven properly handles system-specific path separators
# Given module is full module name eg. 'core' or 'couchbase-binding'
def get_classpath_from_maven(module):
try:
debug("Running 'mvn -pl com.yahoo.ycsb:" + module + " -am package -DskipTests "
"dependency:build-classpath -DincludeScope=compile -Dmdep.outputFilterFile=true'")
mvn_output = check_output(["mvn", "-pl", "com.yahoo.ycsb:" + module,
"-am", "package", "-DskipTests",
"dependency:build-classpath",
"-DincludeScope=compile",
"-Dmdep.outputFilterFile=true"])
# the above outputs a "classpath=/path/tojar:/path/to/other/jar" for each module
# the last module will be the datastore binding
line = [x for x in mvn_output.splitlines() if x.startswith("classpath=")][-1:]
return line[0][len("classpath="):]
except subprocess.CalledProcessError, err:
error("Attempting to generate a classpath from Maven failed "
"with return code '" + str(err.returncode) + "'. The output from "
"Maven follows, try running "
"'mvn -DskipTests package dependency:build=classpath' on your "
"own and correct errors." + os.linesep + os.linesep + "mvn output:" + os.linesep
+ err.output)
sys.exit(err.returncode)
def main():
p = argparse.ArgumentParser(
usage=usage(),
formatter_class=argparse.RawDescriptionHelpFormatter)
p.add_argument('-cp', dest='classpath', help="""Additional classpath
entries, e.g. '-cp /tmp/hbase-1.0.1.1/conf'. Will be
prepended to the YCSB classpath.""")
p.add_argument("-jvm-args", default=[], type=shlex.split,
help="""Additional arguments to pass to 'java', e.g.
'-Xmx4g'""")
p.add_argument("command", choices=sorted(COMMANDS),
help="""Command to run.""")
p.add_argument("database", choices=sorted(DATABASES),
help="""Database to test.""")
args, remaining = p.parse_known_args()
ycsb_home = get_ycsb_home()
# Use JAVA_HOME to find java binary if set, otherwise just use PATH.
java = "java"
java_home = os.getenv("JAVA_HOME")
if java_home:
java = os.path.join(java_home, "bin", "java")
db_classname = DATABASES[args.database]
command = COMMANDS[args.command]["command"]
main_classname = COMMANDS[args.command]["main"]
# Classpath set up
binding = args.database.split("-")[0]
if binding == "cassandra2":
warn("The 'cassandra2-cql' client has been deprecated. It has been "
"renamed to simply 'cassandra-cql'. This alias will be removed"
" in the next YCSB release.")
binding = "cassandra"
if binding == "couchbase":
warn("The 'couchbase' client has been deprecated. If you are using "
"Couchbase 4.0+ try using the 'couchbase2' client instead.")
if is_distribution():
db_dir = os.path.join(ycsb_home, binding + "-binding")
# include top-level conf for when we're a binding-specific artifact.
# If we add top-level conf to the general artifact, starting here
# will allow binding-specific conf to override (because it's prepended)
cp = [os.path.join(ycsb_home, "conf")]
cp.extend(find_jars(os.path.join(ycsb_home, "lib")))
cp.extend(find_jars(os.path.join(db_dir, "lib")))
else:
warn("Running against a source checkout. In order to get our runtime "
"dependencies we'll have to invoke Maven. Depending on the state "
"of your system, this may take ~30-45 seconds")
db_location = "core" if binding == "basic" else binding
project = "core" if binding == "basic" else binding + "-binding"
db_dir = os.path.join(ycsb_home, db_location)
# goes first so we can rely on side-effect of package
maven_says = get_classpath_from_maven(project)
# TODO when we have a version property, skip the glob
cp = find_jars(os.path.join(db_dir, "target"),
project + "*.jar")
# alredy in jar:jar:jar form
cp.append(maven_says)
cp.insert(0, os.path.join(db_dir, "conf"))
classpath = os.pathsep.join(cp)
if args.classpath:
classpath = os.pathsep.join([args.classpath, classpath])
ycsb_command = ([java] + args.jvm_args +
["-cp", classpath,
main_classname, "-db", db_classname] + remaining)
if command:
ycsb_command.append(command)
print >> sys.stderr, " ".join(ycsb_command)
try:
return subprocess.call(ycsb_command)
except OSError as e:
if e.errno == errno.ENOENT:
error('Command failed. Is java installed and on your PATH?')
return 1
else:
raise
if __name__ == '__main__':
sys.exit(main())
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 506f1170..d3de7a92 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -1,247 +1,252 @@
4.0.0com.yahoo.ycsbroot0.13.0-SNAPSHOTycsbYCSB Release Distribution Builderpom
This module creates the release package of the YCSB with all DB library bindings.
It is only used by the build process and does not contain any real
code of itself.
com.yahoo.ycsbcore${project.version}com.yahoo.ycsbaccumulo-binding${project.version}com.yahoo.ycsbaerospike-binding${project.version}com.yahoo.ycsbarangodb-binding${project.version}com.yahoo.ycsbarangodb3-binding${project.version}com.yahoo.ycsbasynchbase-binding${project.version}com.yahoo.ycsbcassandra-binding${project.version}com.yahoo.ycsbcloudspanner-binding${project.version}com.yahoo.ycsbcouchbase-binding${project.version}com.yahoo.ycsbcouchbase2-binding${project.version}com.yahoo.ycsbazuredocumentdb-binding${project.version}com.yahoo.ycsbdynamodb-binding${project.version}com.yahoo.ycsbelasticsearch-binding${project.version}com.yahoo.ycsbgeode-binding${project.version}com.yahoo.ycsbgoogledatastore-binding${project.version}com.yahoo.ycsbgooglebigtable-binding${project.version}com.yahoo.ycsbhbase094-binding${project.version}com.yahoo.ycsbhbase098-binding${project.version}com.yahoo.ycsbhbase10-binding${project.version}
+
+ com.yahoo.ycsb
+ hbase12-binding
+ ${project.version}
+ com.yahoo.ycsbhypertable-binding${project.version}com.yahoo.ycsbinfinispan-binding${project.version}com.yahoo.ycsbjdbc-binding${project.version}com.yahoo.ycsbkudu-binding${project.version}com.yahoo.ycsbmemcached-binding${project.version}com.yahoo.ycsbmongodb-binding${project.version}com.yahoo.ycsbnosqldb-binding${project.version}com.yahoo.ycsborientdb-binding${project.version}com.yahoo.ycsbrados-binding${project.version}com.yahoo.ycsbredis-binding${project.version}com.yahoo.ycsbrest-binding${project.version}com.yahoo.ycsbriak-binding${project.version}com.yahoo.ycsbs3-binding${project.version}com.yahoo.ycsbsolr-binding${project.version}com.yahoo.ycsbsolr6-binding${project.version}com.yahoo.ycsbtarantool-binding${project.version}org.apache.maven.pluginsmaven-assembly-plugin${maven.assembly.version}src/main/assembly/distribution.xmlfalseposixpackagesingle
diff --git a/hbase12/README.md b/hbase12/README.md
new file mode 100644
index 00000000..ea658e7c
--- /dev/null
+++ b/hbase12/README.md
@@ -0,0 +1,27 @@
+
+
+# HBase (1.2+) Driver for YCSB
+This driver is a binding for the YCSB facilities to operate against a HBase 1.2+ Server cluster, using a shaded client that tries to avoid leaking third party libraries.
+
+See `hbase098/README.md` for a quickstart to setup HBase for load testing and common configuration details.
+
+## Configuration Options
+In addition to those options available for the `hbase098` binding, the following options are available for the `hbase12` binding:
+
+* `durability`: Whether or not writes should be appended to the WAL. Bypassing the WAL can improve throughput but data cannot be recovered in the event of a crash. The default is true.
+
diff --git a/hbase12/pom.xml b/hbase12/pom.xml
new file mode 100644
index 00000000..0754b28e
--- /dev/null
+++ b/hbase12/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+
+ 4.0.0
+
+ com.yahoo.ycsb
+ binding-parent
+ 0.13.0-SNAPSHOT
+ ../binding-parent/
+
+
+ hbase12-binding
+ HBase 1.2 DB Binding
+
+
+
+ true
+
+ true
+
+
+
+ com.yahoo.ycsb
+ hbase10-binding
+ ${project.version}
+
+
+
+ org.apache.hbase
+ hbase-client
+
+
+
+
+ com.yahoo.ycsb
+ core
+ ${project.version}
+ provided
+
+
+ org.apache.hbase
+ hbase-shaded-client
+ ${hbase12.version}
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
diff --git a/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/HBaseClient12.java b/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/HBaseClient12.java
new file mode 100644
index 00000000..a59a0543
--- /dev/null
+++ b/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/HBaseClient12.java
@@ -0,0 +1,28 @@
+/**
+ * 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
+ *
+ * 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. See accompanying
+ * LICENSE file.
+ */
+
+package com.yahoo.ycsb.db.hbase12;
+
+/**
+ * HBase 1.2 client for YCSB framework.
+ *
+ * A modified version of HBaseClient (which targets HBase v1.2) utilizing the
+ * shaded client.
+ *
+ * It should run equivalent to following the hbase098 binding README.
+ *
+ */
+public class HBaseClient12 extends com.yahoo.ycsb.db.HBaseClient10 {
+}
diff --git a/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/package-info.java b/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/package-info.java
new file mode 100644
index 00000000..de54dbd7
--- /dev/null
+++ b/hbase12/src/main/java/com/yahoo/ycsb/db/hbase12/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014, Yahoo!, Inc. All rights reserved.
+ *
+ * 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
+ *
+ * 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. See accompanying
+ * LICENSE file.
+ */
+
+/**
+ * The YCSB binding for HBase
+ * using the HBase 1.2+ shaded API.
+ */
+package com.yahoo.ycsb.db.hbase12;
+
diff --git a/hbase12/src/test/java/com/yahoo/ycsb/db/hbase12/HBaseClient12Test.java b/hbase12/src/test/java/com/yahoo/ycsb/db/hbase12/HBaseClient12Test.java
new file mode 100644
index 00000000..954153ae
--- /dev/null
+++ b/hbase12/src/test/java/com/yahoo/ycsb/db/hbase12/HBaseClient12Test.java
@@ -0,0 +1,213 @@
+/**
+ * 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
+ *
+ * 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. See accompanying
+ * LICENSE file.
+ */
+
+package com.yahoo.ycsb.db.hbase12;
+
+import static com.yahoo.ycsb.workloads.CoreWorkload.TABLENAME_PROPERTY;
+import static com.yahoo.ycsb.workloads.CoreWorkload.TABLENAME_PROPERTY_DEFAULT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import com.yahoo.ycsb.ByteIterator;
+import com.yahoo.ycsb.Status;
+import com.yahoo.ycsb.StringByteIterator;
+import com.yahoo.ycsb.measurements.Measurements;
+import com.yahoo.ycsb.workloads.CoreWorkload;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * Integration tests for the YCSB HBase client 1.2, using an HBase minicluster.
+ */
+public class HBaseClient12Test {
+
+ private final static String COLUMN_FAMILY = "cf";
+
+ private static HBaseTestingUtility testingUtil;
+ private HBaseClient12 client;
+ private Table table = null;
+ private String tableName;
+
+ private static boolean isWindows() {
+ final String os = System.getProperty("os.name");
+ return os.startsWith("Windows");
+ }
+
+ /**
+ * Creates a mini-cluster for use in these tests.
+ *
+ * This is a heavy-weight operation, so invoked only once for the test class.
+ */
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ // Minicluster setup fails on Windows with an UnsatisfiedLinkError.
+ // Skip if windows.
+ assumeTrue(!isWindows());
+ testingUtil = HBaseTestingUtility.createLocalHTU();
+ testingUtil.startMiniCluster();
+ }
+
+ /**
+ * Tears down mini-cluster.
+ */
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ if (testingUtil != null) {
+ testingUtil.shutdownMiniCluster();
+ }
+ }
+
+ /**
+ * Sets up the mini-cluster for testing.
+ *
+ * We re-create the table for each test.
+ */
+ @Before
+ public void setUp() throws Exception {
+ client = new HBaseClient12();
+ client.setConfiguration(new Configuration(testingUtil.getConfiguration()));
+
+ Properties p = new Properties();
+ p.setProperty("columnfamily", COLUMN_FAMILY);
+
+ Measurements.setProperties(p);
+ final CoreWorkload workload = new CoreWorkload();
+ workload.init(p);
+
+ tableName = p.getProperty(TABLENAME_PROPERTY, TABLENAME_PROPERTY_DEFAULT);
+ table = testingUtil.createTable(TableName.valueOf(tableName), Bytes.toBytes(COLUMN_FAMILY));
+
+ client.setProperties(p);
+ client.init();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ table.close();
+ testingUtil.deleteTable(tableName);
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ final String rowKey = "row1";
+ final Put p = new Put(Bytes.toBytes(rowKey));
+ p.addColumn(Bytes.toBytes(COLUMN_FAMILY),
+ Bytes.toBytes("column1"), Bytes.toBytes("value1"));
+ p.addColumn(Bytes.toBytes(COLUMN_FAMILY),
+ Bytes.toBytes("column2"), Bytes.toBytes("value2"));
+ table.put(p);
+
+ final HashMap result = new HashMap();
+ final Status status = client.read(tableName, rowKey, null, result);
+ assertEquals(Status.OK, status);
+ assertEquals(2, result.size());
+ assertEquals("value1", result.get("column1").toString());
+ assertEquals("value2", result.get("column2").toString());
+ }
+
+ @Test
+ public void testReadMissingRow() throws Exception {
+ final HashMap result = new HashMap();
+ final Status status = client.read(tableName, "Missing row", null, result);
+ assertEquals(Status.NOT_FOUND, status);
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void testScan() throws Exception {
+ // Fill with data
+ final String colStr = "row_number";
+ final byte[] col = Bytes.toBytes(colStr);
+ final int n = 10;
+ final List puts = new ArrayList(n);
+ for(int i = 0; i < n; i++) {
+ final byte[] key = Bytes.toBytes(String.format("%05d", i));
+ final byte[] value = java.nio.ByteBuffer.allocate(4).putInt(i).array();
+ final Put p = new Put(key);
+ p.addColumn(Bytes.toBytes(COLUMN_FAMILY), col, value);
+ puts.add(p);
+ }
+ table.put(puts);
+
+ // Test
+ final Vector> result =
+ new Vector>();
+
+ // Scan 5 records, skipping the first
+ client.scan(tableName, "00001", 5, null, result);
+
+ assertEquals(5, result.size());
+ for(int i = 0; i < 5; i++) {
+ final HashMap row = result.get(i);
+ assertEquals(1, row.size());
+ assertTrue(row.containsKey(colStr));
+ final byte[] bytes = row.get(colStr).toArray();
+ final ByteBuffer buf = ByteBuffer.wrap(bytes);
+ final int rowNum = buf.getInt();
+ assertEquals(i + 1, rowNum);
+ }
+ }
+
+ @Test
+ public void testUpdate() throws Exception{
+ final String key = "key";
+ final HashMap input = new HashMap();
+ input.put("column1", "value1");
+ input.put("column2", "value2");
+ final Status status = client.insert(tableName, key, StringByteIterator.getByteIteratorMap(input));
+ assertEquals(Status.OK, status);
+
+ // Verify result
+ final Get get = new Get(Bytes.toBytes(key));
+ final Result result = this.table.get(get);
+ assertFalse(result.isEmpty());
+ assertEquals(2, result.size());
+ for(final java.util.Map.Entry entry : input.entrySet()) {
+ assertEquals(entry.getValue(),
+ new String(result.getValue(Bytes.toBytes(COLUMN_FAMILY),
+ Bytes.toBytes(entry.getKey()))));
+ }
+ }
+
+ @Test
+ @Ignore("Not yet implemented")
+ public void testDelete() {
+ fail("Not yet implemented");
+ }
+}
+
diff --git a/hbase12/src/test/resources/hbase-site.xml b/hbase12/src/test/resources/hbase-site.xml
new file mode 100644
index 00000000..a8b29e45
--- /dev/null
+++ b/hbase12/src/test/resources/hbase-site.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+ hbase.master.info.port
+ -1
+ The port for the hbase master web UI
+ Set to -1 if you do not want the info server to run.
+
+
+
+ hbase.regionserver.info.port
+ -1
+ The port for the hbase regionserver web UI
+ Set to -1 if you do not want the info server to run.
+
+
+
diff --git a/hbase12/src/test/resources/log4j.properties b/hbase12/src/test/resources/log4j.properties
new file mode 100644
index 00000000..a9df32e0
--- /dev/null
+++ b/hbase12/src/test/resources/log4j.properties
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2015 YCSB contributors. All rights reserved.
+#
+# 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
+#
+# 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. See accompanying
+# LICENSE file.
+#
+
+# Root logger option
+log4j.rootLogger=WARN, stderr
+
+log4j.appender.stderr=org.apache.log4j.ConsoleAppender
+log4j.appender.stderr.target=System.err
+log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
+log4j.appender.stderr.layout.conversionPattern=%d{yyyy/MM/dd HH:mm:ss} %-5p %c %x - %m%n
+
+# Suppress messages from ZKTableStateManager: Creates a large number of table
+# state change messages.
+log4j.logger.org.apache.hadoop.hbase.zookeeper.ZKTableStateManager=ERROR
diff --git a/pom.xml b/pom.xml
index a8c38210..567376f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,189 +1,191 @@
4.0.0com.yahoo.ycsbroot0.13.0-SNAPSHOTpomYCSB Root
This is the top level project that builds, packages the core and all the DB bindings for YCSB infrastructure.
scm:git:git://github.com/brianfrankcooper/YCSB.gitmasterhttps://github.com/brianfrankcooper/YCSBcom.puppycrawl.toolscheckstyle7.7.1org.jdomjdom1.1com.google.collectionsgoogle-collections1.0org.slf4jslf4j-api1.6.42.5.52.101.7.10.94.270.98.14-hadoop21.0.2
+ 1.2.51.6.03.0.01.0.0-incubating.M31.8.10.2.37.2.2.Final1.1.02.1.13.0.32.0.12.2.102.0.01.10.200.81UTF-80.8.00.9.5.61.4.102.3.11.6.52.0.53.1.25.5.36.4.12.7.34.1.74.0.00.9.3-betacorebinding-parentaccumuloaerospikearangodbarangodb3asynchbaseazuretablestoragecassandracloudspannercouchbasecouchbase2distributionazuredocumentdbdynamodbelasticsearchgeodegooglebigtablegoogledatastorehbase094hbase098hbase10
+ hbase12hypertableinfinispanjdbckudumemcachedmongodbnosqldborientdbradosredisrestriaks3solrsolr6tarantoolorg.apache.maven.pluginsmaven-checkstyle-plugin2.16org.apache.maven.pluginsmaven-compiler-plugin3.31.7org.apache.maven.pluginsmaven-checkstyle-pluginvalidatevalidatecheckcheckstyle.xml