0

I am in the process of migrating my Java code from Riak Client 1.4 to Riak Client 2.0.

I'm storing a BinaryValue in Riak 2.0, encapsulated in a RiakObject. I need to provide my own ConflictResolver to deal with siblings, but in order to do that I need to pull in other data. This data is derived from the key of the stored object.

In Riak 1.4, I used IRiakObject, which exposed getKey(). RiakObject of Riak 2.0 does not offer this.

How is it possible to determine the Location (specifically the key) of the object during ConflictResolver.resolve(List<RiakObject> siblings)?

Hank
  • 4,597
  • 5
  • 42
  • 84

1 Answers1

2

Not sure if this is the best approach, but it seems to work:

  1. Create a POJO as a container for the binary data. Annotate a String field with @RiakKey:

    public class Chunk {
    
        @RiakKey
        public String   chunkId;
    
        public byte[]   data;
    }
    
  2. Create a custom converter:

    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. Register the converter from #2 for the class from #1:

    ConverterFactory.getInstance().registerConverterForClass(Chunk.class, new ChunkConverter());
    
  4. Create a conflict resolver for the class from #1:

    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. Register the new conflict resolver from #4 for the class from #1:

    ConflictResolverFactory.getInstance().registerConflictResolver(Chunk.class, new ChunkResolver());
    
  6. When fetching the object from Riak, specify the class from #1 as type of value:

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

During the conversion, the context of the object is transferred, observing the annotations. The custom converter only needs to transfer the value-part of the data.

Hank
  • 4,597
  • 5
  • 42
  • 84