Skip to content

Commit f136444

Browse files
committed
Merge branch 'master' into MapCustomTypeToString
2 parents 734ee71 + a6b2e71 commit f136444

29 files changed

+468
-61
lines changed

Microsoft.OpenApi.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E546B92F-20A
2323
EndProject
2424
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6357D7FD-2DE4-4900-ADB9-ABC37052040A}"
2525
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.SmokeTests", "test\Microsoft.OpenApi.SmokeTests\Microsoft.OpenApi.SmokeTests.csproj", "{AD79B61D-88CF-497C-9ED5-41AE3867C5AC}"
27+
EndProject
2628
Global
2729
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2830
Debug|Any CPU = Debug|Any CPU
@@ -49,6 +51,10 @@ Global
4951
{1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Debug|Any CPU.Build.0 = Debug|Any CPU
5052
{1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Release|Any CPU.ActiveCfg = Release|Any CPU
5153
{1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Release|Any CPU.Build.0 = Release|Any CPU
54+
{AD79B61D-88CF-497C-9ED5-41AE3867C5AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55+
{AD79B61D-88CF-497C-9ED5-41AE3867C5AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
56+
{AD79B61D-88CF-497C-9ED5-41AE3867C5AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
57+
{AD79B61D-88CF-497C-9ED5-41AE3867C5AC}.Release|Any CPU.Build.0 = Release|Any CPU
5258
EndGlobalSection
5359
GlobalSection(SolutionProperties) = preSolution
5460
HideSolutionNode = FALSE
@@ -59,6 +65,7 @@ Global
5965
{79933258-0126-4382-8755-D50820ECC483} = {E546B92F-20A8-49C3-8323-4B25BB78F3E1}
6066
{AD83F991-DBF3-4251-8613-9CC54C826964} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A}
6167
{1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A}
68+
{AD79B61D-88CF-497C-9ED5-41AE3867C5AC} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A}
6269
EndGlobalSection
6370
GlobalSection(ExtensibilityGlobals) = postSolution
6471
SolutionGuid = {9F171EFC-0DB5-4B10-ABFA-AF48D52CC565}

src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<Company>Microsoft</Company>
1111
<Title>Microsoft.OpenApi.Readers</Title>
1212
<PackageId>Microsoft.OpenApi.Readers</PackageId>
13-
<Version>1.0.0-beta014</Version>
13+
<Version>1.0.0-beta015</Version>
1414
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
1515
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
1616
<PackageTags>OpenAPI .NET</PackageTags>

src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.IO;
66
using System.Linq;
7+
using Microsoft.OpenApi.Exceptions;
78
using Microsoft.OpenApi.Extensions;
89
using Microsoft.OpenApi.Models;
910
using Microsoft.OpenApi.Readers.Interface;
@@ -58,21 +59,35 @@ public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic)
5859
ExtensionParsers = _settings.ExtensionParsers
5960
};
6061

61-
// Parse the OpenAPI Document
62-
var document = context.Parse(yamlDocument, diagnostic);
62+
OpenApiDocument document = null;
6363

64-
// Resolve References if requested
65-
switch (_settings.ReferenceResolution)
64+
try
65+
{
66+
// Parse the OpenAPI Document
67+
document = context.Parse(yamlDocument, diagnostic);
68+
69+
// Resolve References if requested
70+
switch (_settings.ReferenceResolution)
71+
{
72+
case ReferenceResolutionSetting.ResolveAllReferences:
73+
throw new ArgumentException(Properties.SRResource.CannotResolveRemoteReferencesSynchronously);
74+
case ReferenceResolutionSetting.ResolveLocalReferences:
75+
var resolver = new OpenApiReferenceResolver(document);
76+
var walker = new OpenApiWalker(resolver);
77+
walker.Walk(document);
78+
foreach (var item in resolver.Errors)
79+
{
80+
diagnostic.Errors.Add(item);
81+
}
82+
break;
83+
case ReferenceResolutionSetting.DoNotResolveReferences:
84+
break;
85+
}
86+
87+
}
88+
catch (OpenApiException ex)
6689
{
67-
case ReferenceResolutionSetting.ResolveAllReferences:
68-
throw new ArgumentException(Properties.SRResource.CannotResolveRemoteReferencesSynchronously);
69-
case ReferenceResolutionSetting.ResolveLocalReferences:
70-
var resolver = new OpenApiReferenceResolver(document);
71-
var walker = new OpenApiWalker(resolver);
72-
walker.Walk(document);
73-
break;
74-
case ReferenceResolutionSetting.DoNotResolveReferences:
75-
break;
90+
diagnostic.Errors.Add(new OpenApiError(ex));
7691
}
7792

7893
// Validate the document

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,33 @@ public ListNode(ParsingContext context, OpenApiDiagnostic diagnostic, YamlSequen
2626

2727
public override List<T> CreateList<T>(Func<MapNode, T> map)
2828
{
29-
var yamlSequence = _nodeList;
30-
if (yamlSequence == null)
29+
if (_nodeList == null)
3130
{
3231
throw new OpenApiException(
3332
$"Expected list at line {_nodeList.Start.Line} while parsing {typeof(T).Name}");
3433
}
3534

36-
return yamlSequence.Select(n => map(new MapNode(Context, Diagnostic, n as YamlMappingNode)))
35+
return _nodeList.Select(n => map(new MapNode(Context, Diagnostic, n as YamlMappingNode)))
36+
.Where(i => i != null)
37+
.ToList();
38+
}
39+
40+
public override List<IOpenApiAny> CreateListOfAny()
41+
{
42+
return _nodeList.Select(n => ParseNode.Create(Context, Diagnostic,n).CreateAny())
3743
.Where(i => i != null)
3844
.ToList();
3945
}
4046

4147
public override List<T> CreateSimpleList<T>(Func<ValueNode, T> map)
4248
{
43-
var yamlSequence = _nodeList;
44-
if (yamlSequence == null)
49+
if (_nodeList == null)
4550
{
4651
throw new OpenApiException(
4752
$"Expected list at line {_nodeList.Start.Line} while parsing {typeof(T).Name}");
4853
}
4954

50-
return yamlSequence.Select(n => map(new ValueNode(Context, Diagnostic, (YamlScalarNode)n))).ToList();
55+
return _nodeList.Select(n => map(new ValueNode(Context, Diagnostic, (YamlScalarNode)n))).ToList();
5156
}
5257

5358
public IEnumerator<ParseNode> GetEnumerator()

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public override Dictionary<string, T> CreateMapWithReference<T>(
9595
key = n.Key.GetScalarValue(),
9696
value = map(new MapNode(Context, Diagnostic, (YamlMappingNode)n.Value))
9797
};
98+
if (entry.value == null)
99+
{
100+
return null; // Body Parameters shouldn't be converted to Parameters
101+
}
98102
entry.value.Reference = new OpenApiReference()
99103
{
100104
Type = referenceType,
@@ -103,7 +107,7 @@ public override Dictionary<string, T> CreateMapWithReference<T>(
103107
return entry;
104108
}
105109
);
106-
return nodes.ToDictionary(k => k.key, v => v.value);
110+
return nodes.Where(n => n!= null).ToDictionary(k => k.key, v => v.value);
107111
}
108112

109113
public override Dictionary<string, T> CreateSimpleMap<T>(Func<ValueNode, T> map)

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ public MapNode CheckMapNode(string nodeName)
3131
var mapNode = this as MapNode;
3232
if (mapNode == null)
3333
{
34-
Diagnostic.Errors.Add(
35-
new OpenApiError("", $"{nodeName} must be a map/object at " + Context.GetLocation()));
34+
throw new OpenApiException($"{nodeName} must be a map/object");
3635
}
3736

3837
return mapNode;
@@ -69,49 +68,51 @@ public static ParseNode Create(ParsingContext context, OpenApiDiagnostic diagnos
6968

7069
public virtual List<T> CreateList<T>(Func<MapNode, T> map)
7170
{
72-
throw new OpenApiException("Cannot create list");
71+
throw new OpenApiException("Cannot create list from this type of node.");
7372
}
7473

7574
public virtual Dictionary<string, T> CreateMap<T>(Func<MapNode, T> map)
7675
{
77-
throw new OpenApiException("Cannot create map");
76+
throw new OpenApiException("Cannot create map from this type of node.");
7877
}
7978

8079
public virtual Dictionary<string, T> CreateMapWithReference<T>(
8180
ReferenceType referenceType,
8281
Func<MapNode, T> map)
8382
where T : class, IOpenApiReferenceable
8483
{
85-
throw new OpenApiException("Cannot create map from reference");
84+
throw new OpenApiException("Cannot create map from this reference.");
8685
}
8786

8887
public virtual List<T> CreateSimpleList<T>(Func<ValueNode, T> map)
8988
{
90-
throw new OpenApiException("Cannot create simple list");
89+
throw new OpenApiException("Cannot create simple list from this type of node.");
9190
}
9291

9392
public virtual Dictionary<string, T> CreateSimpleMap<T>(Func<ValueNode, T> map)
9493
{
95-
throw new OpenApiException("Cannot create simple map");
94+
throw new OpenApiException("Cannot create simple map from this type of node.");
9695
}
9796

98-
/// <summary>
99-
/// Create a <see cref="IOpenApiAny"/>
100-
/// </summary>
101-
/// <returns></returns>
10297
public virtual IOpenApiAny CreateAny()
10398
{
104-
throw new NotSupportedException();
99+
throw new OpenApiException("Cannot create an Any object this type of node.");
105100
}
106101

107102
public virtual string GetRaw()
108103
{
109-
throw new OpenApiException("Cannot get raw value");
104+
throw new OpenApiException("Cannot get raw value from this type of node.");
110105
}
111106

112107
public virtual string GetScalarValue()
113108
{
114-
throw new OpenApiException("Cannot get scalar value");
109+
throw new OpenApiException("Cannot create a scalar value from this type of node.");
115110
}
111+
112+
public virtual List<IOpenApiAny> CreateListOfAny()
113+
{
114+
throw new OpenApiException("Cannot create a list from this type of node.");
115+
}
116+
116117
}
117118
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public override IOpenApiAny CreateAny()
6666
dblValue); // Note(darrmi): This may be better as decimal. Further investigation required.
6767
}
6868

69-
if (DateTime.TryParse(value, out var datetimeValue))
69+
if (DateTimeOffset.TryParse(value, out var datetimeValue))
7070
{
7171
return new OpenApiDateTime(datetimeValue);
7272
}

src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Linq;
7+
using Microsoft.OpenApi.Exceptions;
78
using Microsoft.OpenApi.Interfaces;
89
using Microsoft.OpenApi.Models;
910
using Microsoft.OpenApi.Services;
@@ -17,13 +18,22 @@ internal class OpenApiReferenceResolver : OpenApiVisitorBase
1718
{
1819
private OpenApiDocument _currentDocument;
1920
private bool _resolveRemoteReferences;
21+
private List<OpenApiError> _errors = new List<OpenApiError>();
2022

2123
public OpenApiReferenceResolver(OpenApiDocument currentDocument, bool resolveRemoteReferences = true)
2224
{
2325
_currentDocument = currentDocument;
2426
_resolveRemoteReferences = resolveRemoteReferences;
2527
}
2628

29+
public IEnumerable<OpenApiError> Errors
30+
{
31+
get
32+
{
33+
return _errors;
34+
}
35+
}
36+
2737
public override void Visit(OpenApiDocument doc)
2838
{
2939
if (doc.Tags != null)
@@ -89,6 +99,31 @@ public override void Visit(OpenApiResponses responses)
8999
ResolveMap(responses);
90100
}
91101

102+
/// <summary>
103+
/// Resolve all references to SecuritySchemes
104+
/// </summary>
105+
public override void Visit(OpenApiSecurityRequirement securityRequirement)
106+
{
107+
foreach (var scheme in securityRequirement.Keys.ToList())
108+
{
109+
ResolveObject(scheme, (resolvedScheme) => {
110+
// If scheme was unresolved
111+
// copy Scopes and remove old unresolved scheme
112+
var scopes = securityRequirement[scheme];
113+
securityRequirement.Remove(scheme);
114+
securityRequirement.Add(resolvedScheme, scopes);
115+
});
116+
}
117+
}
118+
119+
/// <summary>
120+
/// Resolve all references to parameters
121+
/// </summary>
122+
public override void Visit(IList<OpenApiParameter> parameters)
123+
{
124+
ResolveList(parameters);
125+
}
126+
92127
/// <summary>
93128
/// Resolve all references to links
94129
/// </summary>
@@ -177,11 +212,19 @@ private void ResolveTags(IList<OpenApiTag> tags)
177212
{
178213
if (string.IsNullOrEmpty(reference.ExternalResource))
179214
{
180-
return _currentDocument.ResolveReference(reference) as T;
215+
try
216+
{
217+
return _currentDocument.ResolveReference(reference) as T;
218+
}
219+
catch (OpenApiException ex)
220+
{
221+
_errors.Add(new OpenApiError(ex));
222+
return null;
223+
}
181224
}
182225
else if (_resolveRemoteReferences == true)
183226
{
184-
// TODO: Resolve Remote reference
227+
// TODO: Resolve Remote reference (Targeted for 1.1 release)
185228
return new T()
186229
{
187230
UnresolvedReference = true,

0 commit comments

Comments
 (0)