M
- type of Message
that underlying records will use@API(value=UNSTABLE) public class TransformedRecordSerializer<M extends Message> extends Object implements RecordSerializer<M>
RecordSerializer
implementation that transforms the bytes produced
by another serializer before returning (and likewise performs the reverse
transformation before deserializing). At the moment, the transformations
are encryption and compression, but other transformations could be
added in the future.
This serializer will begin each serialized string with a one-byte prefix containing information about which transformations were performed. This way, when deserializing, it can detect which transformations were applied so it knows which ones it needs to use to restore the original record. This also allows it to do things like decide not to compress records, even if compression is turned on, if the compression algorithm actually produces a byte array that is larger than the raw record, for example.
This base class does not itself support encryption: an exception will be thrown
when trying to construct a serializer with encryption enabled or when encountering
a serialized record that requires decryption. Subclasses, such as TransformedRecordSerializerJCE
,
implement encryption and have additional state like secret keys.
It is designed to be compatible with the DynamicMessageRecordSerializer
insofar as it can deserialize records written by that serializer, though
records serialized by this class cannot be read by instances of that class.
In the future, we might remove that capability (when all existing data
have been migrated to use this class).
Modifier and Type | Class and Description |
---|---|
static class |
TransformedRecordSerializer.Builder<M extends Message>
Builder class for the
TransformedRecordSerializer class. |
protected static class |
TransformedRecordSerializer.TransformState |
RecordSerializer.Counts, RecordSerializer.Events
Modifier and Type | Field and Description |
---|---|
protected int |
compressionLevel |
protected boolean |
compressWhenSerializing |
protected static int |
DEFAULT_COMPRESSION_LEVEL |
protected static int |
ENCODING_CLEAR |
protected static int |
ENCODING_COMPRESSED |
protected static int |
ENCODING_ENCRYPTED |
protected static int |
ENCODING_PROTO_MESSAGE_FIELD |
protected static int |
ENCODING_PROTO_TYPE_MASK |
protected boolean |
encryptWhenSerializing |
protected RecordSerializer<M> |
inner |
protected static int |
MAX_COMPRESSION_VERSION |
protected static int |
MIN_COMPRESSION_VERSION |
Modifier | Constructor and Description |
---|---|
protected |
TransformedRecordSerializer(RecordSerializer<M> inner,
boolean compressWhenSerializing,
int compressionLevel,
boolean encryptWhenSerializing) |
protected static final int ENCODING_ENCRYPTED
protected static final int ENCODING_CLEAR
protected static final int ENCODING_COMPRESSED
protected static final int ENCODING_PROTO_MESSAGE_FIELD
protected static final int ENCODING_PROTO_TYPE_MASK
protected static final int DEFAULT_COMPRESSION_LEVEL
protected static final int MIN_COMPRESSION_VERSION
protected static final int MAX_COMPRESSION_VERSION
@Nonnull protected final RecordSerializer<M extends Message> inner
protected final boolean compressWhenSerializing
protected final int compressionLevel
protected final boolean encryptWhenSerializing
protected TransformedRecordSerializer(@Nonnull RecordSerializer<M> inner, boolean compressWhenSerializing, int compressionLevel, boolean encryptWhenSerializing)
protected void compress(@Nonnull TransformedRecordSerializer.TransformState state, @Nullable StoreTimer timer)
protected void encrypt(@Nonnull TransformedRecordSerializer.TransformState state, @Nullable StoreTimer timer) throws GeneralSecurityException
GeneralSecurityException
@Nonnull public byte[] serialize(@Nonnull RecordMetaData metaData, @Nonnull RecordType recordType, @Nonnull M record, @Nullable StoreTimer timer)
RecordSerializer
MessageLite.toByteArray()
method for serialization,
record stores may elect to first wrap the raw Protobuf record in another
wrapping type or perform additional transformations like encrypt or
compress records. Implementors of this interface can control how
exactly which transformations are done, with the main constraint being
that whatever operation is done should be reversible by calling the
deserialize()
method on those bytes. Implementors should also be careful as they
evolve this method that the deserialize
method is still able
to read older data unless they are certain that any record store that
used the older implementation has since been cleared out or migrated
to a newer format.serialize
in interface RecordSerializer<M extends Message>
metaData
- the store's meta-datarecordType
- the record type of the messagerecord
- the Protobuf record to serializetimer
- a timer used to instrument serializationprotected void decompress(@Nonnull TransformedRecordSerializer.TransformState state, @Nullable StoreTimer timer) throws DataFormatException
DataFormatException
protected void decrypt(@Nonnull TransformedRecordSerializer.TransformState state, @Nullable StoreTimer timer) throws GeneralSecurityException
GeneralSecurityException
@Nonnull public M deserialize(@Nonnull RecordMetaData metaData, @Nonnull Tuple primaryKey, @Nonnull byte[] serialized, @Nullable StoreTimer timer)
RecordSerializer
serialize()
method.deserialize
in interface RecordSerializer<M extends Message>
metaData
- the store's meta-dataprimaryKey
- the primary key of the recordserialized
- the serialized bytestimer
- a timer used to instrument deserialization@Nonnull public RecordSerializer<Message> widen()
RecordSerializer
widen
that serializer and return the result wrapped equivalently.
If a FDBTypedRecordStore
is created without calling
FDBTypedRecordStore.Builder.setUntypedSerializer(com.apple.foundationdb.record.provider.common.RecordSerializer<com.google.protobuf.Message>)
, then
in order to make the untyped record store that is paired with the typed store (used, for instance, to rebuild indexes),
the given typed serializer will be widened by calling this method.
widen
in interface RecordSerializer<M extends Message>
public static TransformedRecordSerializer.Builder<Message> newDefaultBuilder()
TransformedRecordSerializer.Builder
instance
that is backed by the default serializer for Message
s, namely
a DynamicMessageRecordSerializer
. Methods on the returned
Builder
instance can be used to specify which transformations
to apply after using the default serializer.Builder
instance backed by a DynamicMessageRecordSerializer
public static <M extends Message> TransformedRecordSerializer.Builder<M> newBuilder(@Nonnull RecordSerializer<M> inner)
TransformedRecordSerializer.Builder
instance around
the given serializer. Methods on the Builder
instance can be used to
specify which transformations after using the provided serializer.M
- type of Message
that underlying records will useinner
- RecordSerializer
to use before/after applying transformationsBuilder
instance that can be used to specify transformations