-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathAsyncApiDocument.cs
More file actions
211 lines (180 loc) · 8.04 KB
/
AsyncApiDocument.cs
File metadata and controls
211 lines (180 loc) · 8.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Copyright (c) The LEGO Group. All rights reserved.
namespace LEGO.AsyncAPI.Models
{
using System;
using System.Collections.Generic;
using LEGO.AsyncAPI.Exceptions;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Services;
using LEGO.AsyncAPI.Writers;
/// <summary>
/// This is the root document object for the API specification. It combines resource listing and API declaration together into one document.
/// </summary>
public class AsyncApiDocument : IAsyncApiExtensible, IAsyncApiSerializable
{
/// <summary>
/// REQUIRED. Specifies the AsyncAPI Specification version being used.
/// </summary>
public string Asyncapi { get; set; }
/// <summary>
/// Identifier of the application the AsyncAPI document is defining.
/// </summary>
public string Id { get; set; }
/// <summary>
/// REQUIRED. Provides metadata about the API. The metadata can be used by the clients if needed.
/// </summary>
public AsyncApiInfo Info { get; set; }
/// <summary>
/// provides connection details of servers.
/// </summary>
public IDictionary<string, AsyncApiServer> Servers { get; set; } = new Dictionary<string, AsyncApiServer>();
/// <summary>
/// default content type to use when encoding/decoding a message's payload.
/// </summary>
/// <remarks>
/// A string representing the default content type to use when encoding/decoding a message's payload.
/// The value MUST be a specific media type (e.g. application/json). This value MUST be used by schema parsers when the contentType property is omitted.
/// </remarks>
public string DefaultContentType { get; set; }
/// <summary>
/// REQUIRED. The available channels and messages for the API.
/// </summary>
public IDictionary<string, AsyncApiChannel> Channels { get; set; }
/// <summary>
/// an element to hold various schemas for the specification.
/// </summary>
public AsyncApiComponents Components { get; set; }
/// <summary>
/// a list of tags used by the specification with additional metadata. Each tag name in the list MUST be unique.
/// </summary>
public IList<AsyncApiTag> Tags { get; set; } = new List<AsyncApiTag>();
/// <summary>
/// additional external documentation.
/// </summary>
public AsyncApiExternalDocumentation ExternalDocs { get; set; }
/// <inheritdoc/>
public IDictionary<string, IAsyncApiExtension> Extensions { get; set; } = new Dictionary<string, IAsyncApiExtension>();
public void SerializeV2(IAsyncApiWriter writer)
{
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}
if (writer.GetSettings().InlineReferences)
{
this.ResolveReferences();
}
writer.WriteStartObject();
// asyncApi
writer.WriteRequiredProperty(AsyncApiConstants.AsyncApi, "2.6.0");
// info
writer.WriteRequiredObject(AsyncApiConstants.Info, this.Info, (w, i) => i.SerializeV2(w));
// id
writer.WriteOptionalProperty(AsyncApiConstants.Id, this.Id);
// servers
writer.WriteOptionalMap(AsyncApiConstants.Servers, this.Servers, (writer, key, component) =>
{
if (component.Reference != null &&
component.Reference.Type == ReferenceType.Server &&
component.Reference.Id == key)
{
component.SerializeV2WithoutReference(writer);
}
else
{
component.SerializeV2(writer);
}
});
// content type
writer.WriteOptionalProperty(AsyncApiConstants.DefaultContentType, this.DefaultContentType);
// channels
writer.WriteRequiredMap(AsyncApiConstants.Channels, this.Channels, (writer, key, component) =>
{
if (component.Reference != null &&
component.Reference.Type == ReferenceType.Channel &&
component.Reference.Id == key)
{
component.SerializeV2WithoutReference(writer);
}
else
{
component.SerializeV2(writer);
}
});
// components
writer.WriteOptionalObject(AsyncApiConstants.Components, this.Components, (w, c) => c.SerializeV2(w));
// tags
writer.WriteOptionalCollection(AsyncApiConstants.Tags, this.Tags, (w, t) => t.SerializeV2(w));
// external docs
writer.WriteOptionalObject(AsyncApiConstants.ExternalDocs, this.ExternalDocs, (w, e) => e.SerializeV2(w));
// extensions
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}
public IEnumerable<AsyncApiError> ResolveReferences()
{
var resolver = new AsyncApiReferenceResolver(this);
var walker = new AsyncApiWalker(resolver);
walker.Walk(this);
return resolver.Errors;
}
internal T ResolveReference<T>(AsyncApiReference reference)
where T : class, IAsyncApiReferenceable
{
return this.ResolveReference(reference) as T;
}
internal IAsyncApiReferenceable ResolveReference(AsyncApiReference reference)
{
if (reference == null)
{
return null;
}
if (!reference.Type.HasValue)
{
throw new ArgumentException("Reference must have a type.");
}
if (this.Components == null)
{
throw new AsyncApiException(string.Format("Invalid reference Id: '{0}'", reference.Id));
}
try
{
switch (reference.Type)
{
case ReferenceType.Schema:
return this.Components.Schemas[reference.Id];
case ReferenceType.Server:
return this.Components.Servers[reference.Id];
case ReferenceType.Channel:
return this.Components.Channels[reference.Id];
case ReferenceType.Message:
return this.Components.Messages[reference.Id];
case ReferenceType.SecurityScheme:
return this.Components.SecuritySchemes[reference.Id];
case ReferenceType.Parameter:
return this.Components.Parameters[reference.Id];
case ReferenceType.CorrelationId:
return this.Components.CorrelationIds[reference.Id];
case ReferenceType.OperationTrait:
return this.Components.OperationTraits[reference.Id];
case ReferenceType.MessageTrait:
return this.Components.MessageTraits[reference.Id];
case ReferenceType.ServerBindings:
return this.Components.ServerBindings[reference.Id];
case ReferenceType.ChannelBindings:
return this.Components.ChannelBindings[reference.Id];
case ReferenceType.OperationBindings:
return this.Components.OperationBindings[reference.Id];
case ReferenceType.MessageBindings:
return this.Components.MessageBindings[reference.Id];
default:
throw new AsyncApiException("Invalid reference type.");
}
}
catch (KeyNotFoundException)
{
throw new AsyncApiException(string.Format("Invalid reference Id: '{0}'", reference.Id));
}
}
}
}