Skip to content

Commit 962b971

Browse files
authored
Merge pull request #822 from microsoft/fix/warnings
Added support for Validation to produce warnings as well as errors
2 parents a09cc5c + decde9d commit 962b971

17 files changed

+162
-69
lines changed

src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public class OpenApiDiagnostic : IDiagnostic
1717
/// </summary>
1818
public IList<OpenApiError> Errors { get; set; } = new List<OpenApiError>();
1919

20+
/// <summary>
21+
/// List of all warnings
22+
/// </summary>
23+
public IList<OpenApiError> Warnings { get; set; } = new List<OpenApiError>();
24+
2025
/// <summary>
2126
/// Open API specification version of the document parsed.
2227
/// </summary>

src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs

Lines changed: 9 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.IO;
7+
using System.Linq;
78
using System.Threading.Tasks;
89
using Microsoft.OpenApi.Exceptions;
910
using Microsoft.OpenApi.Extensions;
@@ -12,6 +13,7 @@
1213
using Microsoft.OpenApi.Readers.Interface;
1314
using Microsoft.OpenApi.Readers.Services;
1415
using Microsoft.OpenApi.Services;
16+
using Microsoft.OpenApi.Validations;
1517
using SharpYaml.Serialization;
1618

1719
namespace Microsoft.OpenApi.Readers
@@ -68,11 +70,16 @@ public OpenApiDocument Read(YamlDocument input, out OpenApiDiagnostic diagnostic
6870
// Validate the document
6971
if (_settings.RuleSet != null && _settings.RuleSet.Rules.Count > 0)
7072
{
71-
var errors = document.Validate(_settings.RuleSet);
72-
foreach (var item in errors)
73+
var openApiErrors = document.Validate(_settings.RuleSet);
74+
foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorError))
7375
{
7476
diagnostic.Errors.Add(item);
7577
}
78+
foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorWarning))
79+
{
80+
diagnostic.Warnings.Add(item);
81+
}
82+
7683
}
7784

7885
return document;

src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System.Collections.Generic;
5+
using System.Linq;
56
using Microsoft.OpenApi.Interfaces;
67
using Microsoft.OpenApi.Models;
78
using Microsoft.OpenApi.Services;
@@ -25,7 +26,7 @@ public static IEnumerable<OpenApiError> Validate(this IOpenApiElement element, V
2526
var validator = new OpenApiValidator(ruleSet);
2627
var walker = new OpenApiWalker(validator);
2728
walker.Walk(element);
28-
return validator.Errors;
29+
return validator.Errors.Cast<OpenApiError>().Union(validator.Warnings);
2930
}
3031
}
3132
}

src/Microsoft.OpenApi/Validations/IValidationContext.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ public interface IValidationContext
1414
/// <param name="error">Error to register.</param>
1515
void AddError(OpenApiValidatorError error);
1616

17+
/// <summary>
18+
/// Register a warning with the validation context.
19+
/// </summary>
20+
/// <param name="warning">Warning to register.</param>
21+
void AddWarning(OpenApiValidatorWarning warning);
22+
1723
/// <summary>
1824
/// Allow Rule to indicate validation error occured at a deeper context level.
1925
/// </summary>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Microsoft.OpenApi.Exceptions;
5+
using Microsoft.OpenApi.Models;
6+
7+
namespace Microsoft.OpenApi.Validations
8+
{
9+
/// <summary>
10+
/// Warnings detected when validating an OpenAPI Element
11+
/// </summary>
12+
public class OpenApiValidatorWarning : OpenApiError
13+
{
14+
/// <summary>
15+
/// Initializes the <see cref="OpenApiError"/> class.
16+
/// </summary>
17+
public OpenApiValidatorWarning(string ruleName, string pointer, string message) : base(pointer, message)
18+
{
19+
RuleName = ruleName;
20+
}
21+
22+
/// <summary>
23+
/// Name of rule that detected the error.
24+
/// </summary>
25+
public string RuleName { get; set; }
26+
}
27+
28+
}

src/Microsoft.OpenApi/Validations/OpenApiValidator.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class OpenApiValidator : OpenApiVisitorBase, IValidationContext
1717
{
1818
private readonly ValidationRuleSet _ruleSet;
1919
private readonly IList<OpenApiValidatorError> _errors = new List<OpenApiValidatorError>();
20+
private readonly IList<OpenApiValidatorWarning> _warnings = new List<OpenApiValidatorWarning>();
2021

2122
/// <summary>
2223
/// Create a vistor that will validate an OpenAPIDocument
@@ -38,6 +39,17 @@ public IEnumerable<OpenApiValidatorError> Errors
3839
}
3940
}
4041

42+
/// <summary>
43+
/// Gets the validation warnings.
44+
/// </summary>
45+
public IEnumerable<OpenApiValidatorWarning> Warnings
46+
{
47+
get
48+
{
49+
return _warnings;
50+
}
51+
}
52+
4153
/// <summary>
4254
/// Register an error with the validation context.
4355
/// </summary>
@@ -52,6 +64,19 @@ public void AddError(OpenApiValidatorError error)
5264
_errors.Add(error);
5365
}
5466

67+
/// <summary>
68+
/// Register an error with the validation context.
69+
/// </summary>
70+
/// <param name="warning">Error to register.</param>
71+
public void AddWarning(OpenApiValidatorWarning warning)
72+
{
73+
if (warning == null)
74+
{
75+
throw Error.ArgumentNull(nameof(warning));
76+
}
77+
78+
_warnings.Add(warning);
79+
}
5580

5681
/// <summary>
5782
/// Execute validation rules against an <see cref="OpenApiDocument"/>

src/Microsoft.OpenApi/Validations/Rules/OpenApiHeaderRules.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Microsoft.OpenApi.Validations.Rules
1010
/// <summary>
1111
/// The validation rules for <see cref="OpenApiHeader"/>.
1212
/// </summary>
13+
//Removed from Default Rules as this is not a MUST in OpenAPI
1314
[OpenApiRule]
1415
public static class OpenApiHeaderRules
1516
{

src/Microsoft.OpenApi/Validations/Rules/OpenApiMediaTypeRules.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Microsoft.OpenApi.Validations.Rules
1717
/// Future versions of the example parsers should not try an infer types.
1818
/// Example validation should be done as a separate post reading step so all schemas can be fully available.
1919
/// </remarks>
20-
//[OpenApiRule]
20+
[OpenApiRule]
2121
public static class OpenApiMediaTypeRules
2222
{
2323
/// <summary>

src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Microsoft.OpenApi.Validations.Rules
1111
/// <summary>
1212
/// The validation rules for <see cref="OpenApiSchema"/>.
1313
/// </summary>
14+
1415
[OpenApiRule]
1516
public static class OpenApiSchemaRules
1617
{

src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static void ValidateDataTypeMismatch(
7777
// If value is not a string and also not an object, there is a data mismatch.
7878
if (!(value is OpenApiObject))
7979
{
80-
context.CreateError(
80+
context.CreateWarning(
8181
ruleName,
8282
DataTypeMismatchedErrorMessage);
8383
return;
@@ -117,7 +117,7 @@ public static void ValidateDataTypeMismatch(
117117
// If value is not a string and also not an array, there is a data mismatch.
118118
if (!(value is OpenApiArray))
119119
{
120-
context.CreateError(
120+
context.CreateWarning(
121121
ruleName,
122122
DataTypeMismatchedErrorMessage);
123123
return;
@@ -141,7 +141,7 @@ public static void ValidateDataTypeMismatch(
141141
{
142142
if (!(value is OpenApiInteger))
143143
{
144-
context.CreateError(
144+
context.CreateWarning(
145145
ruleName,
146146
DataTypeMismatchedErrorMessage);
147147
}
@@ -153,7 +153,7 @@ public static void ValidateDataTypeMismatch(
153153
{
154154
if (!(value is OpenApiLong))
155155
{
156-
context.CreateError(
156+
context.CreateWarning(
157157
ruleName,
158158
DataTypeMismatchedErrorMessage);
159159
}
@@ -165,7 +165,7 @@ public static void ValidateDataTypeMismatch(
165165
{
166166
if (!(value is OpenApiInteger))
167167
{
168-
context.CreateError(
168+
context.CreateWarning(
169169
ruleName,
170170
DataTypeMismatchedErrorMessage);
171171
}
@@ -177,7 +177,7 @@ public static void ValidateDataTypeMismatch(
177177
{
178178
if (!(value is OpenApiFloat))
179179
{
180-
context.CreateError(
180+
context.CreateWarning(
181181
ruleName,
182182
DataTypeMismatchedErrorMessage);
183183
}
@@ -189,7 +189,7 @@ public static void ValidateDataTypeMismatch(
189189
{
190190
if (!(value is OpenApiDouble))
191191
{
192-
context.CreateError(
192+
context.CreateWarning(
193193
ruleName,
194194
DataTypeMismatchedErrorMessage);
195195
}
@@ -201,7 +201,7 @@ public static void ValidateDataTypeMismatch(
201201
{
202202
if (!(value is OpenApiDouble))
203203
{
204-
context.CreateError(
204+
context.CreateWarning(
205205
ruleName,
206206
DataTypeMismatchedErrorMessage);
207207
}
@@ -213,7 +213,7 @@ public static void ValidateDataTypeMismatch(
213213
{
214214
if (!(value is OpenApiByte))
215215
{
216-
context.CreateError(
216+
context.CreateWarning(
217217
ruleName,
218218
DataTypeMismatchedErrorMessage);
219219
}
@@ -225,7 +225,7 @@ public static void ValidateDataTypeMismatch(
225225
{
226226
if (!(value is OpenApiDate))
227227
{
228-
context.CreateError(
228+
context.CreateWarning(
229229
ruleName,
230230
DataTypeMismatchedErrorMessage);
231231
}
@@ -237,7 +237,7 @@ public static void ValidateDataTypeMismatch(
237237
{
238238
if (!(value is OpenApiDateTime))
239239
{
240-
context.CreateError(
240+
context.CreateWarning(
241241
ruleName,
242242
DataTypeMismatchedErrorMessage);
243243
}
@@ -249,7 +249,7 @@ public static void ValidateDataTypeMismatch(
249249
{
250250
if (!(value is OpenApiPassword))
251251
{
252-
context.CreateError(
252+
context.CreateWarning(
253253
ruleName,
254254
DataTypeMismatchedErrorMessage);
255255
}
@@ -261,7 +261,7 @@ public static void ValidateDataTypeMismatch(
261261
{
262262
if (!(value is OpenApiString))
263263
{
264-
context.CreateError(
264+
context.CreateWarning(
265265
ruleName,
266266
DataTypeMismatchedErrorMessage);
267267
}
@@ -273,7 +273,7 @@ public static void ValidateDataTypeMismatch(
273273
{
274274
if (!(value is OpenApiBoolean))
275275
{
276-
context.CreateError(
276+
context.CreateWarning(
277277
ruleName,
278278
DataTypeMismatchedErrorMessage);
279279
}

0 commit comments

Comments
 (0)