Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SR API updates based on architect feedback #27016

Merged
merged 4 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,8 +1,8 @@
namespace Azure
{
public partial class MessageWithMetadata
public partial class BinaryContent
{
public MessageWithMetadata() { }
public BinaryContent() { }
public virtual Azure.Core.ContentType? ContentType { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
protected virtual Azure.Core.ContentType? ContentTypeCore { get { throw null; } set { } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
namespace Azure
{
/// <summary>
/// A message containing a content type along with its data.
/// Content containing a content type along with its data.
/// </summary>
public class MessageWithMetadata
public class BinaryContent
{
/// <summary>
/// Gets or sets the message data.
/// Gets or sets the data.
/// </summary>
public virtual BinaryData? Data { get; set; }

/// <summary>
/// Gets or sets the message content type.
/// Gets or sets the content type.
/// </summary>
public virtual ContentType? ContentType
{
Expand All @@ -35,7 +35,7 @@ public virtual ContentType? ContentType
protected virtual ContentType? ContentTypeCore { get; set; }

/// <summary>
/// Gets whether the message is read only or not. This
/// Gets whether the content is read only or not. This
/// can be overriden by inheriting classes to specify whether or
/// not the message can be modified.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Azure.Messaging.EventHubs
{
public partial class EventData : Azure.MessageWithMetadata
public partial class EventData : Azure.BinaryContent
{
public EventData() { }
public EventData(System.BinaryData eventBody) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@

<ItemGroup>
<!--
TEMP: Move Core to a project reference until the MessageWithMetadata are shipped in Azure.Core.
TEMP: Move Core to a project reference until BinaryContent is shipped in Azure.Core.Experimental.

<PackageReference Include="Azure.Core" />
<PackageReference Include="Azure.Core" />
-->
<PackageReference Include="Azure.Core.Experimental" />
<ProjectReference Include="..\..\..\core\Azure.Core.Experimental\src\Azure.Core.Experimental.csproj" />
<!-- <PackageReference Include="Azure.Core.Experimental" />-->
JoshLove-msft marked this conversation as resolved.
Show resolved Hide resolved
JoshLove-msft marked this conversation as resolved.
Show resolved Hide resolved
<!-- END TEMP -->

<PackageReference Include="Azure.Core.Amqp" />
Expand Down
8 changes: 4 additions & 4 deletions sdk/eventhub/Azure.Messaging.EventHubs/src/EventData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Azure.Messaging.EventHubs
/// An Event Hubs event, encapsulating a set of data and its associated metadata.
/// </summary>
///
public class EventData : MessageWithMetadata
public class EventData : BinaryContent
{
/// <summary>The AMQP representation of the event, allowing access to additional protocol data elements not used directly by the Event Hubs client library.</summary>
private readonly AmqpAnnotatedMessage _amqpMessage;
Expand Down Expand Up @@ -98,7 +98,7 @@ public BinaryData EventBody

/// <summary>
/// This member is intended to allow the string-based <see cref="ContentType" /> in this class to be
/// translated to/from the <see cref="Azure.Core.ContentType" /> type used by the <see cref="MessageWithMetadata" />
/// translated to/from the <see cref="Azure.Core.ContentType" /> type used by the <see cref="BinaryContent" />
/// base class.
/// </summary>
///
Expand All @@ -111,7 +111,7 @@ protected override ContentType? ContentTypeCore

/// <summary>
/// Hidden property that shadows the <see cref="EventBody"/> property. This is added
/// in order to inherit from <see cref="MessageWithMetadata"/>.
/// in order to inherit from <see cref="BinaryContent"/>.
/// </summary>
///
[EditorBrowsable(EditorBrowsableState.Never)]
Expand All @@ -123,7 +123,7 @@ public override BinaryData Data

/// <summary>
/// Hidden property that indicates that the <see cref="EventData"/> is not read-only. This is part of
/// the <see cref="MessageWithMetadata"/> abstraction.
/// the <see cref="BinaryContent"/> abstraction.
/// </summary>
///
[EditorBrowsable(EditorBrowsableState.Never)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Azure Schema Registry Apache Avro client library for .NET

Azure Schema Registry is a schema repository service hosted by Azure Event Hubs, providing schema storage, versioning, and management. This package provides an Avro encoder capable of encoding and decoding payloads containing Schema Registry schema identifiers and Avro-encoded data.
Azure Schema Registry is a schema repository service hosted by Azure Event Hubs, providing schema storage, versioning, and management. This package provides an Avro serializer capable of serializing and deserializing payloads containing Schema Registry schema identifiers and Avro-serialized data.

## Getting started

Expand Down Expand Up @@ -50,17 +50,17 @@ var schemaRegistryClient = new SchemaRegistryClient(fullyQualifiedNamespace: ful

## Key concepts

### Encoder
### Serializer

This library provides an encoder, [SchemaRegistryAvroEncoder]
[schema_registry_avro_encoder], that interacts with `EventData` events. The SchemaRegistryAvroEncoder utilizes a SchemaRegistryClient to enrich the `EventData` events with the schema ID for the schema used to encode the data.
This library provides a serializer, [SchemaRegistryAvroSerializer]
[schema_registry_avro_serializer], that interacts with `EventData` events. The SchemaRegistryAvroSerializer utilizes a SchemaRegistryClient to enrich the `EventData` events with the schema ID for the schema used to serialize the data.

This encoder requires the [Apache Avro library][apache_avro_library]. The payload types accepted by this encoder include [GenericRecord][generic_record] and [ISpecificRecord][specific_record].
This serializer requires the [Apache Avro library][apache_avro_library]. The payload types accepted by this serializer include [GenericRecord][generic_record] and [ISpecificRecord][specific_record].


### Examples

The following shows examples of what is available through the `SchemaRegistryAvroEncoder`. There are both sync and async methods available for these operations. These examples use a generated Apache Avro class [Employee.cs][employee] created using this schema:
The following shows examples of what is available through the `SchemaRegistryAvroSerializer`. There are both sync and async methods available for these operations. These examples use a generated Apache Avro class [Employee.cs][employee] created using this schema:

```json
{
Expand All @@ -76,14 +76,14 @@ The following shows examples of what is available through the `SchemaRegistryAvr

Details on generating a class using the Apache Avro library can be found in the [Avro C# Documentation][avro_csharp_documentation].

### Encode and decode data using the Event Hub EventData model
### Serialize and deserialize data using the Event Hub EventData model

In order to encode an `EventData` instance with Avro information, you can do the following:
In order to serialize an `EventData` instance with Avro information, you can do the following:
```C# Snippet:SchemaRegistryAvroEncodeEventData
var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroEncoderOptions { AutoRegisterSchemas = true });
var serializer = new SchemaRegistryAvroSerializer(client, groupName, new SchemaRegistryAvroSerializerOptions { AutoRegisterSchemas = true });

var employee = new Employee { Age = 42, Name = "Caketown" };
JoshLove-msft marked this conversation as resolved.
Show resolved Hide resolved
EventData eventData = (EventData) await encoder.EncodeMessageDataAsync(employee, messageType: typeof(EventData));
EventData eventData = (EventData) await serializer.SerializeAsync(employee, messageType: typeof(EventData));

// the schema Id will be included as a parameter of the content type
Console.WriteLine(eventData.ContentType);
Expand All @@ -92,19 +92,19 @@ Console.WriteLine(eventData.ContentType);
Console.WriteLine(eventData.EventBody);
```

To decode an `EventData` event that you are consuming:
To deserialize an `EventData` event that you are consuming:
```C# Snippet:SchemaRegistryAvroDecodeEventData
Employee deserialized = (Employee) await encoder.DecodeMessageDataAsync(eventData, typeof(Employee));
Employee deserialized = (Employee) await serializer.DeserializeAsync(eventData, typeof(Employee));
Console.WriteLine(deserialized.Age);
Console.WriteLine(deserialized.Name);
```

You can also use generic methods to encode and decode the data. This may be more convenient if you are not building a library on top of the Avro encoder, as you won't have to worry about the virality of generics:
You can also use generic methods to serialize and deserialize the data. This may be more convenient if you are not building a library on top of the Avro serializer, as you won't have to worry about the virality of generics:
```C# Snippet:SchemaRegistryAvroEncodeEventDataGenerics
var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroEncoderOptions { AutoRegisterSchemas = true });
var serializer = new SchemaRegistryAvroSerializer(client, groupName, new SchemaRegistryAvroSerializerOptions { AutoRegisterSchemas = true });

var employee = new Employee { Age = 42, Name = "Caketown" };
EventData eventData = await encoder.EncodeMessageDataAsync<EventData, Employee>(employee);
EventData eventData = await serializer.SerializeAsync<EventData, Employee>(employee);

// the schema Id will be included as a parameter of the content type
Console.WriteLine(eventData.ContentType);
Expand All @@ -113,21 +113,21 @@ Console.WriteLine(eventData.ContentType);
Console.WriteLine(eventData.EventBody);
```

Similarly, to decode:
Similarly, to deserialize:
```C# Snippet:SchemaRegistryAvroDecodeEventDataGenerics
Employee deserialized = (Employee) await encoder.DecodeMessageDataAsync<Employee>(eventData);
Employee deserialized = await serializer.DeserializeAsync<Employee>(eventData);
Console.WriteLine(deserialized.Age);
Console.WriteLine(deserialized.Name);
```

### Encode and decode data using `MessageWithMetadata` directly
### Serialize and deserialize data using `BinaryContent` directly

It is also possible to encode and decode using `MessageWithMetadata`. Use this option if you are not integrating with any of the messaging libraries that work with `MessageWithMetadata`.
```C# Snippet:SchemaRegistryAvroEncodeDecodeMessageWithMetadata
var encoder = new SchemaRegistryAvroEncoder(client, groupName, new SchemaRegistryAvroEncoderOptions { AutoRegisterSchemas = true });
MessageWithMetadata messageData = await encoder.EncodeMessageDataAsync<MessageWithMetadata, Employee>(employee);
It is also possible to serialize and deserialize using `BinaryContent`. Use this option if you are not integrating with any of the messaging libraries that work with `BinaryContent`.
```C# Snippet:SchemaRegistryAvroEncodeDecodeBinaryContent
var serializer = new SchemaRegistryAvroSerializer(client, groupName, new SchemaRegistryAvroSerializerOptions { AutoRegisterSchemas = true });
BinaryContent content = await serializer.SerializeAsync<BinaryContent, Employee>(employee);

Employee decodedEmployee = await encoder.DecodeMessageDataAsync<Employee>(messageData);
Employee deserializedEmployee = await serializer.DeserializeAsync<Employee>(content);
```

## Troubleshooting
Expand Down Expand Up @@ -162,7 +162,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con
[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
[code_of_conduct_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[email_opencode]: mailto:[email protected]
[schema_registry_avro_encoder]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/schemaregistry/Microsoft.Azure.Data.SchemaRegistry.ApacheAvro/src/SchemaRegistryAvroEncoder.cs
[schema_registry_avro_serializer]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/schemaregistry/Microsoft.Azure.Data.SchemaRegistry.ApacheAvro/src/SchemaRegistryAvroSerializer.cs
[employee]: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/schemaregistry/Microsoft.Azure.Data.SchemaRegistry.ApacheAvro/tests/Models/Employee.cs
[avro_csharp_documentation]: https://avro.apache.org/docs/current/api/csharp/html/index.html
[apache_avro_library]: https://www.nuget.org/packages/Apache.Avro/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
namespace Microsoft.Azure.Data.SchemaRegistry.ApacheAvro
{
public partial class SchemaRegistryAvroEncoder
public partial class SchemaRegistryAvroSerializer
{
public SchemaRegistryAvroEncoder(Azure.Data.SchemaRegistry.SchemaRegistryClient client, string groupName, Microsoft.Azure.Data.SchemaRegistry.ApacheAvro.SchemaRegistryAvroEncoderOptions options = null) { }
public object DecodeMessageData(Azure.MessageWithMetadata message, System.Type dataType, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<object> DecodeMessageDataAsync(Azure.MessageWithMetadata message, System.Type dataType, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<TData> DecodeMessageDataAsync<TData>(Azure.MessageWithMetadata message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public TData DecodeMessageData<TData>(Azure.MessageWithMetadata message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public Azure.MessageWithMetadata EncodeMessageData(object data, System.Type dataType = null, System.Type messageType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<Azure.MessageWithMetadata> EncodeMessageDataAsync(object data, System.Type dataType = null, System.Type messageType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<TMessage> EncodeMessageDataAsync<TMessage, TData>(TData data, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where TMessage : Azure.MessageWithMetadata, new() { throw null; }
public TMessage EncodeMessageData<TMessage, TData>(TData data, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where TMessage : Azure.MessageWithMetadata, new() { throw null; }
public SchemaRegistryAvroSerializer(Azure.Data.SchemaRegistry.SchemaRegistryClient client, string groupName, Microsoft.Azure.Data.SchemaRegistry.ApacheAvro.SchemaRegistryAvroSerializerOptions options = null) { }
public object Deserialize(Azure.BinaryContent content, System.Type dataType, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<object> DeserializeAsync(Azure.BinaryContent content, System.Type dataType, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<TData> DeserializeAsync<TData>(Azure.BinaryContent content, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public TData Deserialize<TData>(Azure.BinaryContent content, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public Azure.BinaryContent Serialize(object data, System.Type dataType = null, System.Type messageType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<Azure.BinaryContent> SerializeAsync(object data, System.Type dataType = null, System.Type messageType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask<TEnvelope> SerializeAsync<TEnvelope, TData>(TData data, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where TEnvelope : Azure.BinaryContent, new() { throw null; }
public TEnvelope Serialize<TEnvelope, TData>(TData data, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) where TEnvelope : Azure.BinaryContent, new() { throw null; }
}
public partial class SchemaRegistryAvroEncoderOptions
public partial class SchemaRegistryAvroSerializerOptions
{
public SchemaRegistryAvroEncoderOptions() { }
public SchemaRegistryAvroSerializerOptions() { }
public bool AutoRegisterSchemas { get { throw null; } set { } }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="Apache.Avro" />
<PackageReference Include="Azure.Data.SchemaRegistry" />
<PackageReference Include="Azure.Core.Experimental" />
<!-- <PackageReference Include="Azure.Core.Experimental" />-->
</ItemGroup>

<!-- Shared source from Azure.Core -->
Expand All @@ -22,4 +22,7 @@
<Compile Include="$(AzureCoreSharedSources)OperationHelpers.cs" LinkBase="Shared" />
<Compile Include="$(AzureCoreSharedSources)Argument.cs" LinkBase="Shared" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\core\Azure.Core.Experimental\src\Azure.Core.Experimental.csproj" />
</ItemGroup>
</Project>
Loading