Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
29f7f6c
init
arerlend May 1, 2020
ba86f02
Merge remote-tracking branch 'upstream/master'
arerlend May 22, 2020
4e94edf
remove kafka
arerlend May 1, 2020
54d5ad8
azure- artifact ids
arerlend May 8, 2020
98ce87d
azure-core + version change
arerlend May 8, 2020
21b663d
progress snapshot before swapping autorest client
arerlend May 12, 2020
be646ab
swagger generated http client
arerlend May 20, 2020
8fa8f89
update common package
arerlend May 20, 2020
305ffa5
junit engine
arerlend May 20, 2020
7eb5a2f
fix versioning
arerlend May 20, 2020
e13f670
javadoc checkstyle
arerlend May 21, 2020
59c1c07
javadoc checkstyle
arerlend May 21, 2020
492a77e
checkstyle javadoc
arerlend May 22, 2020
07fcff1
spotbugs override for serializing null value
arerlend May 22, 2020
16ec23e
add service client annotation
arerlend May 22, 2020
a6b56a8
service client style
arerlend May 22, 2020
309b0bb
fix dep management tags
arerlend May 22, 2020
51db740
add module-info and initial readme
arerlend May 22, 2020
7492f73
add readme sections
arerlend May 22, 2020
c1ac6c6
fix readme section case
arerlend May 22, 2020
47dba95
add src clients to jacoco
arerlend May 22, 2020
198a030
add latest swagger
arerlend May 22, 2020
24381c0
add basic readme intros
arerlend May 22, 2020
f2a69b4
Merge branch 'master' into arerlend.src
arerlend May 26, 2020
09d2745
Update sdk/schemaregistry/azure-schemaregistry-client/src/main/java/c…
arerlend May 26, 2020
866fe7f
fix comments
arerlend May 26, 2020
abc131d
Merge branch 'arerlend.src' of https://github.com/arerlend/azure-sdk-…
arerlend May 26, 2020
d4e5340
Update sdk/schemaregistry/azure-schemaregistry-client/src/main/java/c…
arerlend May 26, 2020
f0a35a9
default retry policy on null
arerlend May 26, 2020
6199719
Merge branch 'arerlend.src' of https://github.com/arerlend/azure-sdk-…
arerlend May 27, 2020
2a216c3
remove unused headers policy
arerlend May 27, 2020
d25047f
netty dep
arerlend May 27, 2020
9cd191e
hashmap to concurrent hashmap, slf4j format pattern
arerlend May 27, 2020
59d8f9d
builder cleanup
arerlend May 27, 2020
a04c383
remove runtime error from method signature
arerlend May 27, 2020
1656da9
comments
arerlend May 27, 2020
81682bc
change group name
arerlend May 28, 2020
b855cd0
move rest service builder
arerlend May 28, 2020
850201a
update dirs and repo files
arerlend May 28, 2020
6b1ee4e
update package structure
arerlend May 28, 2020
d6e0941
update versioning
arerlend May 28, 2020
c1f7199
fix jacoco test pom
arerlend May 28, 2020
93defa9
fix eng system comments
arerlend May 29, 2020
cea60ee
Update sdk/schemaregistry/azure-data-schemaregistry-avro/pom.xml
arerlend May 29, 2020
6ffe759
Update sdk/schemaregistry/azure-data-schemaregistry-avro/src/main/jav…
arerlend May 29, 2020
e5c40b1
fix comments
arerlend May 29, 2020
101aeeb
spotbugs update
arerlend May 29, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,14 @@
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD"/>
</Match>

<!-- Serializing a null value should return null to allow client to handle null cases
consistently instead of injecting null payload behavior from the payload. -->
<Match>
<Class name="com.azure.data.schemaregistry.avro.SchemaRegistryAvroSerializer"/>
<Method name="serialize"/>
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
</Match>

<!-- Exclude spotbug from non-shipping modules -->
<Match>
<Or>
Expand Down
11 changes: 10 additions & 1 deletion eng/jacoco-test-coverage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@
<artifactId>azure-sdk-template</artifactId>
<version>1.0.4-beta.20</version> <!-- {x-version-update;com.azure:azure-sdk-template;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-schemaregistry</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-data-schemaregistry;current} -->
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-schemaregistry-avro</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-data-schemaregistry-avro;current} -->
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot</artifactId>
Expand All @@ -208,7 +218,6 @@
<version>2.2.5-beta.1</version> <!-- {x-version-update;com.microsoft.azure:azure-keyvault-secrets-spring-boot-starter;current} -->
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
Expand Down
1 change: 1 addition & 0 deletions eng/versioning/external_dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ io.reactivex:rxjava;1.2.4
javax.annotation:javax.annotation-api;1.3.2
javax.servlet:javax.servlet-api;4.0.1
javax.validation:validation-api;2.0.1.Final
org.apache.avro:avro;1.9.2
org.apache.httpcomponents:httpclient;4.3.6
org.apache.logging.log4j:log4j-api;2.11.1
org.apache.logging.log4j:log4j-core;2.11.1
Expand Down
2 changes: 2 additions & 0 deletions eng/versioning/version_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ com.azure:azure-cosmos;4.0.1-beta.3;4.0.1-beta.4
com.azure:azure-cosmos-examples;4.0.1-beta.1;4.0.1-beta.1
com.azure:azure-cosmos-benchmark;4.0.1-beta.1;4.0.1-beta.1
com.azure:azure-data-appconfiguration;1.1.1;1.2.0-beta.1
com.azure:azure-data-schemaregistry;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-data-schemaregistry-avro;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-e2e;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-identity;1.0.6;1.1.0-beta.5
com.azure:azure-identity-perf;1.0.0-beta.1;1.0.0-beta.1
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<module>sdk/keyvault</module>
<module>sdk/loganalytics</module>
<module>sdk/mediaservices</module>
<module>sdk/schemaregistry</module>
<module>sdk/search</module>
<module>sdk/servicebus</module>
<module>sdk/storage</module>
Expand Down
17 changes: 17 additions & 0 deletions sdk/schemaregistry/azure-data-schemaregistry-avro/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Azure Schema Registry Avro Serializer/Deserializer client library for Java

This library contains Avro-specific implementations of Azure Schema Registry-back serializers and deserializers, in addition to builder classes that specify required configurations.

This class requires a Maven dependency on `org.apache.avro:avro:1.9.2`.

## Getting started

## Key concepts

## Examples

## Troubleshooting

## Next steps

## Contributing
97 changes: 97 additions & 0 deletions sdk/schemaregistry/azure-data-schemaregistry-avro/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
~ Copyright (c) Microsoft Corporation. All rights reserved.
~ Licensed under the MIT License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.azure</groupId>
<artifactId>azure-client-sdk-parent</artifactId>
<version>1.7.0</version> <!-- {x-version-update;com.azure:azure-client-sdk-parent;current} -->
<relativePath>../../parents/azure-client-sdk-parent</relativePath>
</parent>

<groupId>com.azure</groupId>
<artifactId>azure-data-schemaregistry-avro</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-data-schemaregistry-avro;current} -->

<name>Microsoft Azure Schema Registry - Avro-specific package for client library</name>
<description>Avro-specific package for Azure Schema Registry client library</description>
<url>https://github.com/Azure/azure-sdk-for-java</url>

<distributionManagement>
<site>
<id>azure-java-build-docs</id>
<url>${site.url}/site/${project.artifactId}</url>
</site>
</distributionManagement>

<scm>
<url>scm:git:https://github.com/Azure/azure-sdk-for-java</url>
<connection>scm:git:git@github.com:Azure/azure-sdk-for-java.git</connection>
<tag>HEAD</tag>
</scm>

<properties>
<!-- SchemaRegistrySkip temporarily relaxing code coverage -->
<jacoco.skip.coverage.check>true</jacoco.skip.coverage.check>
</properties>

<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-schemaregistry</artifactId>
<version>1.0.0-beta.1</version> <!-- {x-version-update;com.azure:azure-data-schemaregistry;dependency} -->
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.9.2</version> <!-- {x-version-update;org.apache.avro:avro;external_dependency} -->
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version> <!-- {x-version-update;org.junit.jupiter:junit-jupiter-api;external_dependency} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version> <!-- {x-version-update;org.junit.jupiter:junit-jupiter-engine;external_dependency} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.6.2</version> <!-- {x-version-update;org.junit.jupiter:junit-jupiter-params;external_dependency} -->
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version> <!-- {x-version-update;org.apache.maven.plugins:maven-enforcer-plugin;external_dependency} -->
<configuration>
<rules>
<bannedDependencies>
<includes>
<include>com.azure:*</include>
<include>org.apache.avro:avro:[1.9.2]</include> <!-- {x-include-update;org.apache.avro:avro;external_dependency} -->
</includes>
</bannedDependencies>
</rules>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.data.schemaregistry.avro;

import com.azure.core.util.logging.ClientLogger;
import com.azure.data.schemaregistry.ByteDecoder;
import com.azure.data.schemaregistry.SerializationException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.specific.SpecificDatumReader;

import java.io.IOException;
import java.util.Objects;

/**
* Apache Avro ByteDecoder implementation with all Avro-specific functionality required to deserialize byte arrays
* given an Avro schema.
*/
public class AvroByteDecoder extends AvroCodec
implements ByteDecoder {
private final ClientLogger logger = new ClientLogger(AvroByteDecoder.class);
private static final DecoderFactory DECODER_FACTORY = DecoderFactory.get();
private final boolean avroSpecificReader;

/**
* Instantiates AvroByteDecoder instance
* @param avroSpecificReader flag indicating if attempting to decode as Avro SpecificRecord
*/
public AvroByteDecoder(boolean avroSpecificReader) {
this.avroSpecificReader = avroSpecificReader;
}

/**
* @param b byte array containing encoded bytes
* @param object schema for Avro reader read - fetched from Azure Schema Registry
* @return deserialized object
* @throws SerializationException upon deserialization failure
*/
public Object decodeBytes(byte[] b, Object object) {
Objects.requireNonNull(object, "Schema must not be null.");

if (!(object instanceof Schema)) {
throw logger.logExceptionAsError(
new SerializationException("Object must be an Avro schema."));
}
Schema schema = (Schema) object;

if (schema.getType().equals(Schema.Type.BYTES)) {
return b;
}

DatumReader<?> reader = getDatumReader(schema);

try {
Object result = reader.read(null, DECODER_FACTORY.binaryDecoder(b, null));

if (schema.getType().equals(Schema.Type.STRING)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also conditionally check !(result instanceof String). It is possible to configure your schema with "avro.java.stringType":"String" to tell the parser to read the string type as java.lang.String instead of Apache's Utf8 CharSequence implementation.

return result.toString();
}

return result;
} catch (IOException | RuntimeException e) {
// avro deserialization may throw AvroRuntimeException, NullPointerException, etc
throw logger.logExceptionAsError(new SerializationException("Error deserializing Avro message.", e));
}
}

/**
* Returns correct reader for decoding payload.
*
* @param writerSchema Avro schema fetched from schema registry store
* @return correct Avro DatumReader object given encoder configuration
*/
private DatumReader<?> getDatumReader(Schema writerSchema) {
boolean writerSchemaIsPrimitive = AvroSchemaUtils.getPrimitiveSchemas().values().contains(writerSchema);
// do not use SpecificDatumReader if writerSchema is a primitive
if (avroSpecificReader && !writerSchemaIsPrimitive) {
return new SpecificDatumReader<>(writerSchema);
} else {
return new GenericDatumReader<>(writerSchema);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.data.schemaregistry.avro;

import com.azure.core.util.logging.ClientLogger;
import com.azure.data.schemaregistry.ByteEncoder;
import com.azure.data.schemaregistry.SerializationException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.io.BinaryEncoder;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificRecord;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
* ByteEncoder implementation with all Avro-specific functionality required to serialize Java objects into byte arrays.
*/
public class AvroByteEncoder extends AvroCodec
implements ByteEncoder {
private final ClientLogger logger = new ClientLogger(AvroByteEncoder.class);
private static final EncoderFactory ENCODER_FACTORY = EncoderFactory.get();

/**
* @param object Schema object used to generate schema string
* @see AvroSchemaUtils for distinction between primitive and Avro schema generation
* @return string representation of schema
*/
@Override
public String getSchemaString(Object object) {
Schema schema = AvroSchemaUtils.getSchema(object);
return schema.toString();
}

/**
* Returns schema name for storing schemas in schema registry store.
*
* @param object Schema object used to generate schema path
* @return schema name as string
*/
@Override
public String getSchemaName(Object object) {
return AvroSchemaUtils.getSchema(object).getFullName();
}

/**
* Returns ByteArrayOutputStream containing Avro encoding of object parameter
* @param object Object to be encoded into byte stream
* @return closed ByteArrayOutputStream
* @throws SerializationException wraps runtime exceptions
*/
@Override
public ByteArrayOutputStream encode(Object object) {
Schema schema = AvroSchemaUtils.getSchema(object);

try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (object instanceof byte[]) {
out.write((byte[]) object); // todo: real avro byte arrays require writing array size to buffer
} else {
BinaryEncoder encoder = ENCODER_FACTORY.directBinaryEncoder(out, null);
DatumWriter<Object> writer;
if (object instanceof SpecificRecord) {
writer = new SpecificDatumWriter<>(schema);
} else {
writer = new GenericDatumWriter<>(schema);
}
writer.write(object, encoder);
encoder.flush();
}
return out;
} catch (IOException | RuntimeException e) {
// Avro serialization can throw AvroRuntimeException, NullPointerException, ClassCastException, etc
throw logger.logExceptionAsError(
new SerializationException("Error serializing Avro message", e));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.data.schemaregistry.avro;

import com.azure.data.schemaregistry.Codec;
import org.apache.avro.Schema;

/**
* Base Codec class for Avro encoder and decoder implementations
*/
abstract class AvroCodec implements Codec {
@Override
public String schemaType() {
return "avro";
}

/**
* @param schemaString string representation of schema
* @return avro schema
*/
@Override
public Schema parseSchemaString(String schemaString) {
return (new Schema.Parser()).parse(schemaString);
}
}
Loading