From 59ac3c5d4b773a6cee2385f31c648336e5c13326 Mon Sep 17 00:00:00 2001 From: "J. Brisbin" Date: Tue, 23 Nov 2010 10:28:25 -0600 Subject: [PATCH] Javadoc'd almost everything --- .../riak/convert/KeyValueStoreMetaData.java | 13 + .../datastore/riak/core/BucketKeyPair.java | 13 + .../riak/core/BucketKeyResolver.java | 16 ++ .../riak/core/KeyValueStoreMetaData.java | 12 + .../riak/core/KeyValueStoreOperations.java | 177 ++++++++++++- .../riak/core/KeyValueStoreValue.java | 12 + .../datastore/riak/core/RiakMetaData.java | 3 + .../datastore/riak/core/RiakTemplate.java | 247 ++++++++++++++---- .../riak/core/SimpleBucketKeyResolver.java | 8 +- .../mapreduce/ErlangMapReduceOperation.java | 14 + .../JavascriptMapReduceOperation.java | 14 + .../riak/mapreduce/MapReduceJob.java | 39 ++- .../riak/mapreduce/MapReduceOperation.java | 7 + .../riak/mapreduce/MapReduceOperations.java | 23 ++ .../riak/mapreduce/MapReducePhase.java | 17 ++ .../riak/mapreduce/RiakMapReduceJob.java | 14 +- .../riak/mapreduce/RiakMapReducePhase.java | 3 + .../core/RiakTemplateIntegrationTests.java | 76 ------ .../riak/core/RiakTemplateSpec.groovy | 161 ------------ .../datastore/riak/core/TestObject.java | 41 --- 20 files changed, 570 insertions(+), 340 deletions(-) delete mode 100644 spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateIntegrationTests.java delete mode 100644 spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateSpec.groovy delete mode 100644 spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/TestObject.java diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/convert/KeyValueStoreMetaData.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/convert/KeyValueStoreMetaData.java index a8998b39a..ea9cb8810 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/convert/KeyValueStoreMetaData.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/convert/KeyValueStoreMetaData.java @@ -20,13 +20,26 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** + * Specify the bucket in which to store the annotated object, overriding the + * default classname method of deriving bucket name. + * * @author J. Brisbin */ @Retention(RetentionPolicy.RUNTIME) public @interface KeyValueStoreMetaData { + /** + * The bucket in which to store an instance of this object. + * + * @return + */ String bucket(); + /** + * The media type in which to covert and store this object. + * + * @return + */ String mediaType() default "application/json"; } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyPair.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyPair.java index 9cd383699..615ed6a03 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyPair.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyPair.java @@ -1,12 +1,25 @@ package org.springframework.datastore.riak.core; /** + * A generic interface for representing composite keys in data stores that use a + * bucket and key pair. + * * @author J. Brisbin */ public interface BucketKeyPair { + /** + * Get the bucket representation. + * + * @return + */ B getBucket(); + /** + * Get the key representation. + * + * @return + */ K getKey(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyResolver.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyResolver.java index 76cb869e2..5425f1ec3 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyResolver.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/BucketKeyResolver.java @@ -1,11 +1,27 @@ package org.springframework.datastore.riak.core; /** + * A generic interface to a resolver to turn a single object into a {@link + * org.springframework.datastore.riak.core.BucketKeyPair}. + * * @author J. Brisbin */ public interface BucketKeyResolver { + /** + * Can this resolver deal with the given object? + * + * @param o + * @param + * @return + */ boolean canResolve(V o); + /** + * Turn the given object into a BucketKeyPair. + * + * @param o + * @return + */ BucketKeyPair resolve(V o); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreMetaData.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreMetaData.java index 6eeb17f9c..dc5ddbf21 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreMetaData.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreMetaData.java @@ -5,12 +5,24 @@ import org.springframework.http.MediaType; import java.util.Map; /** + * A generic interface to MetaData provided by Key/Value data stores. + * * @author J. Brisbin */ public interface KeyValueStoreMetaData { + /** + * Get the Content-Type of this object. + * + * @return + */ MediaType getContentType(); + /** + * Get the arbitrary properties for this object. + * + * @return + */ Map getProperties(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreOperations.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreOperations.java index dd5e112b0..8ccb10283 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreOperations.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreOperations.java @@ -18,57 +18,232 @@ package org.springframework.datastore.riak.core; import java.util.List; import java.util.Map; +/** + * Generic abstraction for Key/Value stores. Contains most operations that + * generic K/V stores might expose. + */ public interface KeyValueStoreOperations { - // Set and Set with expiry operations + // Set operations + + /** + * Set a value at a specified key. + * + * @param key + * @param value + * @return This template interface + */ KeyValueStoreOperations set(K key, V value); + /** + * Set a value as a byte array at a specified key. + * + * @param key + * @param value + * @return This template interface + */ KeyValueStoreOperations setAsBytes(K key, byte[] value); // Get operations + + /** + * Get a value at the specified key, trying to infer the type from either the + * bucket in which the value was stored, or (by default) as a + * java.util.Map. + * + * @param key + * @return The converted value, or null if not found. + */ V get(K key); + /** + * Get the value at the specified key as a byte array. + * + * @param key + * @return The byte array of data, or null if not found. + */ byte[] getAsBytes(K key); + /** + * Get the value at the specified key and convert it into an instance of the + * specified type. + * + * @param key + * @param requiredType + * @return The converted value, or null if not found. + */ T getAsType(K key, Class requiredType); // Get and Set operations + + /** + * Get the old value at the specified key and replace it with the given + * value. + * + * @param key + * @param value + * @return The old value (before it was overwritten). + */ V getAndSet(K key, V value); + /** + * Get the old value at the specified key as a byte array and replace it with + * the given bytes. + * + * @param key + * @param value + * @return The old byte array (before it was overwritten). + */ byte[] getAndSetAsBytes(K key, byte[] value); + /** + * Get the old value at the specified key and replace it with the given value, + * converting it to an instance of the given type. + * + * @param key + * @param value + * @param requiredType The type to convert the value to. + * @return The old value (before it was overwritten). + */ T getAndSetAsType(K key, V value, Class requiredType); // Multi-get operations + + /** + * Get all the values at the specified keys. + * + * @param keys + * @return A list of the values retrieved or an empty list if none were + * found. + */ List getValues(List keys); + /** + * Variation on {@link KeyValueStoreOperations#getValues(java.util.List)} that + * uses varargs instead of a java.util.List. + * + * @param keys + * @return A list of the values retrieved or an empty list if none were + * found. + */ List getValues(K... keys); + /** + * Get all the values at the specified keys, converting the values into + * instances of the specified type. + * + * @param keys + * @param requiredType + * @return A list of the values retrieved or an empty list if none were + * found. + */ List getValuesAsType(List keys, Class requiredType); + /** + * A variation on {@link KeyValueStoreOperations#getValuesAsType(java.util.List, + * Class)} that takes uses varargs instead of a java.util.List. + * + * @param requiredType + * @param keys + * @return A list of the values retrieved or an empty list if none were + * found. + */ List getValuesAsType(Class requiredType, K... keys); // Set if non-existent operations + + /** + * Set the value at the given key only if that key doesn't already exist. + * + * @param key + * @param value + * @return This template interface + */ KeyValueStoreOperations setIfKeyNonExistent(K key, V value); + /** + * Set the value at the given key as a byte array only if that key doesn't + * already exist. + * + * @param key + * @param value + * @return This template interface + */ KeyValueStoreOperations setIfKeyNonExistentAsBytes(K key, byte[] value); // Multiple key-value set + + /** + * Convenience method to set multiple values as Key/Value pairs. + * + * @param keysAndValues + * @return This template interface + */ KeyValueStoreOperations setMultiple(Map keysAndValues); + /** + * Convenience method to set multiple values as Key/byte[] pairs. + * + * @param keysAndValues + * @return This template interface + */ KeyValueStoreOperations setMultipleAsBytes(Map keysAndValues); // Multiple key-value set if non-existent + + /** + * Variation on setting multiple values only if the key doesn't already + * exist. + * + * @param keysAndValues + * @return This template interface + */ KeyValueStoreOperations setMultipleIfKeysNonExistent(Map keysAndValues); + /** + * Variation on setting multiple values as byte arryas only if the key doesn't + * already exist. + * + * @param keysAndValues + * @param + * @return + */ KeyValueStoreOperations setMultipleAsBytesIfKeysNonExistent(Map keysAndValues); + /** + * Does the store contain this key? + * + * @param key + * @return true if the key exists, false otherwise. + */ boolean containsKey(K key); + /** + * Delete one or more keys from the store. + * + * @param keys + * @return true if all keys were successfully deleted, + * false otherwise. + */ boolean deleteKeys(K... keys); + /** + * Get the properties of the specified bucket. + * + * @param bucket + * @return The bucket properties, without a list of keys in that bucket. + */ Map getBucketSchema(B bucket); + /** + * Get the properties of the bucket and specify whether or not to list the + * keys in that bucket. + * + * @param bucket + * @param listKeys + * @return The bucket properties, with or without a list of keys in that + * bucket. + */ Map getBucketSchema(B bucket, boolean listKeys); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreValue.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreValue.java index 9474a0cb9..f0924c0c8 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreValue.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/KeyValueStoreValue.java @@ -1,12 +1,24 @@ package org.springframework.datastore.riak.core; /** + * A generic interface for dealing with values and their store metadata. + * * @author J. Brisbin */ public interface KeyValueStoreValue { + /** + * Get the metadata associated with this value. + * + * @return + */ KeyValueStoreMetaData getMetaData(); + /** + * Get the converted value itself. + * + * @return + */ T get(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakMetaData.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakMetaData.java index d2773e4ff..f74efc6d4 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakMetaData.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakMetaData.java @@ -5,6 +5,9 @@ import org.springframework.http.MediaType; import java.util.Map; /** + * An implementation of {@link org.springframework.datastore.riak.core.KeyValueStoreMetaData} + * for Riak. + * * @author J. Brisbin */ public class RiakMetaData implements KeyValueStoreMetaData { diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakTemplate.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakTemplate.java index 9e46bf4bd..c812cdc7d 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakTemplate.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/RiakTemplate.java @@ -61,41 +61,112 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** + * An implementation of {@link org.springframework.datastore.riak.core.KeyValueStoreOperations} + * and {@link org.springframework.datastore.riak.mapreduce.MapReduceOperations} + * for the Riak data store. + *

+ * To use the RiakTemplate, create a singleton in your Spring + * application-context.xml: + *


+ * <bean id="riak" class="org.springframework.datastore.riak.core.RiakTemplate"
+ *     p:defaultUri="http://localhost:8098/riak/{bucket}/{key}"
+ *     p:mapReduceUri="http://localhost:8098/mapred"/>
+ * 
+ * To store and retrieve objects in Riak, use the setXXX and getXXX methods + * (example in Groovy): + *

+ * def obj = new TestObject(name: "My Name", age: 40)
+ * riak.set([bucket: "mybucket", key: "mykey"], obj)
+ * ...
+ * def name = riak.get([bucket: "mybucket", key: "mykey"]).name
+ * println "Hello $name!"
+ * 
+ * You're key object should be one of:
  • A String encoding + * the bucket and key together, separated by a colon. e.g. "mybucket:mykey"
  • + *
  • An implementation of BucketKeyPair (like {@link org.springframework.datastore.riak.core.SimpleBucketKeyPair})
  • + *
  • A Map with both a "bucket" and a "key" specified.
  • A + * String of only the key name, but specifying a bucket by using + * the {@link org.springframework.datastore.riak.convert.KeyValueStoreMetaData} + * annotation on the object you're storing.
+ * * @author J. Brisbin */ @SuppressWarnings({"unchecked"}) public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOperations, MapReduceOperations, InitializingBean { + /** + * Client ID used by Riak to correlate updates. + */ private static final String RIAK_CLIENT_ID = "org.springframework.datastore.riak.core.RiakTemplate/1.0"; - private static final Pattern prefix = Pattern.compile("http[s]?://(\\S+):([0-9]+)/(\\S+)/\\{bucket\\}(\\S+)"); - private static final boolean groovyPresent = ClassUtils.isPresent("org.codehaus.groovy.runtime.GStringImpl", + /** + * Regex used to extract host, port, and prefix from the given URI. + */ + private static final Pattern prefix = Pattern.compile( + "http[s]?://(\\S+):([0-9]+)/(\\S+)/\\{bucket\\}(\\S+)"); + /** + * Do we need to handle Groovy strings in the Jackson JSON processor? + */ + private static final boolean groovyPresent = ClassUtils.isPresent( + "org.codehaus.groovy.runtime.GStringImpl", RiakTemplate.class.getClassLoader()); - - private static SimpleDateFormat httpDate = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z"); + /** + * For getting a java.util.Date from the Last-Modified header. + */ + private static SimpleDateFormat httpDate = new SimpleDateFormat( + "EEE, d MMM yyyy HH:mm:ss z"); protected final Logger log = LoggerFactory.getLogger(getClass()); + /** + * For converting objects to/from other kinds of objects. + */ protected ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService(); + /** + * For caching objects based on ETags. + */ protected ConcurrentSkipListMap> cache = new ConcurrentSkipListMap>(); + /** + * Whether or not to use the ETag-based cache. + */ protected boolean useCache = true; + /** + * Not yet used. + */ protected ExecutorService queue = Executors.newCachedThreadPool(); - + /** + * The URI to use inside the RestTemplate. + */ protected String defaultUri = "http://localhost:8098/riak/{bucket}/{key}"; + /** + * The URI for the Riak Map/Reduce API. + */ protected String mapReduceUri = "http://localhost:8098/mapred"; + /** + * A list of resolvers to turn a single object into a {#link BucketKeyPair}. + */ protected List bucketKeyResolvers; + /** + * Take all the defaults. + */ public RiakTemplate() { setRestTemplate(new RestTemplate()); } + /** + * Use the specified {@link org.springframework.http.client.ClientHttpRequestFactory}. + * + * @param requestFactory + */ public RiakTemplate(ClientHttpRequestFactory requestFactory) { super(requestFactory); } - public RiakTemplate(String defaultUri) { - setRestTemplate(new RestTemplate()); - setDefaultUri(defaultUri); - } - + /** + * Use the specified defaultUri and mapReduceUri. + * + * @param defaultUri + * @param mapReduceUri + */ public RiakTemplate(String defaultUri, String mapReduceUri) { setRestTemplate(new RestTemplate()); this.setDefaultUri(defaultUri); @@ -106,6 +177,11 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe return conversionService; } + /** + * Specify the conversion service to use. + * + * @param conversionService + */ public void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } @@ -130,6 +206,11 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe return bucketKeyResolvers; } + /** + * Set the list of BucketKeyResolvers to use. + * + * @param bucketKeyResolvers + */ public void setBucketKeyResolvers(List bucketKeyResolvers) { this.bucketKeyResolvers = bucketKeyResolvers; } @@ -142,6 +223,14 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe this.useCache = useCache; } + public String getPrefix() { + Matcher m = prefix.matcher(defaultUri); + if (m.matches()) { + return "/" + m.group(3); + } + return "/riak"; + } + /*----------------- Set Operations -----------------*/ public KeyValueStoreOperations set(K key, V value) { @@ -151,7 +240,8 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe public KeyValueStoreOperations setAsBytes(K key, byte[] value) { Assert.notNull(key, "Can't store an object with a NULL key."); BucketKeyPair bucketKeyPair = resolveBucketKeyPair(key, value); - String bucketName = (null != bucketKeyPair.getBucket() ? bucketKeyPair.getBucket().toString() : "bytes"); + String bucketName = (null != bucketKeyPair.getBucket() ? bucketKeyPair.getBucket() + .toString() : "bytes"); RestTemplate restTemplate = getRestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.set("X-Riak-ClientId", RIAK_CLIENT_ID); @@ -159,7 +249,9 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe HttpEntity entity = new HttpEntity(value, headers); restTemplate.put(defaultUri, entity, bucketName, bucketKeyPair.getKey()); if (log.isDebugEnabled()) { - log.debug(String.format("PUT byte[]: bucket=%s, key=%s", bucketKeyPair.getBucket(), bucketKeyPair.getKey())); + log.debug(String.format("PUT byte[]: bucket=%s, key=%s", + bucketKeyPair.getBucket(), + bucketKeyPair.getKey())); } return this; } @@ -176,7 +268,10 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe } } HttpEntity entity = new HttpEntity(value, headers); - restTemplate.put(defaultUri, entity, bucketKeyPair.getBucket(), bucketKeyPair.getKey()); + restTemplate.put(defaultUri, + entity, + bucketKeyPair.getBucket(), + bucketKeyPair.getKey()); if (log.isDebugEnabled()) { log.debug(String.format("PUT object: bucket=%s, key=%s, value=%s", bucketKeyPair.getBucket(), @@ -250,27 +345,32 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe } try { - RiakValue bytes = (RiakValue) restTemplate.execute(defaultUri, + RiakValue bytes = (RiakValue) restTemplate.execute( + defaultUri, HttpMethod.GET, new RequestCallback() { - public void doWithRequest(ClientHttpRequest request) throws IOException { + public void doWithRequest(ClientHttpRequest request) throws + IOException { List mediaTypes = new ArrayList(); mediaTypes.add(MediaType.APPLICATION_JSON); request.getHeaders().setAccept(mediaTypes); } }, new ResponseExtractor() { - public Object extractData(ClientHttpResponse response) throws IOException { + public Object extractData(ClientHttpResponse response) throws + IOException { InputStream in = response.getBody(); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buff = new byte[in.available()]; - for (int bytesRead = in.read(buff); bytesRead > 0; bytesRead = in.read(buff)) { + for (int bytesRead = in.read(buff); bytesRead > 0; bytesRead = in.read( + buff)) { out.write(buff, 0, bytesRead); } HttpHeaders headers = response.getHeaders(); RiakMetaData meta = extractMetaData(headers); - RiakValue val = new RiakValue(out.toByteArray(), meta); + RiakValue val = new RiakValue(out.toByteArray(), + meta); return val; } }, @@ -351,7 +451,9 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe set(key, value); } else { if (log.isDebugEnabled()) { - log.debug(String.format("key: %s already exists. Not adding %s", key, value)); + log.debug(String.format("key: %s already exists. Not adding %s", + key, + value)); } } return this; @@ -362,7 +464,9 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe setAsBytes(key, value); } else { if (log.isDebugEnabled()) { - log.debug(String.format("key: %s already exists. Not adding %s", key, value)); + log.debug(String.format("key: %s already exists. Not adding %s", + key, + value)); } } return this; @@ -405,7 +509,9 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe RestTemplate restTemplate = getRestTemplate(); HttpHeaders headers = null; try { - headers = restTemplate.headForHeaders(defaultUri, bucketKeyPair.getBucket(), bucketKeyPair.getKey()); + headers = restTemplate.headForHeaders(defaultUri, + bucketKeyPair.getBucket(), + bucketKeyPair.getKey()); } catch (ResourceAccessException e) { } return (null != headers); @@ -442,7 +548,9 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe public T execute(MapReduceJob job, Class targetType) { RestTemplate restTemplate = getRestTemplate(); - ResponseEntity resp = restTemplate.postForEntity(mapReduceUri, job.toJson(), targetType); + ResponseEntity resp = restTemplate.postForEntity(mapReduceUri, + job.toJson(), + targetType); if (resp.hasBody()) { return resp.getBody(); } @@ -455,6 +563,14 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe /*----------------- Link Operations -----------------*/ + /** + * Use Riak's native Link mechanism to link two entries together. + * + * @param destination Key to the child object + * @param source Key to the parent object + * @param tag The tag for this relationship + * @return This template interface + */ public RiakTemplate link(K1 destination, K2 source, String tag) { BucketKeyPair bkpFrom = resolveBucketKeyPair(source, null); BucketKeyPair bkpTo = resolveBucketKeyPair(destination, null); @@ -462,7 +578,8 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe RiakValue fromObj = getAsBytesWithMetaData(source); if (null == fromObj) { - throw new DataStoreOperationException("Cannot link from a non-existent source: " + source); + throw new DataStoreOperationException( + "Cannot link from a non-existent source: " + source); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(fromObj.getMetaData().getContentType()); @@ -473,7 +590,11 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe } else if (linksObj instanceof String) { links.add(linksObj.toString()); } - links.add(String.format("<%s/%s/%s>; riaktag=\"%s\"", extractPrefix(), bkpTo.getBucket(), bkpTo.getKey(), tag)); + links.add(String.format("<%s/%s/%s>; riaktag=\"%s\"", + getPrefix(), + bkpTo.getBucket(), + bkpTo.getKey(), + tag)); StringWriter sw = new StringWriter(); boolean needsComma = false; for (String link : links) { @@ -493,21 +614,34 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe return this; } + /** + * Incomplete implementation of Link Walking. + * + * @param source + * @param tag + * @return + */ public T linkWalk(K source, String tag) { BucketKeyPair bkpSource = resolveBucketKeyPair(source, null); RestTemplate restTemplate = getRestTemplate(); final List types = new ArrayList(); types.add(MediaType.ALL); - restTemplate.execute(defaultUri + "/_,{tag},_", HttpMethod.GET, new RequestCallback() { - public void doWithRequest(ClientHttpRequest request) throws IOException { - request.getHeaders().setAccept(types); - } - }, new ResponseExtractor() { - public Object extractData(ClientHttpResponse response) throws IOException { - response.getHeaders(); - return null; //To change body of implemented methods use File | Settings | File Templates. - } - }, bkpSource.getBucket(), + restTemplate.execute(defaultUri + "/_,{tag},_", + HttpMethod.GET, + new RequestCallback() { + public void doWithRequest(ClientHttpRequest request) throws + IOException { + request.getHeaders().setAccept(types); + } + }, + new ResponseExtractor() { + public Object extractData(ClientHttpResponse response) throws + IOException { + response.getHeaders(); + return null; //To change body of implemented methods use File | Settings | File Templates. + } + }, + bkpSource.getBucket(), bkpSource.getKey(), tag); return null; @@ -528,12 +662,14 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe if (resp.hasBody()) { return resp.getBody(); } else { - throw new DataStoreOperationException("Error encountered retrieving bucket schema (Status: " + resp.getStatusCode() + ")"); + throw new DataStoreOperationException( + "Error encountered retrieving bucket schema (Status: " + resp.getStatusCode() + ")"); } } public void afterPropertiesSet() throws Exception { - Assert.notNull(conversionService, "Must specify a valid ConversionService."); + Assert.notNull(conversionService, + "Must specify a valid ConversionService."); if (null == bucketKeyResolvers) { bucketKeyResolvers = new ArrayList(); bucketKeyResolvers.add(new SimpleBucketKeyResolver()); @@ -548,7 +684,8 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe mapper.setSerializerFactory(fac); for (HttpMessageConverter converter : converters) { if (converter instanceof MappingJacksonHttpMessageConverter) { - ((MappingJacksonHttpMessageConverter) converter).setObjectMapper(mapper); + ((MappingJacksonHttpMessageConverter) converter).setObjectMapper( + mapper); } } } @@ -569,24 +706,28 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe if (null != resolver) { bucketKeyPair = resolver.resolve(key); if (null != val) { - Annotation meta = (val instanceof Class ? (Class) val : val.getClass()).getAnnotation(KeyValueStoreMetaData.class); + Annotation meta = (val instanceof Class ? (Class) val : val.getClass()).getAnnotation( + KeyValueStoreMetaData.class); if (null != meta) { String bucket = ((KeyValueStoreMetaData) meta).bucket(); if (null != bucket) { - return new SimpleBucketKeyPair(bucket, bucketKeyPair.getKey()); + return new SimpleBucketKeyPair(bucket, + bucketKeyPair.getKey()); } } } return bucketKeyPair; } - throw new DataStoreOperationException(String.format("No resolvers available to resolve bucket/key pair from %s", + throw new DataStoreOperationException(String.format( + "No resolvers available to resolve bucket/key pair from %s", key)); } protected MediaType extractMediaType(Object value) { MediaType mediaType = (value instanceof byte[] ? MediaType.APPLICATION_OCTET_STREAM : MediaType.APPLICATION_JSON); if (value.getClass().getAnnotations().length > 0) { - KeyValueStoreMetaData meta = value.getClass().getAnnotation(KeyValueStoreMetaData.class); + KeyValueStoreMetaData meta = value.getClass() + .getAnnotation(KeyValueStoreMetaData.class); if (null != meta) { mediaType = MediaType.parseMediaType(meta.mediaType()); } @@ -594,13 +735,15 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe return mediaType; } - protected RiakMetaData extractMetaData(HttpHeaders headers) throws IOException { + protected RiakMetaData extractMetaData(HttpHeaders headers) throws + IOException { Map props = new LinkedHashMap(); for (Map.Entry> entry : headers.entrySet()) { List val = entry.getValue(); Object prop = (1 == val.size() ? val.get(0) : val); try { - if (entry.getKey().equals("Last-Modified") || entry.getKey().equals("Date")) { + if (entry.getKey().equals("Last-Modified") || entry.getKey() + .equals("Date")) { prop = httpDate.parse(val.get(0)); } } catch (ParseException e) { @@ -637,8 +780,14 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe String bucketName = (null != bucketKeyPair.getBucket() ? bucketKeyPair.getBucket() .toString() : requiredType.getName()); RestTemplate restTemplate = getRestTemplate(); - HttpHeaders resp = restTemplate.headForHeaders(defaultUri, bucketName, bucketKeyPair.getKey()); - if (!obj.getMetaData().getProperties().get("ETag").toString().equals(resp.getETag())) { + HttpHeaders resp = restTemplate.headForHeaders(defaultUri, + bucketName, + bucketKeyPair.getKey()); + if (!obj.getMetaData() + .getProperties() + .get("ETag") + .toString() + .equals(resp.getETag())) { obj = null; } else { if (log.isDebugEnabled()) { @@ -649,12 +798,4 @@ public class RiakTemplate extends RestGatewaySupport implements KeyValueStoreOpe return (null != obj ? (T) obj.get() : null); } - public String extractPrefix() { - Matcher m = prefix.matcher(defaultUri); - if (m.matches()) { - return "/" + m.group(3); - } - return "/riak"; - } - } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/SimpleBucketKeyResolver.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/SimpleBucketKeyResolver.java index f2f56f7d0..61667619f 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/SimpleBucketKeyResolver.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/core/SimpleBucketKeyResolver.java @@ -12,7 +12,8 @@ import java.util.regex.Pattern; @SuppressWarnings({"unchecked"}) public class SimpleBucketKeyResolver implements BucketKeyResolver { - private static final boolean groovyPresent = ClassUtils.isPresent("org.codehaus.groovy.runtime.GStringImpl", + private static final boolean groovyPresent = ClassUtils.isPresent( + "org.codehaus.groovy.runtime.GStringImpl", RiakTemplate.class.getClassLoader()); protected Pattern bucketColonKey = Pattern.compile("(.+):(.+)"); @@ -43,12 +44,13 @@ public class SimpleBucketKeyResolver implements BucketKeyResolver { Map m = (Map) o; Object bucket = m.get("bucket"); Object key = m.get("key"); - bucketKeyPair = new SimpleBucketKeyPair((null != bucket ? bucket.toString() : null), + bucketKeyPair = new SimpleBucketKeyPair((null != bucket ? bucket + .toString() : null), (null != key ? key.toString() : null)); } else if (o instanceof BucketKeyPair) { bucketKeyPair = (BucketKeyPair) o; } else if (groovyPresent && o instanceof GStringImpl) { - bucketKeyPair = resolve(((GStringImpl) o).toString()); + bucketKeyPair = resolve(o.toString()); } return bucketKeyPair; diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/ErlangMapReduceOperation.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/ErlangMapReduceOperation.java index 0b9583183..3d50e8d9f 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/ErlangMapReduceOperation.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/ErlangMapReduceOperation.java @@ -4,6 +4,10 @@ import java.util.LinkedHashMap; import java.util.Map; /** + * An implementation of {@link org.springframework.datastore.riak.mapreduce.MapReduceOperation} + * to represent an Erlang M/R function, which must be already defined inside the + * Riak server. + * * @author J. Brisbin */ @SuppressWarnings({"unchecked"}) @@ -20,10 +24,20 @@ public class ErlangMapReduceOperation implements MapReduceOperation { setFunction(function); } + /** + * Set the Erlang module this function is defined in. + * + * @param module + */ public void setModule(String module) { moduleFunction.put("module", module); } + /** + * Set the name of this Erlang function. + * + * @param function + */ public void setFunction(String function) { moduleFunction.put("function", function); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/JavascriptMapReduceOperation.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/JavascriptMapReduceOperation.java index 4609d2ba3..3c95cc849 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/JavascriptMapReduceOperation.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/JavascriptMapReduceOperation.java @@ -3,6 +3,9 @@ package org.springframework.datastore.riak.mapreduce; import org.springframework.datastore.riak.core.BucketKeyPair; /** + * An implementation of {@link org.springframework.datastore.riak.mapreduce.MapReduceOperation} + * to describe a Javascript language M/R function. + * * @author J. Brisbin */ public class JavascriptMapReduceOperation implements MapReduceOperation { @@ -22,6 +25,11 @@ public class JavascriptMapReduceOperation implements MapReduceOperation { return source; } + /** + * Set the anonymous source to use for the M/R function. + * + * @param source + */ public void setSource(String source) { this.source = source; } @@ -30,6 +38,12 @@ public class JavascriptMapReduceOperation implements MapReduceOperation { return bucketKeyPair; } + /** + * Set the {@link org.springframework.datastore.riak.core.BucketKeyPair} to + * point to for the Javascript to use in this M/R function. + * + * @param bucketKeyPair + */ public void setBucketKeyPair(BucketKeyPair bucketKeyPair) { this.bucketKeyPair = bucketKeyPair; } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceJob.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceJob.java index 33e4c5f0f..3275425a5 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceJob.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceJob.java @@ -20,19 +20,56 @@ import java.util.List; import java.util.concurrent.Callable; /** + * A generic interface to representing a Map/Reduce job to a data store that + * supports that operation. + * * @author J. Brisbin */ public interface MapReduceJob extends Callable { - List getInputs(); + /** + * Get the list of inputs for this job. + * + * @return + */ + List getInputs(); + /** + * Set the list of inputs for this job. + * + * @param keys + * @param + * @return + */ MapReduceJob addInputs(List keys); + /** + * Add a phase to this operation. + * + * @param phase + * @return + */ MapReduceJob addPhase(MapReducePhase phase); + /** + * Set the static argument for this job. + * + * @param arg + */ void setArg(T arg); + /** + * Get the static argument for this job. + * + * @param + * @return + */ T getArg(); + /** + * Convert this job into the appropriate JSON to send to the server. + * + * @return + */ String toJson(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperation.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperation.java index 76a9762bd..0e3e6fb54 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperation.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperation.java @@ -17,10 +17,17 @@ package org.springframework.datastore.riak.mapreduce; /** + * A generic interface to a Map/Reduce operation. + * * @author J. Brisbin */ public interface MapReduceOperation { + /** + * Get the implementation-specific representation of a Map/Reduce operation. + * + * @return + */ Object getRepresentation(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperations.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperations.java index df330ed85..3e04565a0 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperations.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReduceOperations.java @@ -20,14 +20,37 @@ import java.util.List; import java.util.concurrent.Future; /** + * Generic interface to Map/Reduce in data stores that support it. + * * @author J. Brisbin */ public interface MapReduceOperations { + /** + * Execute a {@link org.springframework.datastore.riak.mapreduce.MapReduceJob} + * synchronously. + * + * @param job + * @return + */ Object execute(MapReduceJob job); + /** + * Execute a MapReduceJob synchronously, converting the result into the given + * type. + * + * @param job + * @param targetType + * @return The converted value. + */ T execute(MapReduceJob job, Class targetType); + /** + * Submit the job to run asynchronously. + * + * @param job + * @return The Future representing the submitted job. + */ Future> submit(MapReduceJob job); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReducePhase.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReducePhase.java index d396ebffa..92b7c98f5 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReducePhase.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/MapReducePhase.java @@ -17,6 +17,8 @@ package org.springframework.datastore.riak.mapreduce; /** + * A generic interface to the phases of Map/Reduce jobs. + * * @author J. Brisbin */ public interface MapReducePhase { @@ -27,10 +29,25 @@ public interface MapReducePhase { Phase getPhase(); + /** + * The language this phase is described in. + * + * @return + */ String getLanguage(); + /** + * Whether or not to keep the result of this phase. + * + * @return + */ boolean getKeepResults(); + /** + * Get the operation this phase will execute. + * + * @return + */ MapReduceOperation getOperation(); } diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReduceJob.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReduceJob.java index 652f3ccb8..28692bd9a 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReduceJob.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReduceJob.java @@ -31,6 +31,9 @@ import java.util.List; import java.util.Map; /** + * An implementation of {@link org.springframework.datastore.riak.mapreduce.MapReduceJob} + * for the Riak data store. + * * @author J. Brisbin */ @SuppressWarnings({"unchecked"}) @@ -54,7 +57,7 @@ public class RiakMapReduceJob implements MapReduceJob { this.riakTemplate = riakTemplate; } - public List getInputs() { + public List getInputs() { return this.inputs; } @@ -117,14 +120,17 @@ public class RiakMapReduceJob implements MapReduceJob { Object repr = phase.getOperation().getRepresentation(); if (repr instanceof String) { // Using source - json.writeStringField("source", String.format("%s", phase.getOperation().getRepresentation())); + json.writeStringField("source", + String.format("%s", phase.getOperation().getRepresentation())); } else if (repr instanceof BucketKeyPair) { BucketKeyPair pair = (BucketKeyPair) repr; - json.writeStringField("bucket", String.format("%s", pair.getBucket())); + json.writeStringField("bucket", + String.format("%s", pair.getBucket())); json.writeStringField("key", String.format("%s", pair.getKey())); } else if (repr instanceof Map) { for (Map.Entry entry : ((Map) repr).entrySet()) { - json.writeStringField(entry.getKey().toString(), entry.getValue().toString()); + json.writeStringField(entry.getKey().toString(), + entry.getValue().toString()); } } if (phase.getKeepResults()) { diff --git a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReducePhase.java b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReducePhase.java index 02c7a50c7..6f74836f5 100644 --- a/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReducePhase.java +++ b/spring-datastore-riak/src/main/java/org/springframework/datastore/riak/mapreduce/RiakMapReducePhase.java @@ -17,6 +17,9 @@ package org.springframework.datastore.riak.mapreduce; /** + * An implementation of {@link org.springframework.datastore.riak.mapreduce.MapReducePhase} + * for the Riak data store. + * * @author J. Brisbin */ public class RiakMapReducePhase implements MapReducePhase { diff --git a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateIntegrationTests.java b/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateIntegrationTests.java deleted file mode 100644 index dd1f1e7d8..000000000 --- a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateIntegrationTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2010 the original author or authors. - * - * 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. - */ - -package org.springframework.datastore.riak.core; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import java.util.LinkedHashMap; -import java.util.Map; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration({"/org/springframework/datastore/RiakTemplateTests.xml"}) -@SuppressWarnings({"unchecked"}) -public class RiakTemplateIntegrationTests { - - @Autowired - ApplicationContext appCtx; - @Autowired - RiakTemplate riak; - - public void testSet() { - Map obj = new LinkedHashMap(); - obj.put("test", "value"); - obj.put("test2", 12); - riak.set("test:test", obj); - } - - @Test - public void testSetAsType() { - TestObject obj = new TestObject(); - riak.set("test", obj); - } - - public void testSetInferringType() { - Map obj = new LinkedHashMap(); - obj.put("test", "value"); - obj.put("test2", 12); - riak.set("test", obj); - } - - public void testGetInferringType() { - Map obj = riak.get("java.util.LinkedHashMap:test"); - assert null != obj; - assert 12 == (Integer) obj.get("test2"); - } - - @Test - public void testGetAsType() { - TestObject obj = riak.getAsType("test", TestObject.class); - assert null != obj; - } - - @Test - public void conversions() { - - } - -} diff --git a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateSpec.groovy b/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateSpec.groovy deleted file mode 100644 index 8f3c275f8..000000000 --- a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/RiakTemplateSpec.groovy +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2010 by J. Brisbin - * - * 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. - */ -package org.springframework.datastore.riak.core - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.ApplicationContext -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -/** - * @author J. Brisbin - */ -@ContextConfiguration(locations = "/org/springframework/datastore/RiakTemplateTests.xml") -class RiakTemplateSpec extends Specification { - - @Autowired - ApplicationContext appCtx - @Autowired - RiakTemplate riak - int run = 1 - - def "Test Map object with 'bucket:key' key"() { - - given: - def i = run++ - String val = "value $i" - def objIn = [test: "value $i", integer: 12] - riak.set("test:test", objIn) - - when: - def objOut = riak.get("test:test") - - then: - objOut.test == val - - } - - def "Test Map object with Map key"() { - - given: - def i = run++ - String val = "value $i" - def objIn = [test: val, integer: 12] - riak.set([bucket: "test", key: "test"], objIn) - - when: - def objOut = riak.get([bucket: "test", key: "test"]) - - then: - objOut.test == val - - } - - def "Test custom object with 'bucket:key' key"() { - - given: - TestObject objIn = new TestObject() - riak.set("test:test", objIn) - - when: - TestObject objOut = riak.get("test:test") - - then: - objOut.test == "value" - - } - - def "Test custom object with 'ClassName:key' key"() { - - given: - TestObject objIn = new TestObject() - riak.set("test", objIn) - - when: - TestObject objOut = riak.getAsType("test", TestObject) - - then: - objOut.test == "value" - - } - - def "Test containsKey"() { - - when: - def containsKey = riak.containsKey("test:test") - - then: - true == containsKey - - } - - def "Test multiple get"() { - - when: - def objs = riak.getValues(["test:test", "${TestObject.name}:test"]) - - then: - 2 == objs.size() - - } - - def "Test getAndSet with Map"() { - - given: - def i = run++ - String val = "value $i" - def newObj = [test: val, integer: 12] - - when: - def oldObj = riak.getAndSet("test:test", newObj) - - then: - "value" == oldObj.test - - } - - def "Test deleteKeys"() { - - when: - def deleted = riak.deleteKeys("test:test", "${TestObject.name}:test") - - then: - true == deleted - - } - - def "Test setMultipleIfKeysNonExistent with Map"() { - - given: - def newObj = [ - "test:test": [test: "value", integer: 12], - "${TestObject.name}:test": [test: "value", integer: 12] - ] - - when: - def secondObj = riak.setMultipleIfKeysNonExistent(newObj).get("${TestObject.name}:test") - secondObj.test = "newValue" - def thirdObj = riak.setMultipleIfKeysNonExistent(["${TestObject.name}:test": secondObj]).get("${TestObject.name}:test") - - then: - "value" == thirdObj.test - - cleanup: - riak.deleteKeys("test:test", "${TestObject.name}:test") - - } - -} diff --git a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/TestObject.java b/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/TestObject.java deleted file mode 100644 index d435ae1f3..000000000 --- a/spring-datastore-riak/src/test/java/org/springframework/datastore/riak/core/TestObject.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010 by J. Brisbin - * - * 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. - */ - -package org.springframework.datastore.riak.core; - -/** - * @author J. Brisbin - */ -public class TestObject { - String test = "value"; - Integer integer = 12; - - public String getTest() { - return test; - } - - public void setTest(String test) { - this.test = test; - } - - public Integer getInteger() { - return integer; - } - - public void setInteger(Integer integer) { - this.integer = integer; - } -}