Skip to content

Commit 78f9fa2

Browse files
committed
add AvroValidationRule for names and symbols
1 parent 59fef05 commit 78f9fa2

File tree

6 files changed

+106
-1
lines changed

6 files changed

+106
-1
lines changed

src/LEGO.AsyncAPI/Resource.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/LEGO.AsyncAPI/Resource.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,10 @@
132132
<data name="Validation_MustBeAbsoluteUrl" xml:space="preserve">
133133
<value>The field '{0}' in '{1}' object MUST be an absolute uri.</value>
134134
</data>
135+
<data name="Validation_NameMustMatchRegularExpr" xml:space="preserve">
136+
<value>'{0}' MUST match the regular expression '{1}'.</value>
137+
</data>
138+
<data name="Validation_SymbolsMustMatchRegularExpression" xml:space="preserve">
139+
<value>Symbols MUST match the regular expression '{1}'.</value>
140+
</data>
135141
</root>

src/LEGO.AsyncAPI/Services/AsyncApiVisitorBase.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ public virtual void Visit(AsyncApiDocument doc)
5555
{
5656
}
5757

58+
public virtual void Visit(AsyncApiJsonSchemaPayload jsonPayload)
59+
{
60+
}
61+
62+
public virtual void Visit(AsyncApiAvroSchemaPayload avroPayload)
63+
{
64+
}
65+
5866
public virtual void Visit(IDictionary<string, AsyncApiAny> anys)
5967
{
6068
}

src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,11 @@ internal void Walk(AsyncApiParameter parameter, bool isComponent = false)
326326
this.Walk(parameter as IAsyncApiExtensible);
327327
}
328328

329+
internal void Walk(AsyncApiAvroSchemaPayload payload)
330+
{
331+
this.visitor.Visit(payload);
332+
}
333+
329334
internal void Walk(AsyncApiSchema schema, bool isComponent = false)
330335
{
331336
if (schema == null || this.ProcessAsReference(schema, isComponent))
@@ -539,7 +544,11 @@ internal void Walk(AsyncApiMessage message, bool isComponent = false)
539544
this.Walk(AsyncApiConstants.Payload, () => this.Walk((AsyncApiSchema)payload));
540545
}
541546

542-
// #ToFix Add walking for avro.
547+
if (message.Payload is AsyncApiAvroSchemaPayload avroPayload)
548+
{
549+
this.Walk(AsyncApiConstants.Payload, () => this.Walk(avroPayload));
550+
}
551+
543552
this.Walk(AsyncApiConstants.CorrelationId, () => this.Walk(message.CorrelationId));
544553
this.Walk(AsyncApiConstants.Tags, () => this.Walk(message.Tags));
545554
this.Walk(AsyncApiConstants.Examples, () => this.Walk(message.Examples));

src/LEGO.AsyncAPI/Validation/AsyncApiValidator.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ public void AddWarning(AsyncApiValidatorWarning warning)
144144

145145
public override void Visit(IMessageBinding item) => this.Validate(item);
146146

147+
public override void Visit(AsyncApiAvroSchemaPayload item) => this.Validate(item);
148+
149+
public override void Visit(AsyncApiJsonSchemaPayload item) => this.Validate(item);
150+
147151
/// <summary>
148152
/// Execute validation rules against an <see cref="IAsyncApiExtensible"/>.
149153
/// </summary>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) The LEGO Group. All rights reserved.
2+
3+
namespace LEGO.AsyncAPI.Validation.Rules
4+
{
5+
using System.Linq;
6+
using System.Text.RegularExpressions;
7+
using LEGO.AsyncAPI.Models;
8+
using LEGO.AsyncAPI.Validations;
9+
10+
[AsyncApiRule]
11+
public static class AsyncApiAvroRules
12+
{
13+
/// <summary>
14+
/// The key regex.
15+
/// </summary>
16+
public static Regex NameRegex = new Regex(@"^[A-Za-z_][A-Za-z0-9_]*$");
17+
18+
public static ValidationRule<AsyncApiAvroSchemaPayload> NameRegularExpression =>
19+
new ValidationRule<AsyncApiAvroSchemaPayload>(
20+
(context, avroPayload) =>
21+
{
22+
string name = null;
23+
context.Enter("name");
24+
if (avroPayload.TryGetAs<AvroRecord>(out var record))
25+
{
26+
name = record.Name;
27+
}
28+
29+
if (avroPayload.TryGetAs<AvroEnum>(out var @enum))
30+
{
31+
name = @enum.Name;
32+
if (@enum.Symbols.Any(symbol => !NameRegex.IsMatch(symbol)))
33+
{
34+
context.CreateError(
35+
"SymbolsRegularExpression",
36+
string.Format(Resource.Validation_SymbolsMustMatchRegularExpression, NameRegex.ToString()));
37+
}
38+
}
39+
40+
if (avroPayload.TryGetAs<AvroFixed>(out var @fixed))
41+
{
42+
name = @fixed.Name;
43+
}
44+
45+
if (name == null)
46+
{
47+
return;
48+
}
49+
50+
if (!NameRegex.IsMatch(record.Name))
51+
{
52+
context.CreateError(
53+
nameof(NameRegex),
54+
string.Format(Resource.Validation_NameMustMatchRegularExpr, name, NameRegex.ToString()));
55+
}
56+
57+
context.Exit();
58+
});
59+
}
60+
}

0 commit comments

Comments
 (0)