All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.basho.riak.client.bucket.DomainBucket Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * This file is provided to you 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 com.basho.riak.client.bucket;

import com.basho.riak.client.RiakException;
import com.basho.riak.client.builders.DomainBucketBuilder;
import com.basho.riak.client.cap.ConflictResolver;
import com.basho.riak.client.cap.Mutation;
import com.basho.riak.client.cap.MutationProducer;
import com.basho.riak.client.cap.Retrier;
import com.basho.riak.client.convert.Converter;
import com.basho.riak.client.convert.KeyUtil;
import com.basho.riak.client.convert.RiakKey;
import com.basho.riak.client.operations.DeleteObject;
import com.basho.riak.client.operations.FetchObject;
import com.basho.riak.client.operations.StoreObject;
import com.basho.riak.client.raw.DeleteMeta;
import com.basho.riak.client.raw.FetchMeta;
import com.basho.riak.client.raw.StoreMeta;

/**
 * A domain bucket is a wrapper around a {@link Bucket} that is strongly typed and uses
 * a preset {@link ConflictResolver}, {@link MutationProducer}, {@link Converter}, r, w, dw, rw, {@link Retrier},
 * returnBody etc
 * 
 * 

* If you are working with one specific type of data only it can be simpler to * create a {@link DomainBucket} around your bucket. It reduces the amount of * code since the {@link Converter}, {@link Mutation}, {@link Retrier} and * {@link ConflictResolver} are likely to be the same for each operation. *

*

* Example: *

 * final Bucket b = client.createBucket(bucketName).allowSiblings(true).nVal(3).execute();
 * 
 * final DomainBucket carts = DomainBucket.builder(b, ShoppingCart.class)
 *          .withResolver(new MergeCartResolver())
 *          .returnBody(true)
 *          .retrier(DefaultRetrier.attempts(3))
 *          .w(1)
 *          .dw(1)
 *          .r(1)
 *          .rw(1)
 *          .build();
 * 
 *  final ShoppingCart cart = new ShoppingCart(userId);
 * 
 *  cart.addItem("coffee");
 *  cart.addItem("fixie");
 *  cart.addItem("moleskine");
 * 
 *  final ShoppingCart storedCart = carts.store(cart);
 *  ShoppinCart cart2 = carts.fetch("userX");
 *  cart.addItem("toaster");
 *  carts.store(cart2);
 *  //etc
 * 
*

* * @author russell * @see RiakBucket * @see DomainBucketBuilder * */ public class DomainBucket { private final Bucket bucket; private final ConflictResolver resolver; private final Converter converter; private final MutationProducer mutationProducer; private final StoreMeta storeMeta; private final FetchMeta fetchMeta; private final DeleteMeta deleteMeta; private final Class clazz; private final Retrier retrier; /** * Create a new {@link DomainBucket} for clazz Class objects * wrapped around bucket * * It is recommended to use the {@link DomainBucketBuilder} rather than this * constructor. * * @param bucket * The bucket to wrap. * @param resolver * the {@link ConflictResolver} * @param converter * the {@link Converter} to use * @param mutationProducer * the {@link MutationProducer} to use * @param storeMeta * the set of store parameters * @param fetchMeta * the set of fetch parameters * @param deleteMeta * the set of delete parameters * @param clazz * the Class type of the DomainBucket * @param retrier * the {@link Retrier} to use for each operation */ public DomainBucket(Bucket bucket, ConflictResolver resolver, Converter converter, MutationProducer mutationProducer, StoreMeta storeMeta, FetchMeta fetchMeta, DeleteMeta deleteMeta, Class clazz, final Retrier retrier) { this.bucket = bucket; this.resolver = resolver; this.converter = converter; this.mutationProducer = mutationProducer; this.storeMeta = storeMeta; this.fetchMeta = fetchMeta; this.deleteMeta = deleteMeta; this.clazz = clazz; this.retrier = retrier; } /** * Store o in Riak. * T must have a field annotated with {@link RiakKey}. * *

* This is equivalent to creating and executing a {@link StoreObject} * operation with the {@link Converter}, {@link ConflictResolver}, * {@link Retrier}, and a {@link Mutation} (from calling * {@link MutationProducer#produce(Object)} on o), r, w, dw * etc. passed when the DomainBucket was constructed. *

* * @param o * instance of to store. * @return stored instance of T * @throws RiakException */ public T store(T o) throws RiakException { final Mutation mutation = mutationProducer.produce(o); final StoreObject so = bucket.store(o) .withConverter(converter) .withMutator(mutation) .withResolver(resolver) .withRetrier(retrier); if (fetchMeta.getR() != null) { so.r(fetchMeta.getR()); } if (storeMeta.hasW()) { so.w(storeMeta.getW()); } if (storeMeta.hasDw()) { so.dw(storeMeta.getDw()); } if (fetchMeta.hasPr()) { so.pr(fetchMeta.getPr()); } if (storeMeta.hasPw()) { so.pw(storeMeta.getPw()); } if (fetchMeta.hasBasicQuorum()) { so.basicQuorum(fetchMeta.getBasicQuorum()); } if (fetchMeta.hasNotFoundOk()) { so.notFoundOK(fetchMeta.getNotFoundOK()); } if (storeMeta.hasIfNotModified()) { so.ifNotModified(storeMeta.isIfNotModified()); } if (storeMeta.hasIfNoneMatch()) { so.ifNoneMatch(storeMeta.isIfNoneMatch()); } if (fetchMeta.hasReturnDeletedVClock()) { so.returnDeletedVClock(fetchMeta.getReturnDeletedVClock()); } if (storeMeta.hasReturnBody()) { so.returnBody(storeMeta.getReturnBody()); } return so.execute(); } /** * Fetch data stored at key in this bucket as an instance of * T. * *

* This is equivalent to creating and executing a {@link FetchObject} * configured with the {@link Converter}, {@link ConflictResolver}, * {@link Retrier} and r value specified in the constructor. *

* * @param key * @return * @throws RiakException */ public T fetch(String key) throws RiakException { final FetchObject fo = bucket.fetch(key, clazz) .withConverter(converter) .withResolver(resolver) .withRetrier(retrier); if (fetchMeta.hasR()) { fo.r(fetchMeta.getR()); } if (fetchMeta.hasPr()) { fo.pr(fetchMeta.getPr()); } if (fetchMeta.hasBasicQuorum()) { fo.basicQuorum(fetchMeta.getBasicQuorum()); } if (fetchMeta.hasNotFoundOk()) { fo.notFoundOK(fetchMeta.getNotFoundOK()); } return fo.execute(); } /** * Fetch data stored at the key extracted from o's * {@link RiakKey} annotated field as an instance of * T. * *

* This is equivalent to creating and executing a {@link FetchObject} * configured with the {@link Converter}, {@link ConflictResolver}, * {@link Retrier} and r value specified in the constructor. *

* * @param key * @return * @throws RiakException */ public T fetch(T o) throws RiakException { final FetchObject fo = bucket.fetch(o) .withConverter(converter) .withResolver(resolver) .withRetrier(retrier); if (fetchMeta.hasR()) { fo.r(fetchMeta.getR()); } if (fetchMeta.hasPr()) { fo.pr(fetchMeta.getPr()); } if (fetchMeta.hasBasicQuorum()) { fo.basicQuorum(fetchMeta.getBasicQuorum()); } if (fetchMeta.hasNotFoundOk()) { fo.notFoundOK(fetchMeta.getNotFoundOK()); } return fo.execute(); } /** * Delete the key/value stored at the key extracted from o's * {@link RiakKey} annotated field. * *

* This is equivalent to creating and executing a {@link DeleteObject} * configured with the {@link Retrier} and r value specified in the * constructor. *

* * @param key * @return * @throws RiakException */ public void delete(T o) throws RiakException { final String key = KeyUtil.getKey(o); delete(key); } /** * Delete the key/value stored at the key * *

* This is equivalent to creating and executing a {@link DeleteObject} * configured with the {@link Retrier} and r value specified in the * constructor. *

* * @param key * @return * @throws RiakException */ public void delete(String key) throws RiakException { final DeleteObject delete = bucket.delete(key).withRetrier(retrier); if (deleteMeta.hasR()) { delete.r(deleteMeta.getR()); } if (deleteMeta.hasPr()) { delete.pr(deleteMeta.getPr()); } if (deleteMeta.hasW()) { delete.w(deleteMeta.getW()); } if (deleteMeta.hasDw()) { delete.dw(deleteMeta.getDw()); } if (deleteMeta.hasPw()) { delete.pw(deleteMeta.getPw()); } delete.fetchBeforeDelete(deleteMeta.hasVclock()); delete.execute(); } /** * Factory method to create a new {@link DomainBucketBuilder} for the given {@link Bucket} and Class. * @param b * the Bucket to wrap * @param clazz the type of object to store/fetch with the new {@link DomainBucket} * @return a DomainBucketBuilder for the wrapped bucket */ public static DomainBucketBuilder builder(Bucket b, Class clazz) { return new DomainBucketBuilder(b, clazz); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy