Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Microsoft.OpenApi.Readers/OpenApiDiagnostic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public class OpenApiDiagnostic : IDiagnostic
/// </summary>
public IList<OpenApiError> Errors { get; set; } = new List<OpenApiError>();

/// <summary>
/// List of all warnings
/// </summary>
public IList<OpenApiError> Warnings { get; set; } = new List<OpenApiError>();

/// <summary>
/// Open API specification version of the document parsed.
/// </summary>
Expand Down
11 changes: 9 additions & 2 deletions src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Extensions;
Expand All @@ -12,6 +13,7 @@
using Microsoft.OpenApi.Readers.Interface;
using Microsoft.OpenApi.Readers.Services;
using Microsoft.OpenApi.Services;
using Microsoft.OpenApi.Validations;
using SharpYaml.Serialization;

namespace Microsoft.OpenApi.Readers
Expand Down Expand Up @@ -68,11 +70,16 @@ public OpenApiDocument Read(YamlDocument input, out OpenApiDiagnostic diagnostic
// Validate the document
if (_settings.RuleSet != null && _settings.RuleSet.Rules.Count > 0)
{
var errors = document.Validate(_settings.RuleSet);
foreach (var item in errors)
var openApiErrors = document.Validate(_settings.RuleSet);
foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorError))
{
diagnostic.Errors.Add(item);
}
foreach (var item in openApiErrors.Where(e => e is OpenApiValidatorWarning))
{
diagnostic.Warnings.Add(item);
}

}

return document;
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license.

using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Services;
Expand All @@ -25,7 +26,7 @@ public static IEnumerable<OpenApiError> Validate(this IOpenApiElement element, V
var validator = new OpenApiValidator(ruleSet);
var walker = new OpenApiWalker(validator);
walker.Walk(element);
return validator.Errors;
return validator.Errors.Cast<OpenApiError>().Union(validator.Warnings);
}
}
}
6 changes: 6 additions & 0 deletions src/Microsoft.OpenApi/Validations/IValidationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public interface IValidationContext
/// <param name="error">Error to register.</param>
void AddError(OpenApiValidatorError error);

/// <summary>
/// Register a warning with the validation context.
/// </summary>
/// <param name="warning">Warning to register.</param>
void AddWarning(OpenApiValidatorWarning warning);

/// <summary>
/// Allow Rule to indicate validation error occured at a deeper context level.
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions src/Microsoft.OpenApi/Validations/OpenApiValidatiorWarning.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Models;

namespace Microsoft.OpenApi.Validations
{
/// <summary>
/// Warnings detected when validating an OpenAPI Element
/// </summary>
public class OpenApiValidatorWarning : OpenApiError
{
/// <summary>
/// Initializes the <see cref="OpenApiError"/> class.
/// </summary>
public OpenApiValidatorWarning(string ruleName, string pointer, string message) : base(pointer, message)
{
RuleName = ruleName;
}

/// <summary>
/// Name of rule that detected the error.
/// </summary>
public string RuleName { get; set; }
}

}
25 changes: 25 additions & 0 deletions src/Microsoft.OpenApi/Validations/OpenApiValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class OpenApiValidator : OpenApiVisitorBase, IValidationContext
{
private readonly ValidationRuleSet _ruleSet;
private readonly IList<OpenApiValidatorError> _errors = new List<OpenApiValidatorError>();
private readonly IList<OpenApiValidatorWarning> _warnings = new List<OpenApiValidatorWarning>();

/// <summary>
/// Create a vistor that will validate an OpenAPIDocument
Expand All @@ -38,6 +39,17 @@ public IEnumerable<OpenApiValidatorError> Errors
}
}

/// <summary>
/// Gets the validation warnings.
/// </summary>
public IEnumerable<OpenApiValidatorWarning> Warnings
{
get
{
return _warnings;
}
}

/// <summary>
/// Register an error with the validation context.
/// </summary>
Expand All @@ -52,6 +64,19 @@ public void AddError(OpenApiValidatorError error)
_errors.Add(error);
}

/// <summary>
/// Register an error with the validation context.
/// </summary>
/// <param name="warning">Error to register.</param>
public void AddWarning(OpenApiValidatorWarning warning)
{
if (warning == null)
{
throw Error.ArgumentNull(nameof(warning));
}

_warnings.Add(warning);
}

/// <summary>
/// Execute validation rules against an <see cref="OpenApiDocument"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Microsoft.OpenApi.Validations.Rules
/// <summary>
/// The validation rules for <see cref="OpenApiHeader"/>.
/// </summary>
//Removed from Default Rules as this is not a MUST in OpenAPI
[OpenApiRule]
public static class OpenApiHeaderRules
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.OpenApi.Validations.Rules
/// Future versions of the example parsers should not try an infer types.
/// Example validation should be done as a separate post reading step so all schemas can be fully available.
/// </remarks>
//[OpenApiRule]
[OpenApiRule]
public static class OpenApiMediaTypeRules
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Microsoft.OpenApi.Validations.Rules
/// <summary>
/// The validation rules for <see cref="OpenApiSchema"/>.
/// </summary>

[OpenApiRule]
public static class OpenApiSchemaRules
{
Expand Down
28 changes: 14 additions & 14 deletions src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static void ValidateDataTypeMismatch(
// If value is not a string and also not an object, there is a data mismatch.
if (!(value is OpenApiObject))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
return;
Expand Down Expand Up @@ -117,7 +117,7 @@ public static void ValidateDataTypeMismatch(
// If value is not a string and also not an array, there is a data mismatch.
if (!(value is OpenApiArray))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
return;
Expand All @@ -141,7 +141,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiInteger))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -153,7 +153,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiLong))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -165,7 +165,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiInteger))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -177,7 +177,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiFloat))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -189,7 +189,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiDouble))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -201,7 +201,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiDouble))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -213,7 +213,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiByte))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -225,7 +225,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiDate))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -237,7 +237,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiDateTime))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -249,7 +249,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiPassword))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -261,7 +261,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiString))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand All @@ -273,7 +273,7 @@ public static void ValidateDataTypeMismatch(
{
if (!(value is OpenApiBoolean))
{
context.CreateError(
context.CreateWarning(
ruleName,
DataTypeMismatchedErrorMessage);
}
Expand Down
10 changes: 10 additions & 0 deletions src/Microsoft.OpenApi/Validations/ValidationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,15 @@ public static void CreateError(this IValidationContext context, string ruleName,
OpenApiValidatorError error = new OpenApiValidatorError(ruleName, context.PathString, message);
context.AddError(error);
}

/// <summary>
/// Helper method to simplify validation rules
/// </summary>
public static void CreateWarning(this IValidationContext context, string ruleName, string message)
{
OpenApiValidatorWarning warning = new OpenApiValidatorWarning(ruleName, context.PathString, message);
context.AddWarning(warning);
}

}
}
10 changes: 10 additions & 0 deletions test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1085,14 +1085,17 @@ namespace Microsoft.OpenApi.Validations
{
string PathString { get; }
void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error);
void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning);
void Enter(string segment);
void Exit();
}
public class OpenApiValidator : Microsoft.OpenApi.Services.OpenApiVisitorBase, Microsoft.OpenApi.Validations.IValidationContext
{
public OpenApiValidator(Microsoft.OpenApi.Validations.ValidationRuleSet ruleSet) { }
public System.Collections.Generic.IEnumerable<Microsoft.OpenApi.Validations.OpenApiValidatorError> Errors { get; }
public System.Collections.Generic.IEnumerable<Microsoft.OpenApi.Validations.OpenApiValidatorWarning> Warnings { get; }
public void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error) { }
public void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning) { }
public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtensible item) { }
public override void Visit(Microsoft.OpenApi.Interfaces.IOpenApiExtension item) { }
public override void Visit(Microsoft.OpenApi.Models.OpenApiCallback item) { }
Expand All @@ -1119,9 +1122,15 @@ namespace Microsoft.OpenApi.Validations
public OpenApiValidatorError(string ruleName, string pointer, string message) { }
public string RuleName { get; set; }
}
public class OpenApiValidatorWarning : Microsoft.OpenApi.Models.OpenApiError
{
public OpenApiValidatorWarning(string ruleName, string pointer, string message) { }
public string RuleName { get; set; }
}
public static class ValidationContextExtensions
{
public static void CreateError(this Microsoft.OpenApi.Validations.IValidationContext context, string ruleName, string message) { }
public static void CreateWarning(this Microsoft.OpenApi.Validations.IValidationContext context, string ruleName, string message) { }
}
public abstract class ValidationRule
{
Expand Down Expand Up @@ -1188,6 +1197,7 @@ namespace Microsoft.OpenApi.Validations.Rules
{
public static Microsoft.OpenApi.Validations.ValidationRule<Microsoft.OpenApi.Models.OpenApiLicense> LicenseRequiredFields { get; }
}
[Microsoft.OpenApi.Validations.Rules.OpenApiRule]
public static class OpenApiMediaTypeRules
{
public static Microsoft.OpenApi.Validations.ValidationRule<Microsoft.OpenApi.Models.OpenApiMediaType> MediaTypeMismatchedDataType { get; }
Expand Down
Loading