From dc44873650073dd290e9b0330d3016790bb769ad Mon Sep 17 00:00:00 2001 From: Madalyn Redding <66138537+m-redding@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:29:35 -0400 Subject: [PATCH] [Schema Registry] Default SchemaFormat to the Content-Type header value (#45007) * fixes * fixes * clean up client --- .../src/ContentType.cs | 58 ------------------- .../src/Generated/SchemaRegistryClient.cs | 28 ++++----- .../src/SchemaFormat.cs | 39 +++++++------ .../src/SchemaRegistryClient.cs | 8 +-- .../tests/SchemaFormatTests.cs | 36 ++++++++++-- 5 files changed, 70 insertions(+), 99 deletions(-) delete mode 100644 sdk/schemaregistry/Azure.Data.SchemaRegistry/src/ContentType.cs diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/ContentType.cs b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/ContentType.cs deleted file mode 100644 index 70d53c6aa38e9..0000000000000 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/ContentType.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ComponentModel; - -namespace Azure.Data.SchemaRegistry -{ - /// The SerializationType. - internal readonly partial struct ContentType : IEquatable - { - private const string AvroValue = "application/json; serialization=Avro"; - private const string JsonValue = "application/json; serialization=json"; - private const string CustomValue = "text/plain; charset=utf-8"; - private const string ProtobufValue = "text/vnd.ms.protobuf"; - - private readonly string _value; - - /// Initializes a new instance of . - /// is null. - public ContentType(string value) - { - _value = value ?? throw new ArgumentNullException(nameof(value)); - } - - /// application/json; serialization=Avro. - public static ContentType Avro { get; } = new ContentType(AvroValue); - - /// application/json; serialization=json. - public static ContentType Json { get; } = new ContentType(JsonValue); - - /// text/plain; charset=utf-8. - public static ContentType Custom { get; } = new ContentType(CustomValue); - - ///// text/vnd.ms.protobuf. - //[CodeGenMember("TextVndMsProtobuf")] - //public static ContentType Protobuf { get; } = new ContentType(ProtobufValue); - - /// Determines if two values are the same. - public static bool operator ==(ContentType left, ContentType right) => left.Equals(right); - /// Determines if two values are not the same. - public static bool operator !=(ContentType left, ContentType right) => !left.Equals(right); - /// Converts a string to a . - public static implicit operator ContentType(string value) => new ContentType(value); - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => obj is ContentType other && Equals(other); - /// - public bool Equals(ContentType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase); - - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public override int GetHashCode() => _value?.GetHashCode() ?? 0; - /// - public override string ToString() => _value; - } -} diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Generated/SchemaRegistryClient.cs b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Generated/SchemaRegistryClient.cs index 09f5d7667091f..c0025b3094b96 100644 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Generated/SchemaRegistryClient.cs +++ b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/Generated/SchemaRegistryClient.cs @@ -267,7 +267,7 @@ internal virtual Response GetSchemaByVersion(string groupName, string schemaName /// , or is null. /// or is an empty string, and was expected to be non-empty. /// Gets the properties referencing an existing schema within the specified schema group, as matched by schema content comparison. - internal virtual async Task GetSchemaPropertiesByContentAsync(string groupName, string schemaName, BinaryData schemaContent, Core.ContentType contentType, CancellationToken cancellationToken = default) + internal virtual async Task GetSchemaPropertiesByContentAsync(string groupName, string schemaName, BinaryData schemaContent, ContentType contentType, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -288,7 +288,7 @@ internal virtual async Task GetSchemaPropertiesByContentAsync(string g /// , or is null. /// or is an empty string, and was expected to be non-empty. /// Gets the properties referencing an existing schema within the specified schema group, as matched by schema content comparison. - internal virtual Response GetSchemaPropertiesByContent(string groupName, string schemaName, BinaryData schemaContent, Core.ContentType contentType, CancellationToken cancellationToken = default) + internal virtual Response GetSchemaPropertiesByContent(string groupName, string schemaName, BinaryData schemaContent, ContentType contentType, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -310,7 +310,7 @@ internal virtual Response GetSchemaPropertiesByContent(string groupName, string /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// @@ -324,7 +324,7 @@ internal virtual Response GetSchemaPropertiesByContent(string groupName, string /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. /// The response returned from the service. - internal virtual async Task GetSchemaPropertiesByContentAsync(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context = null) + internal virtual async Task GetSchemaPropertiesByContentAsync(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context = null) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -354,7 +354,7 @@ internal virtual async Task GetSchemaPropertiesByContentAsync(string g /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// @@ -368,7 +368,7 @@ internal virtual async Task GetSchemaPropertiesByContentAsync(string g /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. /// The response returned from the service. - internal virtual Response GetSchemaPropertiesByContent(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context = null) + internal virtual Response GetSchemaPropertiesByContent(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context = null) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -397,7 +397,7 @@ internal virtual Response GetSchemaPropertiesByContent(string groupName, string /// , or is null. /// or is an empty string, and was expected to be non-empty. /// Register new schema. If schema of specified name does not exist in specified group, schema is created at version 1. If schema of specified name exists already in specified group, schema is created at latest version + 1. - internal virtual async Task RegisterSchemaAsync(string groupName, string schemaName, BinaryData schemaContent, Core.ContentType contentType, CancellationToken cancellationToken = default) + internal virtual async Task RegisterSchemaAsync(string groupName, string schemaName, BinaryData schemaContent, ContentType contentType, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -418,7 +418,7 @@ internal virtual async Task RegisterSchemaAsync(string groupName, stri /// , or is null. /// or is an empty string, and was expected to be non-empty. /// Register new schema. If schema of specified name does not exist in specified group, schema is created at version 1. If schema of specified name exists already in specified group, schema is created at latest version + 1. - internal virtual Response RegisterSchema(string groupName, string schemaName, BinaryData schemaContent, Core.ContentType contentType, CancellationToken cancellationToken = default) + internal virtual Response RegisterSchema(string groupName, string schemaName, BinaryData schemaContent, ContentType contentType, CancellationToken cancellationToken = default) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -440,7 +440,7 @@ internal virtual Response RegisterSchema(string groupName, string schemaName, Bi /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// @@ -454,7 +454,7 @@ internal virtual Response RegisterSchema(string groupName, string schemaName, Bi /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. /// The response returned from the service. - internal virtual async Task RegisterSchemaAsync(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context = null) + internal virtual async Task RegisterSchemaAsync(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context = null) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -484,7 +484,7 @@ internal virtual async Task RegisterSchemaAsync(string groupName, stri /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// @@ -498,7 +498,7 @@ internal virtual async Task RegisterSchemaAsync(string groupName, stri /// or is an empty string, and was expected to be non-empty. /// Service returned a non-success status code. /// The response returned from the service. - internal virtual Response RegisterSchema(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context = null) + internal virtual Response RegisterSchema(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context = null) { Argument.AssertNotNullOrEmpty(groupName, nameof(groupName)); Argument.AssertNotNullOrEmpty(schemaName, nameof(schemaName)); @@ -760,7 +760,7 @@ internal HttpMessage CreateGetSchemaByVersionRequest(string groupName, string sc return message; } - internal HttpMessage CreateGetSchemaPropertiesByContentRequest(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context) + internal HttpMessage CreateGetSchemaPropertiesByContentRequest(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context) { var message = _pipeline.CreateMessage(context, ResponseClassifier204); var request = message.Request; @@ -781,7 +781,7 @@ internal HttpMessage CreateGetSchemaPropertiesByContentRequest(string groupName, return message; } - internal HttpMessage CreateRegisterSchemaRequest(string groupName, string schemaName, RequestContent content, Core.ContentType contentType, RequestContext context) + internal HttpMessage CreateRegisterSchemaRequest(string groupName, string schemaName, RequestContent content, ContentType contentType, RequestContext context) { var message = _pipeline.CreateMessage(context, ResponseClassifier204); var request = message.Request; diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaFormat.cs b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaFormat.cs index 03ba90fa7f16e..9617295b5e368 100644 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaFormat.cs +++ b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaFormat.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; +using Azure.Core; namespace Azure.Data.SchemaRegistry { @@ -16,9 +17,16 @@ namespace Azure.Data.SchemaRegistry private const string CustomValue = "Custom"; private const string ProtobufValue = "Protobuf"; - private const string AvroContentType = "Avro"; - private const string JsonContentType = "Json"; - private const string ProtobufContentType = "vnd.ms.protobuf"; + // Temporary until autorest bug is fixed + private const string AvroContentType = "application/json; serialization=Avro"; + private const string JsonContentType = "application/json; serialization=Json"; + private const string CustomContentType = "text/plain; charset=utf-8"; + private const string ProtobufContentType = "text/vnd.ms.protobuf"; + + private const string AvroContentTypeValue = "Avro"; + private const string JsonContentTypeValue = "Json"; + private const string CustomContentTypeValue = "utf-8"; + private const string ProtobufContentTypeValue = "vnd.ms.protobuf"; /// Initializes a new instance of . /// is null. @@ -63,37 +71,34 @@ internal ContentType ToContentType() switch (_value) { case AvroValue: - return ContentType.Avro; + return new ContentType(AvroContentType); case JsonValue: - return ContentType.Json; + return new ContentType(JsonContentType); //case ProtobufValue: - // return ContentType.Protobuf; + // return new ContentType(ProtobufContentType); default: - return ContentType.Custom; + return new ContentType(CustomContentType); } } internal static SchemaFormat FromContentType(string contentTypeValue) { var contentTypeParameterValue = contentTypeValue.Split('='); - var contentSubType = contentTypeValue.Split('/'); if (contentTypeParameterValue.Length > 1) { switch (contentTypeParameterValue[1]) { - case AvroContentType: - return SchemaFormat.Avro; - case JsonContentType: - return SchemaFormat.Json; + case AvroContentTypeValue: + return Avro; + case JsonContentTypeValue: + return Json; + case CustomContentTypeValue: + return Custom; default: break; } } - return contentSubType[1] switch - { - //ProtobufContentType => SchemaFormat.Protobuf, - _ => SchemaFormat.Custom, - }; + return new SchemaFormat(contentTypeValue); } } } diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaRegistryClient.cs b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaRegistryClient.cs index 7149b2aaa0b62..88e76bf40cd8d 100644 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaRegistryClient.cs +++ b/sdk/schemaregistry/Azure.Data.SchemaRegistry/src/SchemaRegistryClient.cs @@ -133,11 +133,11 @@ private async Task> RegisterSchemaInternalAsync( Response response; if (async) { - response = await RegisterSchemaAsync(groupName, schemaName, new BinaryData(schemaDefinition), new Core.ContentType(format.ToContentType().ToString()), cancellationToken).ConfigureAwait(false); + response = await RegisterSchemaAsync(groupName, schemaName, new BinaryData(schemaDefinition), format.ToContentType(), cancellationToken).ConfigureAwait(false); } else { - response = RegisterSchema(groupName, schemaName, new BinaryData(schemaDefinition), new Core.ContentType(format.ToContentType().ToString()), cancellationToken); + response = RegisterSchema(groupName, schemaName, new BinaryData(schemaDefinition), format.ToContentType(), cancellationToken); } var schemaIdHeader = response.Headers.TryGetValue("Schema-Id", out string idHeader) ? idHeader : null; @@ -210,11 +210,11 @@ private async Task> GetSchemaPropertiesInternalAsync( Response response; if (async) { - response = await GetSchemaPropertiesByContentAsync(groupName, schemaName, new BinaryData(schemaDefinition), new Core.ContentType(format.ToContentType().ToString()), cancellationToken).ConfigureAwait(false); + response = await GetSchemaPropertiesByContentAsync(groupName, schemaName, new BinaryData(schemaDefinition), format.ToContentType().ToString(), cancellationToken).ConfigureAwait(false); } else { - response = GetSchemaPropertiesByContent(groupName, schemaName, new BinaryData(schemaDefinition), new Core.ContentType(format.ToContentType().ToString()), cancellationToken); + response = GetSchemaPropertiesByContent(groupName, schemaName, new BinaryData(schemaDefinition), format.ToContentType(), cancellationToken); } var schemaIdHeader = response.Headers.TryGetValue("Schema-Id", out string idHeader) ? idHeader : null; diff --git a/sdk/schemaregistry/Azure.Data.SchemaRegistry/tests/SchemaFormatTests.cs b/sdk/schemaregistry/Azure.Data.SchemaRegistry/tests/SchemaFormatTests.cs index fe348c5e0f4bc..db21edd9bdd4f 100644 --- a/sdk/schemaregistry/Azure.Data.SchemaRegistry/tests/SchemaFormatTests.cs +++ b/sdk/schemaregistry/Azure.Data.SchemaRegistry/tests/SchemaFormatTests.cs @@ -8,6 +8,11 @@ namespace Azure.Data.SchemaRegistry.Tests { public class SchemaFormatTests { + private const string AvroContentType = "application/json; serialization=Avro"; + private const string JsonContentType = "application/json; serialization=Json"; + private const string CustomContentType = "text/plain; charset=utf-8"; + private const string ProtobufContentType = "text/vnd.ms.protobuf"; + [Test] public void VerifyAvroFormat() { @@ -26,6 +31,12 @@ public void VerifyCustomFormat() Assert.AreEqual("Custom", SchemaFormat.Custom.ToString()); } + [Test] + public void VerifyDefault() + { + Assert.AreEqual("MyValue", (new SchemaFormat("MyValue")).ToString()); + } + //[Test] //public void VerifyProtobufFormat() //{ @@ -35,19 +46,25 @@ public void VerifyCustomFormat() [Test] public void VerifyAvroToContentType() { - Assert.AreEqual(ContentType.Avro, SchemaFormat.Avro.ToContentType()); + Assert.AreEqual(AvroContentType, SchemaFormat.Avro.ToContentType()); } [Test] public void VerifyJsonToContentType() { - Assert.AreEqual(ContentType.Json, SchemaFormat.Json.ToContentType()); + Assert.AreEqual(JsonContentType, SchemaFormat.Json.ToContentType()); } [Test] public void VerifyCustomToContentType() { - Assert.AreEqual(ContentType.Custom, SchemaFormat.Custom.ToContentType()); + Assert.AreEqual(CustomContentType, SchemaFormat.Custom.ToContentType()); + } + + [Test] + public void VerifyDefaultToContentType() + { + Assert.AreEqual(CustomContentType, (new SchemaFormat("MyValue")).ToContentType()); } //[Test] @@ -59,24 +76,31 @@ public void VerifyCustomToContentType() [Test] public void VerifyAvroFromContentType() { - var fromContentType = SchemaFormat.FromContentType("application/json; serialization=Avro"); + var fromContentType = SchemaFormat.FromContentType(AvroContentType); Assert.AreEqual(SchemaFormat.Avro, fromContentType); } [Test] public void VerifyJsonFromContentType() { - var fromContentType = SchemaFormat.FromContentType("application/json; serialization=Json"); + var fromContentType = SchemaFormat.FromContentType(JsonContentType); Assert.AreEqual(SchemaFormat.Json, fromContentType); } [Test] public void VerifyCustomFromContentType() { - var fromContentType = SchemaFormat.FromContentType("text/plain; charset=utf-8"); + var fromContentType = SchemaFormat.FromContentType(CustomContentType); Assert.AreEqual(SchemaFormat.Custom, fromContentType); } + [Test] + public void VerifyDefaultFromContentType() + { + var fromContentType = SchemaFormat.FromContentType("MyValue"); + Assert.AreEqual(new SchemaFormat("MyValue"), fromContentType); + } + //[Test] //public void VerifyProtobufFromContentType() //{