/** * Creates a new {@link BinaryMessageEncoder} that uses the given * {@link GenericData data model} to construct datum instances described by * the {@link Schema schema}. * <p> * The {@code readSchema} is used as the expected schema (read schema). Datum * instances created by this class will are described by the expected schema. * <p> * The schema used to decode incoming buffers is determined by the schema * fingerprint encoded in the message header. This class can decode messages * that were encoded using the {@code readSchema}, other schemas that are * added using {@link #addSchema(Schema)}, or schemas returned by the * {@code resolver}. * * @param model the {@link GenericData data model} for datum instances * @param readSchema the {@link Schema} used to construct datum instances * @param resolver a {@link SchemaStore} used to find schemas by fingerprint */ public BinaryMessageDecoder(GenericData model, Schema readSchema, SchemaStore resolver) { this.model = model; this.readSchema = readSchema; this.resolver = resolver; addSchema(readSchema); }
/** * Creates a new {@link BinaryMessageEncoder} that uses the given * {@link GenericData data model} to construct datum instances described by * the {@link Schema schema}. * <p> * The {@code readSchema} is used as the expected schema (read schema). Datum * instances created by this class will are described by the expected schema. * <p> * The schema used to decode incoming buffers is determined by the schema * fingerprint encoded in the message header. This class can decode messages * that were encoded using the {@code readSchema}, other schemas that are * added using {@link #addSchema(Schema)}, or schemas returned by the * {@code resolver}. * * @param model the {@link GenericData data model} for datum instances * @param readSchema the {@link Schema} used to construct datum instances * @param resolver a {@link SchemaStore} used to find schemas by fingerprint */ public BinaryMessageDecoder(GenericData model, Schema readSchema, SchemaStore resolver) { this.model = model; this.readSchema = readSchema; this.resolver = resolver; addSchema(readSchema); }
private RawMessageDecoder<D> getDecoder(long fp) { RawMessageDecoder<D> decoder = codecByFingerprint.get(fp); if (decoder != null) { return decoder; } if (resolver != null) { Schema writeSchema = resolver.findByFingerprint(fp); if (writeSchema != null) { addSchema(writeSchema); return codecByFingerprint.get(fp); } } throw new MissingSchemaException( "Cannot resolve schema for fingerprint: " + fp); }
private RawMessageDecoder<D> getDecoder(long fp) { RawMessageDecoder<D> decoder = codecByFingerprint.get(fp); if (decoder != null) { return decoder; } if (resolver != null) { Schema writeSchema = resolver.findByFingerprint(fp); if (writeSchema != null) { addSchema(writeSchema); return codecByFingerprint.get(fp); } } throw new MissingSchemaException( "Cannot resolve schema for fingerprint: " + fp); }
@Test public void testSchemaEvolution() throws Exception { List<ByteBuffer> buffers = new ArrayList<>(); List<Record> records = new ArrayList<>(); records.addAll(V1_RECORDS); records.addAll(V2_RECORDS); MessageEncoder<Record> v1Encoder = new BinaryMessageEncoder<>(GenericData.get(), SCHEMA_V1); MessageEncoder<Record> v2Encoder = new BinaryMessageEncoder<>(GenericData.get(), SCHEMA_V2); for (Record record : records) { if (record.getSchema() == SCHEMA_V1) { buffers.add(v1Encoder.encode(record)); } else { buffers.add(v2Encoder.encode(record)); } } Set<Record> allAsV2 = new HashSet<>(V2_RECORDS); allAsV2.add(V2_BUILDER.set("id", 1L).set("message", "m-1").clear("data").build()); allAsV2.add(V2_BUILDER.set("id", 2L).set("message", "m-2").clear("data").build()); allAsV2.add(V2_BUILDER.set("id", 4L).set("message", "m-4").clear("data").build()); allAsV2.add(V2_BUILDER.set("id", 6L).set("message", "m-6").clear("data").build()); BinaryMessageDecoder<Record> v2Decoder = new BinaryMessageDecoder<>(GenericData.get(), SCHEMA_V2); v2Decoder.addSchema(SCHEMA_V1); Set<Record> decodedUsingV2 = new HashSet<>(); for (ByteBuffer buffer : buffers) { decodedUsingV2.add(v2Decoder.decode(buffer)); } Assert.assertEquals(allAsV2, decodedUsingV2); }
@Test public void testCompatibleReadWithSchema() throws Exception { MessageEncoder<Record> v1Encoder = new BinaryMessageEncoder<>(GenericData.get(), SCHEMA_V1); BinaryMessageDecoder<Record> v2Decoder = new BinaryMessageDecoder<>(GenericData.get(), SCHEMA_V2); v2Decoder.addSchema(SCHEMA_V1); ByteBuffer v1Buffer = v1Encoder.encode(V1_RECORDS.get(3)); Record record = v2Decoder.decode(v1Buffer); Assert.assertEquals( V2_BUILDER.set("id", 6L).set("message", "m-6").clear("data").build(), record); }
/** * Creates a new {@link BinaryMessageEncoder} that uses the given * {@link GenericData data model} to construct datum instances described by * the {@link Schema schema}. * <p> * The {@code readSchema} is used as the expected schema (read schema). Datum * instances created by this class will are described by the expected schema. * <p> * The schema used to decode incoming buffers is determined by the schema * fingerprint encoded in the message header. This class can decode messages * that were encoded using the {@code readSchema}, other schemas that are * added using {@link #addSchema(Schema)}, or schemas returned by the * {@code resolver}. * * @param model the {@link GenericData data model} for datum instances * @param readSchema the {@link Schema} used to construct datum instances * @param resolver a {@link SchemaStore} used to find schemas by fingerprint */ public BinaryMessageDecoder(GenericData model, Schema readSchema, SchemaStore resolver) { this.model = model; this.readSchema = readSchema; this.resolver = resolver; addSchema(readSchema); }
private RawMessageDecoder<D> getDecoder(long fp) { RawMessageDecoder<D> decoder = codecByFingerprint.get(fp); if (decoder != null) { return decoder; } if (resolver != null) { Schema writeSchema = resolver.findByFingerprint(fp); if (writeSchema != null) { addSchema(writeSchema); return codecByFingerprint.get(fp); } } throw new MissingSchemaException( "Cannot resolve schema for fingerprint: " + fp); }