Skip to content

Commit 74da56d

Browse files
authored
Feature: Added Qualified and Custom reference name strategy approaches for protobuf references (Schema Registry) (#2345)
* Added QualifiedReferenceSubjectNameStrategy implementation to have feature parity with java version. Added ability to use any custom ReferenceSubjectNameStrategy by implementing ICustomReferenceSubjectNameStrategy and assigning implemented instance to ProtobufSerializerConfig property CustomReferenceSubjectNameStrategy (Note: ReferenceSubjectNameStrategy enumeration value must be set to Custom) Code for ProtobufSerializer was reformatted * Empty-Commit
1 parent c8aa462 commit 74da56d

File tree

3 files changed

+96
-6
lines changed

3 files changed

+96
-6
lines changed

src/Confluent.SchemaRegistry.Serdes.Protobuf/ProtobufSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public ProtobufSerializer(ISchemaRegistryClient schemaRegistryClient, ProtobufSe
9696
if (config.SubjectNameStrategy != null) { this.subjectNameStrategy = config.SubjectNameStrategy.Value.ToDelegate(); }
9797
this.referenceSubjectNameStrategy = config.ReferenceSubjectNameStrategy == null
9898
? ReferenceSubjectNameStrategy.ReferenceName.ToDelegate()
99-
: config.ReferenceSubjectNameStrategy.Value.ToDelegate();
99+
: config.ReferenceSubjectNameStrategy.Value.ToDelegate(config.CustomReferenceSubjectNameStrategy);
100100

101101
if (this.useLatestVersion && this.autoRegisterSchema)
102102
{

src/Confluent.SchemaRegistry.Serdes.Protobuf/ProtobufSerializerConfig.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,5 +274,10 @@ public ReferenceSubjectNameStrategy? ReferenceSubjectNameStrategy
274274
}
275275
}
276276

277+
/// <summary>
278+
/// Custom reference subject name strategy resolver.
279+
/// Ensure <seealso cref="ReferenceSubjectNameStrategy.Custom"/> is set for this to take effect.
280+
/// </summary>
281+
public ICustomReferenceSubjectNameStrategy CustomReferenceSubjectNameStrategy { get; set; } = null;
277282
}
278283
}

src/Confluent.SchemaRegistry/ReferenceSubjectNameStrategy.cs

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// Refer to LICENSE for more information.
1616

1717
using Confluent.Kafka;
18+
using System;
1819

1920

2021
namespace Confluent.SchemaRegistry
@@ -38,11 +39,45 @@ namespace Confluent.SchemaRegistry
3839
public enum ReferenceSubjectNameStrategy
3940
{
4041
/// <summary>
41-
/// (default): Use the reference name as the subject name.
42+
/// ReferenceName (default): Use the reference name as the subject name.
4243
/// </summary>
43-
ReferenceName
44+
ReferenceName,
45+
/// <summary>
46+
/// Qualified: Given a reference name, replace slashes with dots, and remove the .proto suffix to obtain the subject name.
47+
/// For example, mypackage/myfile.proto becomes mypackage.myfile.
48+
/// </summary>
49+
Qualified,
50+
/// <summary>
51+
/// Custom: Use a custom reference subject name strategy resolver to determine the subject name.
52+
/// </summary>
53+
Custom
54+
}
55+
56+
/// <summary>
57+
/// Custom Reference Subject Name Strategy Interface
58+
/// </summary>
59+
public interface ICustomReferenceSubjectNameStrategy
60+
{
61+
/// <summary>
62+
/// Gets the subject name.
63+
/// </summary>
64+
/// <param name="context"></param>
65+
/// <param name="referenceName"></param>
66+
/// <returns></returns>
67+
string GetSubjectName(SerializationContext context, string referenceName);
68+
}
69+
70+
/// <summary>
71+
/// Configuration property names specific to the schema registry client.
72+
/// </summary>
73+
public static partial class PropertyNames
74+
{
75+
/// <summary>
76+
/// The subject name strategy to use for registration / lookup of referenced schemas
77+
/// Possible values: <see cref="Confluent.SchemaRegistry.ReferenceSubjectNameStrategy" />
78+
/// </summary>
79+
public const string ReferenceSubjectNameStrategy = "protobuf.serializer.reference.subject.name.strategy";
4480
}
45-
4681

4782
/// <summary>
4883
/// Extension methods for the ReferenceSubjectNameStrategy type.
@@ -52,7 +87,57 @@ public static class ReferenceSubjectNameStrategyExtensions
5287
/// <summary>
5388
/// Provide a functional implementation corresponding to the enum value.
5489
/// </summary>
55-
public static ReferenceSubjectNameStrategyDelegate ToDelegate(this ReferenceSubjectNameStrategy strategy)
56-
=> (context, referenceName) => referenceName;
90+
public static ReferenceSubjectNameStrategyDelegate ToDelegate(this ReferenceSubjectNameStrategy strategy, ICustomReferenceSubjectNameStrategy customReferenceSubjectNameStrategy = null)
91+
{
92+
return (context, referenceName) =>
93+
{
94+
switch (strategy)
95+
{
96+
case ReferenceSubjectNameStrategy.ReferenceName:
97+
{
98+
return GetReferenceNameSubjectName(context, referenceName);
99+
}
100+
case ReferenceSubjectNameStrategy.Qualified:
101+
{
102+
return GetQualifiedSubjectName(context, referenceName);
103+
}
104+
case ReferenceSubjectNameStrategy.Custom:
105+
{
106+
if (customReferenceSubjectNameStrategy == null)
107+
{
108+
throw new ArgumentException($"Custom strategy requires a custom {nameof(ICustomReferenceSubjectNameStrategy)} implementation to be specified.");
109+
}
110+
111+
return customReferenceSubjectNameStrategy.GetSubjectName(context, referenceName);
112+
}
113+
default:
114+
{
115+
throw new ArgumentException($"Unknown ${PropertyNames.ReferenceSubjectNameStrategy} value: {strategy}.");
116+
}
117+
}
118+
};
119+
}
120+
121+
/// <summary>
122+
/// Get Subject Name
123+
/// </summary>
124+
/// <param name="context"></param>
125+
/// <param name="referenceName"></param>
126+
/// <returns></returns>
127+
public static string GetQualifiedSubjectName(SerializationContext context, string referenceName)
128+
{
129+
return referenceName.Replace(".proto", string.Empty).Replace("/", ".");
130+
}
131+
132+
/// <summary>
133+
/// Get Subject Name
134+
/// </summary>
135+
/// <param name="context"></param>
136+
/// <param name="referenceName"></param>
137+
/// <returns></returns>
138+
public static string GetReferenceNameSubjectName(SerializationContext context, string referenceName)
139+
{
140+
return referenceName;
141+
}
57142
}
58143
}

0 commit comments

Comments
 (0)