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)
?
Not sure if this is the best approach, but it seems to work:
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;
}
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");
}
}
Register the converter from #2 for the class from #1:
ConverterFactory.getInstance().registerConverterForClass(Chunk.class, new ChunkConverter());
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;
...
}
}
Register the new conflict resolver from #4 for the class from #1:
ConflictResolverFactory.getInstance().registerConflictResolver(Chunk.class, new ChunkResolver());
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.