Skip to content

Commit ccd6ff3

Browse files
authored
fix: parameter reference resolution during V3 upgrade (#15)
* tempstorage * fix missing null check
1 parent fd3a236 commit ccd6ff3

4 files changed

Lines changed: 133 additions & 0 deletions

File tree

src/ByteBard.AsyncAPI.Readers/TempStorageKeys.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ public static class TempStorageKeys
77
public const string OperationMessageReferences = "OperationMessageReferences";
88
public const string ComponentMessages = "ComponentMessages";
99
public const string ChannelAddresses = "ChannelAddresses";
10+
public const string ParameterSchemaReferences = "ParameterSchemaReferences";
1011
}
1112
}

src/ByteBard.AsyncAPI.Readers/V2/AsyncApiDocumentDeserializer.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,48 @@ public static AsyncApiDocument LoadAsyncApi(RootNode rootNode)
5757
SetSecuritySchemeScopes(asyncApiNode.Context, document);
5858
SetMessages(asyncApiNode.Context, document);
5959
SetOperations(asyncApiNode.Context, document);
60+
SetParameters(asyncApiNode.Context, document);
6061
return document;
6162
}
6263

64+
private static void SetParameters(ParsingContext context, AsyncApiDocument document)
65+
{
66+
var parameterReferences =
67+
context.GetFromTempStorage<Dictionary<AsyncApiParameter, AsyncApiJsonSchemaReference>>(TempStorageKeys
68+
.ParameterSchemaReferences);
69+
70+
if (parameterReferences == null)
71+
{
72+
return;
73+
}
74+
75+
foreach (var parameterReference in parameterReferences)
76+
{
77+
var parameter = parameterReference.Key;
78+
var multiFormatSchema = context.Workspace.ResolveReference<AsyncApiMultiFormatSchema>(parameterReference.Value.Reference);
79+
var schema = multiFormatSchema.Schema.As<AsyncApiJsonSchema>();
80+
if (schema == null)
81+
{
82+
continue;
83+
}
84+
85+
if (schema.Enum.Any())
86+
{
87+
parameter.Enum = schema.Enum.Select(e => e.GetValue<string>()).ToList();
88+
}
89+
90+
if (schema.Default != null)
91+
{
92+
parameter.Default = schema.Default.GetValue<string>();
93+
}
94+
95+
if (schema.Examples.Any())
96+
{
97+
parameter.Examples = schema.Examples.Select(e => e.GetValue<string>()).ToList();
98+
}
99+
}
100+
}
101+
63102
private static void SetMessages(ParsingContext context, AsyncApiDocument document)
64103
{
65104
var messages = context.GetFromTempStorage<Dictionary<string, AsyncApiMessage>>(TempStorageKeys.ComponentMessages);

src/ByteBard.AsyncAPI.Readers/V2/AsyncApiParameterDeserializer.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace ByteBard.AsyncAPI.Readers
22
{
3+
using System.Collections.Generic;
34
using ByteBard.AsyncAPI.Extensions;
45
using ByteBard.AsyncAPI.Models;
56
using ByteBard.AsyncAPI.Readers.ParseNodes;
@@ -23,6 +24,14 @@ internal static partial class AsyncApiV2Deserializer
2324
private static void LoadParameterFromSchema(AsyncApiParameter instance, ParseNode node)
2425
{
2526
var schema = AsyncApiJsonSchemaDeserializer.LoadSchema(node);
27+
if (schema is AsyncApiJsonSchemaReference schemaReference)
28+
{
29+
var existingReferences = node.Context.GetFromTempStorage<Dictionary<AsyncApiParameter, AsyncApiJsonSchemaReference>>(TempStorageKeys.ParameterSchemaReferences) ?? new Dictionary<AsyncApiParameter, AsyncApiJsonSchemaReference>();
30+
existingReferences.Add(instance, schemaReference);
31+
node.Context.SetTempStorage(TempStorageKeys.ParameterSchemaReferences, existingReferences);
32+
return;
33+
}
34+
2635
if (schema.Enum.Any())
2736
{
2837
instance.Enum = schema.Enum.Select(e => e.GetValue<string>()).ToList();

test/ByteBard.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,5 +1304,89 @@ public void V2_SerializeV2_WithBindings_Serializes()
13041304

13051305
Assert.AreEqual("this mah binding", httpBinding.Headers.Description);
13061306
}
1307+
1308+
[Test]
1309+
public void V2_DocumentWithParameterReference_ResolvesToParameter()
1310+
{
1311+
var input = """
1312+
{
1313+
"asyncapi": "2.6.0",
1314+
"info": {
1315+
"title": "NikolajApi",
1316+
"description": "Trying to work with enum in parameter",
1317+
"contact": {
1318+
"url": "https://github.com/Nikolajls",
1319+
"name": "Nikolaj",
1320+
"email": "test@test.com"
1321+
},
1322+
"version": "0.0.1"
1323+
},
1324+
"servers": {
1325+
"integration-pulsar": {
1326+
"url": "pulsar+ssl://localhost:6651",
1327+
"protocol": "pulsar+ssl"
1328+
}
1329+
},
1330+
"channels": {
1331+
"v1.Room.{roomId}.Opened": {
1332+
"publish": {
1333+
"description": "Publish a message about a room being opened",
1334+
"operationId": "pub-room",
1335+
"message": {
1336+
"$ref": "#/components/messages/RoomOpened"
1337+
}
1338+
},
1339+
"parameters": {
1340+
"roomId": {
1341+
"schema": {
1342+
"$ref": "#/components/schemas/Rooms"
1343+
},
1344+
"description": "The ID of the room"
1345+
}
1346+
}
1347+
}
1348+
},
1349+
"components": {
1350+
"schemas": {
1351+
"RoomOpened": {
1352+
"type": "object",
1353+
"properties": {
1354+
"roomName": {
1355+
"type": "string",
1356+
"examples": [
1357+
"ABC"
1358+
]
1359+
}
1360+
},
1361+
"additionalProperties": false
1362+
},
1363+
"Rooms": {
1364+
"enum": [
1365+
"123",
1366+
"245",
1367+
"678"
1368+
],
1369+
"type": "string"
1370+
}
1371+
},
1372+
"messages": {
1373+
"RoomOpened": {
1374+
"name": "RoomOpened",
1375+
"summary": "Message indicating a room has been opened",
1376+
"contentType": "application/json",
1377+
"payload": {
1378+
"$ref": "#/components/schemas/RoomOpened"
1379+
}
1380+
}
1381+
}
1382+
}
1383+
}
1384+
""";
1385+
1386+
var document = new AsyncApiStringReader().Read(input, out var diagnostic);
1387+
diagnostic.Errors.Should().BeEmpty();
1388+
diagnostic.Warnings.Should().BeEmpty();
1389+
document.Channels.First().Value.Parameters.First().Value.Enum.Should().HaveCount(3);
1390+
}
13071391
}
13081392
}

0 commit comments

Comments
 (0)