diff --git a/distribution/pom.xml b/distribution/pom.xml index 8d4120b410c1900ffd76785353d6a0103678cae1..cd9d04e40c50c47aeaf614071727fcb9665cabbb 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -124,6 +124,11 @@ LICENSE file. <artifactId>mongodb-binding</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>com.yahoo.ycsb</groupId> + <artifactId>nosqldb-binding</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>com.yahoo.ycsb</groupId> <artifactId>orientdb-binding</artifactId> diff --git a/nosqldb/pom.xml b/nosqldb/pom.xml index 6acaa870cd27db0bed71c9873bcf993e941bfe9d..8be3179667227f3167c2f9bb3fd45a0cbd62008a 100644 --- a/nosqldb/pom.xml +++ b/nosqldb/pom.xml @@ -27,12 +27,13 @@ LICENSE file. <artifactId>nosqldb-binding</artifactId> <name>Oracle NoSQL Database Binding</name> + <packaging>jar</packaging> <dependencies> <dependency> - <groupId>com.oracle</groupId> - <artifactId>kvclient</artifactId> - <version>1.2.123</version> + <groupId>com.oracle.kv</groupId> + <artifactId>oracle-nosql-client</artifactId> + <version>3.0.5</version> </dependency> <dependency> <groupId>com.yahoo.ycsb</groupId> @@ -41,4 +42,28 @@ LICENSE file. <scope>provided</scope> </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>2.15</version> + <configuration> + <consoleOutput>true</consoleOutput> + <configLocation>../checkstyle.xml</configLocation> + <failOnViolation>true</failOnViolation> + <failsOnError>true</failsOnError> + </configuration> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <goals> + <goal>checkstyle</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/nosqldb/src/main/java/com/yahoo/ycsb/db/NoSqlDbClient.java b/nosqldb/src/main/java/com/yahoo/ycsb/db/NoSqlDbClient.java index 1426678dcc185c9631238c5daf69bb2c2879875a..8282062053890b0d2a3f78bf97d342519af19243 100644 --- a/nosqldb/src/main/java/com/yahoo/ycsb/db/NoSqlDbClient.java +++ b/nosqldb/src/main/java/com/yahoo/ycsb/db/NoSqlDbClient.java @@ -42,197 +42,209 @@ import com.yahoo.ycsb.ByteArrayByteIterator; import com.yahoo.ycsb.ByteIterator; import com.yahoo.ycsb.DB; import com.yahoo.ycsb.DBException; +import com.yahoo.ycsb.Status; /** * A database interface layer for Oracle NoSQL Database. */ public class NoSqlDbClient extends DB { - - public static final int OK = 0; - public static final int ERROR = -1; - - KVStore store; - - private int getPropertyInt(Properties properties, String key, int defaultValue) throws DBException { - String p = properties.getProperty(key); - int i = defaultValue; - if (p != null) { - try { - i = Integer.parseInt(p); - } catch (NumberFormatException e) { - throw new DBException("Illegal number format in " + key + " property"); - } - } - return i; - } - - @Override - public void init() throws DBException { - Properties properties = getProperties(); - - /* Mandatory properties */ - String storeName = properties.getProperty("storeName", "kvstore"); - String[] helperHosts = properties.getProperty("helperHost", "localhost:5000").split(","); - - KVStoreConfig config = new KVStoreConfig(storeName, helperHosts); - - /* Optional properties */ - String p; - - p = properties.getProperty("consistency"); - if (p != null) { - if (p.equalsIgnoreCase("ABSOLUTE")) { - config.setConsistency(Consistency.ABSOLUTE); - } else if (p.equalsIgnoreCase("NONE_REQUIRED")) { - config.setConsistency(Consistency.NONE_REQUIRED); - } else { - throw new DBException("Illegal value in consistency property"); - } - } - - p = properties.getProperty("durability"); - if (p != null) { - if (p.equalsIgnoreCase("COMMIT_NO_SYNC")) { - config.setDurability(Durability.COMMIT_NO_SYNC); - } else if (p.equalsIgnoreCase("COMMIT_SYNC")) { - config.setDurability(Durability.COMMIT_SYNC); - } else if (p.equalsIgnoreCase("COMMIT_WRITE_NO_SYNC")) { - config.setDurability(Durability.COMMIT_WRITE_NO_SYNC); - } else { - throw new DBException("Illegal value in durability property"); - } - } - - int maxActiveRequests = getPropertyInt(properties, - "requestLimit.maxActiveRequests", RequestLimitConfig.DEFAULT_MAX_ACTIVE_REQUESTS); - int requestThresholdPercent = getPropertyInt(properties, - "requestLimit.requestThresholdPercent", RequestLimitConfig.DEFAULT_REQUEST_THRESHOLD_PERCENT); - int nodeLimitPercent = getPropertyInt(properties, - "requestLimit.nodeLimitPercent", RequestLimitConfig.DEFAULT_NODE_LIMIT_PERCENT); - RequestLimitConfig requestLimitConfig; - /* It is said that the constructor could throw NodeRequestLimitException in Javadoc, the exception is not provided */ -// try { - requestLimitConfig = new RequestLimitConfig(maxActiveRequests, requestThresholdPercent, nodeLimitPercent); -// } catch (NodeRequestLimitException e) { -// throw new DBException(e); -// } - config.setRequestLimit(requestLimitConfig); - - p = properties.getProperty("requestTimeout"); - if (p != null) { - long timeout = 1; - try { - timeout = Long.parseLong(p); - } catch (NumberFormatException e) { - throw new DBException("Illegal number format in requestTimeout property"); - } - try { - // TODO Support other TimeUnit - config.setRequestTimeout(timeout, TimeUnit.SECONDS); - } catch (IllegalArgumentException e) { - throw new DBException(e); - } - } - - try { - store = KVStoreFactory.getStore(config); - } catch (FaultException e) { - throw new DBException(e); - } - } - - @Override - public void cleanup() throws DBException { - store.close(); - } - - /** - * Create a key object. - * We map "table" and (YCSB's) "key" to a major component of the oracle.kv.Key, - * and "field" to a minor component. - * - * @return An oracle.kv.Key object. - */ - private static Key createKey(String table, String key, String field) { - List<String> majorPath = new ArrayList<String>(); - majorPath.add(table); - majorPath.add(key); - if (field == null) { - return Key.createKey(majorPath); - } - - return Key.createKey(majorPath, field); - } - - private static Key createKey(String table, String key) { - return createKey(table, key, null); - } - - private static String getFieldFromKey(Key key) { - return key.getMinorPath().get(0); - } - - @Override - public int read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) { - Key kvKey = createKey(table, key); - SortedMap<Key, ValueVersion> kvResult; - try { - kvResult = store.multiGet(kvKey, null, null); - } catch (FaultException e) { - System.err.println(e); - return ERROR; - } - - for (Map.Entry<Key, ValueVersion> entry : kvResult.entrySet()) { - /* If fields is null, read all fields */ - String field = getFieldFromKey(entry.getKey()); - if (fields != null && !fields.contains(field)) { - continue; - } - result.put(field, new ByteArrayByteIterator(entry.getValue().getValue().getValue())); - } - - return OK; - } - - @Override - public int scan(String table, String startkey, int recordcount, Set<String> fields, Vector<HashMap<String, ByteIterator>> result) { - System.err.println("Oracle NoSQL Database does not support Scan semantics"); - return ERROR; - } - - @Override - public int update(String table, String key, HashMap<String, ByteIterator> values) { - for (Map.Entry<String, ByteIterator> entry : values.entrySet()) { - Key kvKey = createKey(table, key, entry.getKey()); - Value kvValue = Value.createValue(entry.getValue().toArray()); - try { - store.put(kvKey, kvValue); - } catch (FaultException e) { - System.err.println(e); - return ERROR; - } - } - - return OK; - } - - @Override - public int insert(String table, String key, HashMap<String, ByteIterator> values) { - return update(table, key, values); - } - - @Override - public int delete(String table, String key) { - Key kvKey = createKey(table, key); - try { - store.multiDelete(kvKey, null, null); - } catch (FaultException e) { - System.err.println(e); - return ERROR; - } - - return OK; - } + + private KVStore store; + + private int getPropertyInt(Properties properties, String key, + int defaultValue) throws DBException { + String p = properties.getProperty(key); + int i = defaultValue; + if (p != null) { + try { + i = Integer.parseInt(p); + } catch (NumberFormatException e) { + throw new DBException("Illegal number format in " + key + " property"); + } + } + return i; + } + + @Override + public void init() throws DBException { + Properties properties = getProperties(); + + /* Mandatory properties */ + String storeName = properties.getProperty("storeName", "kvstore"); + String[] helperHosts = + properties.getProperty("helperHost", "localhost:5000").split(","); + + KVStoreConfig config = new KVStoreConfig(storeName, helperHosts); + + /* Optional properties */ + String p; + + p = properties.getProperty("consistency"); + if (p != null) { + if (p.equalsIgnoreCase("ABSOLUTE")) { + config.setConsistency(Consistency.ABSOLUTE); + } else if (p.equalsIgnoreCase("NONE_REQUIRED")) { + config.setConsistency(Consistency.NONE_REQUIRED); + } else { + throw new DBException("Illegal value in consistency property"); + } + } + + p = properties.getProperty("durability"); + if (p != null) { + if (p.equalsIgnoreCase("COMMIT_NO_SYNC")) { + config.setDurability(Durability.COMMIT_NO_SYNC); + } else if (p.equalsIgnoreCase("COMMIT_SYNC")) { + config.setDurability(Durability.COMMIT_SYNC); + } else if (p.equalsIgnoreCase("COMMIT_WRITE_NO_SYNC")) { + config.setDurability(Durability.COMMIT_WRITE_NO_SYNC); + } else { + throw new DBException("Illegal value in durability property"); + } + } + + int maxActiveRequests = + getPropertyInt(properties, "requestLimit.maxActiveRequests", + RequestLimitConfig.DEFAULT_MAX_ACTIVE_REQUESTS); + int requestThresholdPercent = + getPropertyInt(properties, "requestLimit.requestThresholdPercent", + RequestLimitConfig.DEFAULT_REQUEST_THRESHOLD_PERCENT); + int nodeLimitPercent = + getPropertyInt(properties, "requestLimit.nodeLimitPercent", + RequestLimitConfig.DEFAULT_NODE_LIMIT_PERCENT); + RequestLimitConfig requestLimitConfig; + /* + * It is said that the constructor could throw NodeRequestLimitException in + * Javadoc, the exception is not provided + */ + // try { + requestLimitConfig = new RequestLimitConfig(maxActiveRequests, + requestThresholdPercent, nodeLimitPercent); + // } catch (NodeRequestLimitException e) { + // throw new DBException(e); + // } + config.setRequestLimit(requestLimitConfig); + + p = properties.getProperty("requestTimeout"); + if (p != null) { + long timeout = 1; + try { + timeout = Long.parseLong(p); + } catch (NumberFormatException e) { + throw new DBException( + "Illegal number format in requestTimeout property"); + } + try { + // TODO Support other TimeUnit + config.setRequestTimeout(timeout, TimeUnit.SECONDS); + } catch (IllegalArgumentException e) { + throw new DBException(e); + } + } + + try { + store = KVStoreFactory.getStore(config); + } catch (FaultException e) { + throw new DBException(e); + } + } + + @Override + public void cleanup() throws DBException { + store.close(); + } + + /** + * Create a key object. We map "table" and (YCSB's) "key" to a major component + * of the oracle.kv.Key, and "field" to a minor component. + * + * @return An oracle.kv.Key object. + */ + private static Key createKey(String table, String key, String field) { + List<String> majorPath = new ArrayList<String>(); + majorPath.add(table); + majorPath.add(key); + if (field == null) { + return Key.createKey(majorPath); + } + + return Key.createKey(majorPath, field); + } + + private static Key createKey(String table, String key) { + return createKey(table, key, null); + } + + private static String getFieldFromKey(Key key) { + return key.getMinorPath().get(0); + } + + @Override + public Status read(String table, String key, Set<String> fields, + HashMap<String, ByteIterator> result) { + Key kvKey = createKey(table, key); + SortedMap<Key, ValueVersion> kvResult; + try { + kvResult = store.multiGet(kvKey, null, null); + } catch (FaultException e) { + System.err.println(e); + return Status.ERROR; + } + + for (Map.Entry<Key, ValueVersion> entry : kvResult.entrySet()) { + /* If fields is null, read all fields */ + String field = getFieldFromKey(entry.getKey()); + if (fields != null && !fields.contains(field)) { + continue; + } + result.put(field, + new ByteArrayByteIterator(entry.getValue().getValue().getValue())); + } + + return Status.OK; + } + + @Override + public Status scan(String table, String startkey, int recordcount, + Set<String> fields, Vector<HashMap<String, ByteIterator>> result) { + System.err.println("Oracle NoSQL Database does not support Scan semantics"); + return Status.ERROR; + } + + @Override + public Status update(String table, String key, + HashMap<String, ByteIterator> values) { + for (Map.Entry<String, ByteIterator> entry : values.entrySet()) { + Key kvKey = createKey(table, key, entry.getKey()); + Value kvValue = Value.createValue(entry.getValue().toArray()); + try { + store.put(kvKey, kvValue); + } catch (FaultException e) { + System.err.println(e); + return Status.ERROR; + } + } + + return Status.OK; + } + + @Override + public Status insert(String table, String key, + HashMap<String, ByteIterator> values) { + return update(table, key, values); + } + + @Override + public Status delete(String table, String key) { + Key kvKey = createKey(table, key); + try { + store.multiDelete(kvKey, null, null); + } catch (FaultException e) { + System.err.println(e); + return Status.ERROR; + } + + return Status.OK; + } } diff --git a/nosqldb/src/main/java/com/yahoo/ycsb/db/package-info.java b/nosqldb/src/main/java/com/yahoo/ycsb/db/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..2e8b9c5a1220587b3a42f9b792a845db3c6789b9 --- /dev/null +++ b/nosqldb/src/main/java/com/yahoo/ycsb/db/package-info.java @@ -0,0 +1,22 @@ +/* + * 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 <a href= + * "http://www.oracle.com/us/products/database/nosql/overview/index.html">Oracle + * 's NoSQL DB</a>. + */ +package com.yahoo.ycsb.db; diff --git a/pom.xml b/pom.xml index 83e6cfa039e19e3bdde8491366e198e17e248027..73af18a466ed71a869fece520b473416d4b8d164 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,6 @@ LICENSE file. </scm> <dependencyManagement> <dependencies> - <!-- voldemort --> <dependency> <groupId>checkstyle</groupId> <artifactId>checkstyle</artifactId> @@ -121,7 +120,7 @@ LICENSE file. <!--<module>mapkeeper</module>--> <module>memcached</module> <module>mongodb</module> - <!--module>nosqldb</module--> + <module>nosqldb</module> <module>orientdb</module> <module>redis</module> <module>s3</module>