在解决冲突期间确定 RiakObject 的位置

Determine Location of RiakObject during conflict resolution

我正在将我的 Java 代码从 Riak Client 1.4 迁移到 Riak Client 2.0。

我在 Riak 2.0 中存储 BinaryValue,封装在 RiakObject 中。我需要提供自己的 ConflictResolver 来处理兄弟姐妹,但为了做到这一点,我需要引入其他数据。此数据源自存储对象的键。

在 Riak 1.4 中,我使用了 IRiakObject,暴露了 getKey()RiakObject Riak 2.0 不提供此功能。

如何在ConflictResolver.resolve(List<RiakObject> siblings)期间确定对象的Location(特别是键)?

不确定这是否是最佳方法,但它似乎有效:

  1. 创建一个 POJO 作为二进制数据的容器。使用 @RiakKey:

    注释 String 字段
    public class Chunk {
    
        @RiakKey
        public String   chunkId;
    
        public byte[]   data;
    }
    
  2. 创建自定义转换器:

    import com.basho.riak.client.api.convert.ConversionException;
    import com.basho.riak.client.api.convert.Converter;
    import com.basho.riak.client.core.util.BinaryValue;
    public class ChunkConverter extends Converter<Chunk> {
    
        public ChunkConverter() {
            super(Chunk.class);
        }
    
        public Chunk toDomain(BinaryValue val, String contentType) throws ConversionException {
            Chunk chunk = newDomainInstance();
            chunk.data = val.getValue();
        }
    
        public ContentAndType fromDomain(Chunk chunk) throws ConversionException {
            return new ContentAndType(BinaryValue.unsafeCreate(chunk.data), "application/octet-stream");
        }
    }
    
  3. 为#1 的 class 注册 #2 的转换器:

    ConverterFactory.getInstance().registerConverterForClass(Chunk.class, new ChunkConverter());
    
  4. 为来自 #1:

    的 class 创建冲突解决程序
    public class ChunkConflictResolver implements ConflictResolver<Chunk> {
    
        public Chunk resolve(List<Chunk> siblings) throws UnresolvedConflictException {
            if (siblings == null) {
                return null;
            }
            Chunk oneChunk = siblings.get(0);
            // finally, the key!
            String key = oneChunk.chunkId;
            ...
        }
    }
    
  5. 为#1 中的class 注册#4 中的新冲突解决程序:

    ConflictResolverFactory.getInstance().registerConflictResolver(Chunk.class, new ChunkResolver());
    
  6. 从 Riak 获取对象时,指定来自 #1 的 class 作为值的类型:

    Location loc = new Location(...);
    FetchValue op = new FetchValue.Builder(loc).build();
    Chunk chunk = riakClient.execute(op).getValue(Chunk.class);
    

在转换过程中,对象的上下文被转移,观察annotations。自定义转换器只需要传输数据的值部分。