Skip to content

Commit 7d48424

Browse files
authored
Merge pull request #113 from Microsoft/PerthCharern/UpdateV2Reader
Add deserializers and restructure the Reader unit tests
2 parents 3c2042f + 4d25aba commit 7d48424

File tree

99 files changed

+3473
-2630
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+3473
-2630
lines changed

src/Microsoft.OpenApi.Readers/OpenApiError.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,40 @@ namespace Microsoft.OpenApi.Readers
1212
/// </summary>
1313
public class OpenApiError
1414
{
15-
private readonly string _message;
16-
private readonly string _pointer;
15+
/// <summary>
16+
/// Message explaining the error.
17+
/// </summary>
18+
public string Message { get; set; }
19+
20+
/// <summary>
21+
/// Pointer to the location of the error.
22+
/// </summary>
23+
public string Pointer { get; set; }
1724

1825
/// <summary>
1926
/// Initializes the <see cref="OpenApiError"/> class using the message and pointer from the given exception.
2027
/// </summary>
2128
public OpenApiError(OpenApiException exception)
2229
{
23-
_message = exception.Message;
24-
_pointer = exception.Pointer;
30+
Message = exception.Message;
31+
Pointer = exception.Pointer;
2532
}
2633

2734
/// <summary>
2835
/// Initializes the <see cref="OpenApiError"/> class.
2936
/// </summary>
3037
public OpenApiError(string pointer, string message)
3138
{
32-
this._pointer = pointer;
33-
this._message = message;
39+
this.Pointer = pointer;
40+
this.Message = message;
3441
}
3542

3643
/// <summary>
3744
/// Gets the string representation of <see cref="OpenApiError"/>.
3845
/// </summary>
39-
/// <returns></returns>
4046
public override string ToString()
4147
{
42-
return _message + (!string.IsNullOrEmpty(_pointer) ? " at " + _pointer : "");
48+
return Message + (!string.IsNullOrEmpty(Pointer) ? " at " + Pointer : "");
4349
}
4450
}
4551
}

src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public MapNode(ParsingContext context, OpenApiDiagnostic diagnostic, YamlMapping
3535
{
3636
if (node == null)
3737
{
38-
throw new OpenApiException($"Expected map");
38+
throw new OpenApiException("Expected map");
3939
}
4040

4141
this.node = node;
@@ -72,8 +72,12 @@ public override Dictionary<string, T> CreateMap<T>(Func<MapNode, T> map)
7272
n => new
7373
{
7474
key = n.Key.GetScalarValue(),
75-
value = map(new MapNode(Context, Diagnostic, n.Value as YamlMappingNode))
75+
value = n.Value as YamlMappingNode == null ?
76+
default(T) :
77+
map(new MapNode(Context, Diagnostic, n.Value as YamlMappingNode))
78+
7679
});
80+
7781
return nodes.ToDictionary(k => k.key, v => v.value);
7882
}
7983

src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
44
// ------------------------------------------------------------
55

6+
using System;
67
using System.Collections.Generic;
78
using Microsoft.OpenApi.Extensions;
89
using Microsoft.OpenApi.Models;
@@ -21,7 +22,7 @@ internal static partial class OpenApiV2Deserializer
2122
{
2223
"swagger", (o, n) =>
2324
{
24-
/* Ignore it */
25+
o.SpecVersion = new Version(2, 0);
2526
}
2627
},
2728
{"info", (o, n) => o.Info = LoadInfo(n)},
@@ -31,10 +32,7 @@ internal static partial class OpenApiV2Deserializer
3132
"schemes", (o, n) => n.Context.SetTempStorage(
3233
"schemes",
3334
n.CreateSimpleList(
34-
s =>
35-
{
36-
return s.GetScalarValue();
37-
}))
35+
s => s.GetScalarValue()))
3836
},
3937
{
4038
"consumes",

src/Microsoft.OpenApi.Readers/V2/OpenApiSchemaDeserializer.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,27 @@ internal static partial class OpenApiV2Deserializer
163163
o.Default = new OpenApiString(n.GetScalarValue());
164164
}
165165
},
166-
167-
// discriminator
166+
{
167+
"discriminator", (o, n) =>
168+
{
169+
o.Discriminator = new OpenApiDiscriminator()
170+
{
171+
PropertyName = n.GetScalarValue()
172+
};
173+
}
174+
},
168175
{
169176
"readOnly", (o, n) =>
170177
{
171178
o.ReadOnly = bool.Parse(n.GetScalarValue());
172179
}
173180
},
174-
// xml
181+
{
182+
"xml", (o, n) =>
183+
{
184+
o.Xml = LoadXml(n);
185+
}
186+
},
175187
{
176188
"externalDocs", (o, n) =>
177189
{
@@ -181,7 +193,7 @@ internal static partial class OpenApiV2Deserializer
181193
{
182194
"example", (o, n) =>
183195
{
184-
o.Example = new OpenApiString(n.GetScalarValue());
196+
o.Example = n.CreateAny();
185197
}
186198
},
187199
};

src/Microsoft.OpenApi.Readers/V2/OpenApiSecuritySchemeDeserializer.cs

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,64 @@ namespace Microsoft.OpenApi.Readers.V2
1616
/// </summary>
1717
internal static partial class OpenApiV2Deserializer
1818
{
19+
private static string flowValue;
20+
21+
private static OpenApiOAuthFlow flow;
22+
1923
private static readonly FixedFieldMap<OpenApiSecurityScheme> SecuritySchemeFixedFields =
2024
new FixedFieldMap<OpenApiSecurityScheme>
2125
{
2226
{
2327
"type",
24-
(o, n) => o.Type = (SecuritySchemeType)Enum.Parse(typeof(SecuritySchemeType), n.GetScalarValue())
28+
(o, n) =>
29+
{
30+
var type = n.GetScalarValue();
31+
switch (type)
32+
{
33+
case "basic":
34+
o.Type = SecuritySchemeType.Http;
35+
o.Scheme = "basic";
36+
break;
37+
38+
case "apiKey":
39+
o.Type = SecuritySchemeType.ApiKey;
40+
break;
41+
42+
case "oauth2":
43+
o.Type = SecuritySchemeType.OAuth2;
44+
break;
45+
}
46+
}
2547
},
2648
{"description", (o, n) => o.Description = n.GetScalarValue()},
2749
{"name", (o, n) => o.Name = n.GetScalarValue()},
2850
{"in", (o, n) => o.In = n.GetScalarValue().GetEnumFromDisplayName<ParameterLocation>()},
29-
{"scheme", (o, n) => o.Scheme = n.GetScalarValue()},
30-
{"bearerFormat", (o, n) => o.BearerFormat = n.GetScalarValue()},
3151
{
32-
"openIdConnectUrl",
33-
(o, n) => o.OpenIdConnectUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute)
52+
"flow", (o, n) =>
53+
{
54+
flowValue = n.GetScalarValue();
55+
}
56+
},
57+
{
58+
"authorizationUrl",
59+
(o, n) =>
60+
{
61+
flow.AuthorizationUrl = new Uri(n.GetScalarValue());
62+
}
3463
},
35-
{"flows", (o, n) => o.Flows = LoadOAuthFlows(n)}
64+
{
65+
"tokenUrl",
66+
(o, n) =>
67+
{
68+
flow.TokenUrl = new Uri(n.GetScalarValue());
69+
}
70+
},
71+
{
72+
"scopes", (o, n) =>
73+
{
74+
flow.Scopes = n.CreateSimpleMap(LoadString);
75+
}
76+
}
3677
};
3778

3879
private static readonly PatternFieldMap<OpenApiSecurityScheme> SecuritySchemePatternFields =
@@ -43,6 +84,10 @@ internal static partial class OpenApiV2Deserializer
4384

4485
public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node)
4586
{
87+
// Reset the local variables every time this method is called.
88+
flowValue = null;
89+
flow = new OpenApiOAuthFlow();
90+
4691
var mapNode = node.CheckMapNode("securityScheme");
4792

4893
var securityScheme = new OpenApiSecurityScheme();
@@ -51,6 +96,36 @@ public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node)
5196
property.ParseField(securityScheme, SecuritySchemeFixedFields, SecuritySchemePatternFields);
5297
}
5398

99+
// Put the Flow object in the right Flows property based on the string in "flow"
100+
if (flowValue == OpenApiConstants.Implicit)
101+
{
102+
securityScheme.Flows = new OpenApiOAuthFlows
103+
{
104+
Implicit = flow
105+
};
106+
}
107+
else if (flowValue == OpenApiConstants.Password)
108+
{
109+
securityScheme.Flows = new OpenApiOAuthFlows
110+
{
111+
Password = flow
112+
};
113+
}
114+
else if (flowValue == OpenApiConstants.Application)
115+
{
116+
securityScheme.Flows = new OpenApiOAuthFlows
117+
{
118+
ClientCredentials = flow
119+
};
120+
}
121+
else if (flowValue == OpenApiConstants.AccessCode)
122+
{
123+
securityScheme.Flows = new OpenApiOAuthFlows
124+
{
125+
AuthorizationCode = flow
126+
};
127+
}
128+
54129
return securityScheme;
55130
}
56131
}

src/Microsoft.OpenApi.Readers/V2/OpenApiV2Deserializer.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ private static void ParseMap<T>(
3636

3737
private static void ReportMissing(ParseNode node, IList<string> required)
3838
{
39-
foreach (var error in required.Select(r => new OpenApiError("", $"{r} is a required property")).ToList())
39+
foreach (var error in required.Select(
40+
r => new OpenApiError(
41+
node.Context.GetLocation(),
42+
$"{r} is a required property"))
43+
.ToList())
4044
{
4145
node.Diagnostic.Errors.Add(error);
4246
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
4+
// ------------------------------------------------------------
5+
6+
using System;
7+
using Microsoft.OpenApi.Any;
8+
using Microsoft.OpenApi.Extensions;
9+
using Microsoft.OpenApi.Models;
10+
using Microsoft.OpenApi.Readers.ParseNodes;
11+
12+
namespace Microsoft.OpenApi.Readers.V2
13+
{
14+
/// <summary>
15+
/// Class containing logic to deserialize Open API V3 document into
16+
/// runtime Open API object model.
17+
/// </summary>
18+
internal static partial class OpenApiV2Deserializer
19+
{
20+
private static readonly FixedFieldMap<OpenApiXml> XmlFixedFields = new FixedFieldMap<OpenApiXml>
21+
{
22+
{
23+
"name", (o, n) =>
24+
{
25+
o.Name = n.GetScalarValue();
26+
}
27+
},
28+
{
29+
"namespace", (o, n) =>
30+
{
31+
o.Namespace = new Uri(n.GetScalarValue());
32+
}
33+
},
34+
{
35+
"prefix", (o, n) =>
36+
{
37+
o.Prefix = n.GetScalarValue();
38+
}
39+
},
40+
{
41+
"attribute", (o, n) =>
42+
{
43+
o.Attribute = bool.Parse(n.GetScalarValue());
44+
}
45+
},
46+
{
47+
"wrapped", (o, n) =>
48+
{
49+
o.Wrapped = bool.Parse(n.GetScalarValue());
50+
}
51+
},
52+
};
53+
54+
private static readonly PatternFieldMap<OpenApiXml> XmlPatternFields =
55+
new PatternFieldMap<OpenApiXml>
56+
{
57+
{s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, n.CreateAny())}
58+
};
59+
60+
public static OpenApiXml LoadXml(ParseNode node)
61+
{
62+
var mapNode = node.CheckMapNode("xml");
63+
64+
var xml = new OpenApiXml();
65+
foreach (var property in mapNode)
66+
{
67+
property.ParseField(xml, XmlFixedFields, XmlPatternFields);
68+
}
69+
70+
return xml;
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)