@Override protected BucketProperties convert(List<RiakPB.RpbGetBucketResp> rawResponse) throws ExecutionException { // This isn't streaming, there will only be one response. RiakPB.RpbBucketProps pbProps = rawResponse.get(0).getProps(); BucketProperties props = new BucketProperties() .withNVal(pbProps.getNVal()) .withAllowMulti(pbProps.getAllowMult()) .withLastWriteWins(pbProps.getLastWriteWins()) .withOldVClock(Operations.getUnsignedIntValue(pbProps.getOldVclock())) .withYoungVClock(Operations.getUnsignedIntValue(pbProps.getYoungVclock())) .withBigVClock(Operations.getUnsignedIntValue(pbProps.getBigVclock())) .withSmallVClock(Operations.getUnsignedIntValue(pbProps.getSmallVclock())) .withPr(pbProps.getPr()) .withR(pbProps.getR()) .withW(pbProps.getW()) .withPw(pbProps.getPw()) .withDw(pbProps.getDw()) .withRw(pbProps.getRw()) .withBasicQuorum(pbProps.getBasicQuorum()) .withNotFoundOk(pbProps.getNotfoundOk()) .withRiakSearchEnabled(pbProps.getSearch()) .withChashkeyFunction( new Function.Builder() .withModule(pbProps.getChashKeyfun().getModule().toStringUtf8()) .withFunction(pbProps.getChashKeyfun().getFunction().toStringUtf8()) .build()); if (pbProps.hasLinkfun()) { props.withLinkwalkFunction( new Function.Builder() .withModule(pbProps.getLinkfun().getModule().toStringUtf8()) .withFunction(pbProps.getLinkfun().getFunction().toStringUtf8()) .build()); } if (pbProps.hasHasPrecommit()) { for (Function f : parseHooks(pbProps.getPrecommitList())) { props.withPrecommitHook(f); } } if (pbProps.hasHasPostcommit()) { for (Function f : parseHooks(pbProps.getPostcommitList())) { props.withPostcommitHook(f); } } if (pbProps.hasYzIndex()) { props.withYokozunaIndex(pbProps.getYzIndex().toStringUtf8()); } if (pbProps.hasBackend()) { props.withBackend(pbProps.getBackend().toStringUtf8()); } return props; }
abstract static class PropsBuilder<T extends PropsBuilder<T>> { protected final RiakPB.RpbBucketProps.Builder propsBuilder = RiakPB.RpbBucketProps.newBuilder(); protected abstract T self(); /** * Set the allow_multi value. * * @param allow whether to allow sibling objects to be created. * @return a reference to this object. */ public T withAllowMulti(boolean allow) { propsBuilder.setAllowMult(allow); return self(); } /** * Set the backend used by this bucket. Only applies when using {@code riak_kv_multi_backend} in * Riak. * * @param backend the name of the backend to use. * @return a reference to this object. */ public T withBackend(String backend) { if (null == backend || backend.length() == 0) { throw new IllegalArgumentException("Backend can not be null or zero length"); } propsBuilder.setBackend(ByteString.copyFromUtf8(backend)); return self(); } /** * Set the basic_quorum value. * * <p>The parameter controls whether a read request should return early in some fail cases. E.g. * If a quorum of nodes has already returned notfound/error, don't wait around for the rest. * * @param use the basic_quorum value. * @return a reference to this object. */ public T withBasicQuorum(boolean use) { propsBuilder.setBasicQuorum(use); return self(); } /** * Set the big_vclock value. * * @param bigVClock a long representing a epoch time value. * @return a reference to this object. * @see <a * href="http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/#Vector-Clock-Pruning">Vector * Clock Pruning</a> */ public T withBigVClock(Long bigVClock) { propsBuilder.setBigVclock(bigVClock.intValue()); return self(); } /** * Set the chash_keyfun value. * * @param func a Function representing the Erlang func to use. * @return a reference to this object. */ public T withChashkeyFunction(Function func) { verifyErlangFunc(func); propsBuilder.setChashKeyfun(convertModFun(func)); return self(); } /** * Set the last_write_wins value. Unless you really know what you're doing, you probably do not * want to set this to true. * * @param wins whether to ignore vector clocks when writing. * @return a reference to this object. */ public T withLastWriteWins(boolean wins) { propsBuilder.setLastWriteWins(wins); return self(); } /** * Set the linkfun value. * * @param func a Function representing the Erlang func to use. * @return a reference to this object. */ public T withLinkwalkFunction(Function func) { verifyErlangFunc(func); propsBuilder.setLinkfun(convertModFun(func)); return self(); } /** * Set the rw value. Individual requests (or buckets in a bucket type) can override this. * * @param rw the rw value as an integer. * @return a reference to this object. */ public T withRw(int rw) { propsBuilder.setRw(rw); return self(); } /** * Set the dw value. Individual requests (or buckets in a bucket type) can override this. * * @param dw the dw value as an integer. * @return a reference to this object. */ public T withDw(int dw) { propsBuilder.setDw(dw); return self(); } /** * Set the w value. Individual requests (or buckets in a bucket type) can override this. * * @param w the w value as an integer. * @return a reference to this object. */ public T withW(int w) { propsBuilder.setW(w); return self(); } /** * Set the r value. Individual requests (or buckets in a bucket type) can override this. * * @param r the r value as an integer. * @return a reference to this object. */ public T withR(int r) { propsBuilder.setR(r); return self(); } /** * Set the pr value. Individual requests (or buckets in a bucket type) can override this. * * @param pr the pr value as an integer. * @return a reference to this object. */ public T withPr(int pr) { propsBuilder.setPr(pr); return self(); } /** * Set the pw value. Individual requests (or buckets in a bucket type) can override this. * * @param pw the pw value as an integer. * @return a reference to this object. */ public T withPw(int pw) { propsBuilder.setPw(pw); return self(); } /** * Set the not_found_ok value. If true a vnode returning notfound for a key increments the r * tally. False is higher consistency, true is higher availability. * * @param ok the not_found_ok value. * @return a reference to this object. */ public T withNotFoundOk(boolean ok) { propsBuilder.setNotfoundOk(ok); return self(); } /** * Add a pre-commit hook. The supplied Function must be an Erlang or Named JS function. * * @param hook the Function to add. * @return a reference to this object. * @see <a href="http://docs.basho.com/riak/latest/dev/using/commit-hooks/">Using Commit * Hooks</a> */ public T withPrecommitHook(Function hook) { if (null == hook || !(!hook.isJavascript() || hook.isNamed())) { throw new IllegalArgumentException("Must be a named JS or Erlang function."); } propsBuilder.addPrecommit(convertHook(hook)); return self(); } /** * Add a post-commit hook. The supplied Function must be an Erlang or Named JS function. * * @param hook the Function to add. * @return a reference to this object. * @see <a href="http://docs.basho.com/riak/latest/dev/using/commit-hooks/">Using Commit * Hooks</a> */ public T withPostcommitHook(Function hook) { verifyErlangFunc(hook); propsBuilder.addPostcommit(convertHook(hook)); return self(); } /** * Set the old_vclock value. * * @param oldVClock an long representing a epoch time value. * @return a reference to this object. * @see <a * href="http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/#Vector-Clock-Pruning">Vector * Clock Pruning</a> */ public T withOldVClock(Long oldVClock) { propsBuilder.setOldVclock(oldVClock.intValue()); return self(); } /** * Set the young_vclock value. * * @param youngVClock a long representing a epoch time value. * @return a reference to this object. * @see <a * href="http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/#Vector-Clock-Pruning">Vector * Clock Pruning</a> */ public T withYoungVClock(Long youngVClock) { propsBuilder.setYoungVclock(youngVClock.intValue()); return self(); } /** * Set the small_vclock value. * * @param smallVClock a long representing a epoch time value. * @return a reference to this object. * @see <a * href="http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/#Vector-Clock-Pruning">Vector * Clock Pruning</a> */ public T withSmallVClock(Long smallVClock) { propsBuilder.setSmallVclock(smallVClock.intValue()); return self(); } /** * Set the nVal. * * @param nVal the number of replicas. * @return a reference to this object. */ public T withNVal(int nVal) { if (nVal <= 0) { throw new IllegalArgumentException("nVal must be >= 1"); } propsBuilder.setNVal(nVal); return self(); } /** * Enable Legacy Riak Search. Setting this to true causes the search pre-commit hook to be * added. * * <p><b>Note this is only for legacy Riak (< v2.0) Search support.</b> * * @param enable add/remove (true/false) the pre-commit hook for Legacy Riak Search. * @return a reference to this object. */ public T withLegacyRiakSearchEnabled(boolean enable) { propsBuilder.setSearch(enable); return self(); } /** * Associate a Search Index. This only applies if Yokozuna is enabled in Riak v2.0. * * @param indexName The name of the search index to use. * @return a reference to this object. */ public T withSearchIndex(String indexName) { if (null == indexName || indexName.length() == 0) { throw new IllegalArgumentException("Index name cannot be null or zero length"); } propsBuilder.setSearchIndex(ByteString.copyFromUtf8(indexName)); return self(); } private void verifyErlangFunc(Function f) { if (null == f || f.isJavascript()) { throw new IllegalArgumentException("Must be an Erlang Function."); } } private RiakPB.RpbModFun convertModFun(Function f) { return RiakPB.RpbModFun.newBuilder() .setModule(ByteString.copyFromUtf8(f.getModule())) .setFunction(ByteString.copyFromUtf8(f.getFunction())) .build(); } private RiakPB.RpbCommitHook convertHook(Function hook) { RiakPB.RpbCommitHook.Builder builder = RiakPB.RpbCommitHook.newBuilder(); RiakPB.RpbModFun.Builder mfBuilder = RiakPB.RpbModFun.newBuilder(); if (hook.isJavascript()) { builder.setName(ByteString.copyFromUtf8(hook.getName())); } else { mfBuilder.setModule(ByteString.copyFromUtf8(hook.getModule())); mfBuilder.setFunction(ByteString.copyFromUtf8(hook.getFunction())); builder.setModfun(mfBuilder); } return builder.build(); } }