kv-4.0.9.src.oracle.kv.avro.RawAvroBinding Maven / Gradle / Ivy
Show all versions of oracle-nosql-client Show documentation
/*-
*
* This file is part of Oracle NoSQL Database
* Copyright (C) 2011, 2016 Oracle and/or its affiliates. All rights reserved.
*
* If you have received this file as part of Oracle NoSQL Database the
* following applies to the work as a whole:
*
* Oracle NoSQL Database server software is free software: you can
* redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation,
* version 3.
*
* Oracle NoSQL Database is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* If you have received this file as part of Oracle NoSQL Database Client or
* distributed separately the following applies:
*
* Oracle NoSQL Database client software is free software: you can
* redistribute it and/or modify it under the terms of the Apache License
* as published by the Apache Software Foundation, version 2.0.
*
* You should have received a copy of the GNU Affero General Public License
* and/or the Apache License in the LICENSE file along with Oracle NoSQL
* Database client or server distribution. If not, see
*
* or
* .
*
* An active Oracle commercial licensing agreement for this product supersedes
* these licenses and in such case the license notices, but not the copyright
* notice, may be removed by you in connection with your distribution that is
* in accordance with the commercial licensing terms.
*
* For more information please contact:
*
* [email protected]
*
*/
package oracle.kv.avro;
import oracle.kv.Value;
import org.apache.avro.generic.GenericRecord;
/**
* The {@code RawAvroBinding} interface has the same methods as {@link
* AvroBinding}, but represents values as instances of {@link RawRecord}. A
* raw binding is created using {@link AvroCatalog#getRawBinding}.
*
* The trade-offs in using a {@code RawAvroBinding}, compared to other types
* of bindings, are:
*
* - The advantage of a raw binding is that it allows handling the Avro
* serialized byte array directly in the application. In other words, it
* allows "escaping" from the built-in serialization provided by the other
* bindings in this package, when necessary. For example:
*
* The Avro serialization and deserialization APIs may be used
* directly, when none of the built-in bindings in this package are
* appropriate.
*
* The serialized byte array may be copied to or from another
* component or system, without deserializing it.
*
* An application may wish to examine the schema of a value before
* deciding on which binding to use, or whether or not to deserialize the
* value.
*
*
*
* - Because it does not perform serialization, deserialization or class
* evolution, a raw binding is lower level and more difficult to use than the
* other built-in buildings. WARNING: When using a raw binding, it is the
* user's responsibility to ensure that a {@link Value} contains valid
* serialized Avro data, before writing it to the store.
*
*
*
* See {@link AvroCatalog} for general information on Avro bindings and
* schemas. The schemas used in the examples below are described in the {@link
* AvroCatalog} javadoc.
*
* When using a {@code RawAvroBinding}, a {@link RawRecord} is used to
* represent values. A {@link RawRecord} contains the raw Avro serialized byte
* array and its associated schema.
*
* The only purpose of a raw binding is to package and unpackage the Avro
* serialized data and the internal schema identifier. These are stored
* together in the byte array of the {@link Value} object, using an internal
* format known to the binding.
*
* No schema is specified when calling {@link AvroCatalog#getRawBinding}, no
* class evolution is performed by a raw binding's {@link #toObject toObject}
* method, and the binding may be used for values with any schema known to the
* store.
*
* The following code fragment demonstrates writing and reading a value using a
* raw binding. The Avro APIs are used directly to perform serialization and
* deserialization. In the example a {@link GenericRecord} is used, but other
* Avro APIs could be used as well.
*
* The example performs the same function as the built-in generic binding
* provided by this class, i.e., the serialization and deserialization sections
* below are equivalent what the built-in generic binding already provides. An
* application would normally use a raw binding along with custom serialization
* done differently than shown below.
*
*
* Schema.Parser parser = new Schema.Parser();
* Schema nameSchema = parser.parse(nameSchemaText);
* Schema memberSchema = parser.parse(memberSchemaText);
*
* RawAvroBinding binding = avroCatalog.getRawBinding();
*
* // Create object
* GenericRecord name = new GenericData.Record(nameSchema)
* name.put("first", ...);
* name.put("last", ...);
* GenericRecord object = new GenericData.Record(memberSchema)
* object.put("name", name);
* object.put("age", new Integer(...));
*
* // Serialize using Avro APIs directly
* ByteArrayOutputStream out = new ByteArrayOutputStream();
* GenericDatumWriter<GenericRecord> writer =
* new GenericDatumWriter<GenericRecord>(object.getSchema());
* Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
* writer.write(object, encoder);
* encoder.flush();
*
* // Package and store
* RawRecord raw = new RawRecord(out.toByteArray(), object.getSchema());
* kvStore.put(key, binding.toValue(raw));
*
* // Sometime later, retrieve and unpackage
* ValueVersion vv = kvStore.get(key);
* RawRecord raw = binding.toObject(vv.getValue());
*
* // Deserialize using Avro APIs directly
* Decoder decoder =
* DecoderFactory.get().binaryDecoder(raw.getRawData(), null);
* GenericDatumReader<GenericRecord> reader =
* new GenericDatumReader<GenericRecord>(raw.getSchema());
* GenericRecord object = reader.read(null, decoder);
*
* // Use object
* GenericRecord name = (GenericRecord) object.get("name");
* Integer age = (Integer) object.get("age");
* ...
*
* The following code fragment demonstrates reading values and examining
* their schema using a raw binding, without performing deserialization.
* Another binding could be used to deserialize the value, if desired,
* after examining the schema. Or, the serialized byte array could be
* copied to or from another component or system, without deserializing it.
*
*
* RawAvroBinding binding = avroCatalog.getRawBinding();
*
* Iterator<KeyValueVersion> iter = kvStore.multiGetIterator(...);
* for (KeyValueVersion kvv : iter) {
* RawRecord object = binding.toObject(kvv.getValue());
* Schema schema = object.getSchema();
*
* // Use schema to decide how to process the object...
* }
*
* @since 2.0
*
* @deprecated as of 4.0, use the table API instead.
*/
@Deprecated
public interface RawAvroBinding extends AvroBinding {
/**
* {@inheritDoc}
*
* This method does not perform deserialization or class evolution. It only
* unpackages the Avro serialized data and the internal schema identifier.
* These are stored together in the byte array of the {@link Value} object,
* using an internal format known to the binding.
*
* WARNING: When using a raw binding, it is the user's responsibility to
* ensure that a {@link Value} contains valid serialized Avro data, before
* writing it to the store.
*
* @return the {@link RawRecord} instance. The {@link RawRecord#getSchema}
* method will return the writer schema, which is the schema that was
* specified when the value was stored.
*/
@Override
public RawRecord toObject(Value value)
throws IllegalArgumentException;
/**
* {@inheritDoc}
*
* This method does not perform serialization. It only packages the Avro
* serialized data and the internal schema identifier. These are stored
* together in the byte array of the {@link Value} object, using an
* internal format known to the binding.
*
* WARNING: When using a raw binding, it is the user's responsibility to
* ensure that a {@link Value} contains valid serialized Avro data, before
* writing it to the store.
*
* @param object the {@link RawRecord} instance that the user wishes to
* package as a {@link Value}.
*/
@Override
public Value toValue(RawRecord object)
throws UndefinedSchemaException;
}