oracle.kv.avro

## Interface RawAvroBinding

- All Superinterfaces:
    AvroBinding<RawRecord>, ValueBinding<RawRecord>

      public interface RawAvroBinding
      extends AvroBinding<RawRecord>

  The `RawAvroBinding` interface has the same methods as `AvroBinding`, but represents values as instances of `RawRecord`. A raw binding is created using `AvroCatalog.getRawBinding()`.

  The trade-offs in using a `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 `Value` contains valid serialized Avro data, before writing it to the store.

  See `AvroCatalog` for general information on Avro bindings and schemas. The schemas used in the examples below are described in the `AvroCatalog` javadoc.

  When using a `RawAvroBinding`, a `RawRecord` is used to represent values. A `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 `Value` object, using an internal format known to the binding.

  No schema is specified when calling `AvroCatalog.getRawBinding()`, no class evolution is performed by a raw binding's `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 `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

- - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `RawRecord` | `toObject(Value value)` After doing a read operation using a `KVStore` method, the user calls `toObject` with the `Value` obtained from the read operation.
    `Value` | `toValue(RawRecord object)` Before doing a write operation, the user calls `toValue` passing an object she wishes to store.

- - ### Method Detail

    - #### toObject

          RawRecord toObject(Value value)
                             throws IllegalArgumentException

      After doing a read operation using a `KVStore` method, the user calls `toObject` with the `Value` obtained from the read operation.

      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 `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 `Value` contains valid serialized Avro data, before writing it to the store.

      Specified by:
        `toObject` in interface `AvroBinding<RawRecord>`
      Specified by:
        `toObject` in interface `ValueBinding<RawRecord>`
      Parameters:
        `value` - the `Value` obtained from a `KVStore` read operation method.. The byte array of the `Value` is serialized Avro data, packaged in an internal format that includes a reference to the Avro schema
      Returns:
        the `RawRecord` instance. The `RawRecord.getSchema()` method will return the writer schema, which is the schema that was specified when the value was stored.
      Throws:
        `IllegalArgumentException` - if the value format is not `Value.Format.AVRO`, the schema identifier embedded in the `value` parameter is invalid, or the serialized data cannot be parsed.

    - #### toValue

          Value toValue(RawRecord object)
                        throws UndefinedSchemaException

      Before doing a write operation, the user calls `toValue` passing an object she wishes to store. The resulting `Value` is then passed to the write operation method in `KVStore`.

      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 `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 `Value` contains valid serialized Avro data, before writing it to the store.

      Specified by:
        `toValue` in interface `AvroBinding<RawRecord>`
      Specified by:
        `toValue` in interface `ValueBinding<RawRecord>`
      Parameters:
        `object` - the `RawRecord` instance that the user wishes to package as a `Value`.
      Returns:
        the serialized object.. The byte array of the `Value` is serialized Avro data, packaged in an internal format that includes a reference to the Avro schema
      Throws:
        `UndefinedSchemaException` - if the schema associated with the `object` parameter has not been defined using the NoSQL Database administration interface. Note that when the allowed schemas for a binding are specified (and validate) at the time the binding is created, this exception is extremely unlikely and is only possible if a schema is mistakenly disabled after the binding is created.

Copyright (c) 2011, 2014 Oracle and/or its affiliates. All rights reserved.