Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7316184
Init implementation for the Open API validation
xuzhg Dec 12, 2017
0988b1b
add the whole visitor classes for validation
xuzhg Dec 15, 2017
620b0f2
add the rules and modify the header copyright
xuzhg Dec 15, 2017
31a3cd9
Add test cases for external docs and response
xuzhg Dec 15, 2017
401072c
add a validation rule for the OAuthFlow object
xuzhg Dec 15, 2017
bd39460
modify to give more meaningful comments
xuzhg Dec 16, 2017
da5f90a
add the OpenApiRuleAttribute for each rule classes
xuzhg Dec 18, 2017
4a6ca43
change to lazy loading for the validation visitors
xuzhg Dec 18, 2017
2e7e2dd
Change the namespace for the Validation test files
xuzhg Dec 18, 2017
aebee6f
Add the test cases for ValidationRuleSet
xuzhg Dec 18, 2017
df86936
resolve the comments, typos and some test codes
xuzhg Dec 19, 2017
bc530c3
Validation using walker and single visitor class
darrelmiller Dec 20, 2017
b29d532
Change debug.assert to throw arugment null and use the resource from …
xuzhg Dec 20, 2017
5eccf02
Merge branch 'sam/validation3' into dm/validation
darrelmiller Dec 20, 2017
0188565
Remove visitor classes
darrelmiller Dec 20, 2017
43ae516
Enhancements to walker
darrelmiller Dec 20, 2017
fc4c334
Removed unused test
darrelmiller Dec 20, 2017
26561e3
Merge remote-tracking branch 'origin/master' into dm/validation
darrelmiller Dec 23, 2017
2fd11fa
Updated Walker to use separate methods for each element
darrelmiller Jan 2, 2018
d6dba10
Updated walkers and added validate method
darrelmiller Jan 3, 2018
9f7c7f6
Merge branch 'master' into dm/validation
darrelmiller Jan 3, 2018
6c47d49
Merge branch 'master' into dm/validation
darrelmiller Jan 11, 2018
0a4c3ee
Merge branch 'master' into dm/validation
darrelmiller Jan 11, 2018
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
72 changes: 72 additions & 0 deletions src/Microsoft.OpenApi/Properties/SRResource.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions src/Microsoft.OpenApi/Properties/SRResource.resx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@
<data name="IndentationLevelInvalid" xml:space="preserve">
<value>Indentation level cannot be lower than 0.</value>
</data>
<data name="InputItemShouldBeType" xml:space="preserve">
<value>The input item should be in type of '{0}'.</value>
</data>
<data name="ObjectScopeNeededForPropertyNameWriting" xml:space="preserve">
<value>The active scope must be an object scope for property name '{0}' to be written.</value>
</data>
Expand Down Expand Up @@ -177,4 +180,25 @@
<data name="SourceExpressionHasInvalidFormat" xml:space="preserve">
<value>The source expression '{0}' has invalid format.</value>
</data>
<data name="UnknownVisitorType" xml:space="preserve">
<value>Can not find visitor type registered for type '{0}'.</value>
</data>
<data name="Validation_ComponentsKeyMustMatchRegularExpr" xml:space="preserve">
<value>The key '{0}' in '{1}' of components MUST match the regular expression '{2}'.</value>
</data>
<data name="Validation_ExtensionNameMustBeginWithXDash" xml:space="preserve">
<value>The extension name '{0}' in '{1}' object MUST begin with 'x-'.</value>
</data>
<data name="Validation_FieldIsRequired" xml:space="preserve">
<value>The field '{0}' in '{1}' object is REQUIRED.</value>
</data>
<data name="Validation_PathItemMustBeginWithSlash" xml:space="preserve">
<value>The path item name '{0}' MUST begin with a slash.</value>
</data>
<data name="Validation_RuleAddTwice" xml:space="preserve">
<value>The same rule cannot be in the same rule set twice.</value>
</data>
<data name="Validation_StringMustBeEmailAddress" xml:space="preserve">
<value>The string '{0}' MUST be in the format of an email address.</value>
</data>
</root>
43 changes: 34 additions & 9 deletions src/Microsoft.OpenApi/Services/OpenApiValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Licensed under the MIT license.

using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Validations;

namespace Microsoft.OpenApi.Services
{
Expand All @@ -12,20 +14,43 @@ namespace Microsoft.OpenApi.Services
/// </summary>
public class OpenApiValidator : OpenApiVisitorBase
{
/// <summary>
/// Exceptions related to this validation.
/// </summary>
public List<OpenApiException> Exceptions { get; } = new List<OpenApiException>();
readonly ValidationRuleSet _ruleSet;
readonly ValidationContext _context;

/// <summary>
/// Visit Open API Response element.
/// Create a vistor that will validate an OpenAPIDocument
/// </summary>
/// <param name="response">Response element.</param>
public override void Visit(OpenApiResponse response)
/// <param name="ruleSet"></param>
public OpenApiValidator(ValidationRuleSet ruleSet = null)
{
_ruleSet = ruleSet ?? ValidationRuleSet.DefaultRuleSet;
_context = new ValidationContext(_ruleSet);
}

public override void Visit(OpenApiDocument item) => Validate(item);
public override void Visit(OpenApiInfo item) => Validate(item);
public override void Visit(OpenApiContact item) => Validate(item);
public override void Visit(OpenApiComponents item) => Validate(item);

public override void Visit(OpenApiResponse item) => Validate(item);

public override void Visit(OpenApiExternalDocs item) => Validate(item);

public override void Visit(OpenApiLicense item) => Validate(item);
public override void Visit(OpenApiOAuthFlow item) => Validate(item);
public override void Visit(OpenApiTag item) => Validate(item);
public override void Visit(OpenApiServer item) => Validate(item);


public IEnumerable<ValidationError> Errors => _context.Errors;

private void Validate<T>(T item)
{
if (string.IsNullOrEmpty(response.Description))
if (item == null) return; // Required fields should be checked by higher level objects
var rules = _ruleSet.Where(r => r.ElementType == typeof(T));
foreach (var rule in rules)
{
Exceptions.Add(new OpenApiException("Response must have a description"));
rule.Evaluate(_context, item);
}
}
}
Expand Down
83 changes: 63 additions & 20 deletions src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,143 +13,186 @@ namespace Microsoft.OpenApi.Services
public abstract class OpenApiVisitorBase
{
/// <summary>
/// Validates <see cref="OpenApiDocument"/>
/// Visits <see cref="OpenApiDocument"/>
/// </summary>
public virtual void Visit(OpenApiDocument doc)
{
}

/// <summary>
/// Validates <see cref="OpenApiInfo"/>
/// Visits <see cref="OpenApiInfo"/>
/// </summary>
public virtual void Visit(OpenApiInfo info)
{
}

/// <summary>
/// Validates list of <see cref="OpenApiServer"/>
/// Visits <see cref="OpenApiContact"/>
/// </summary>
public virtual void Visit(OpenApiContact contact)
{
}


/// <summary>
/// Visits <see cref="OpenApiLicense"/>
/// </summary>
public virtual void Visit(OpenApiLicense license)
{
}

/// <summary>
/// Visits list of <see cref="OpenApiServer"/>
/// </summary>
public virtual void Visit(IList<OpenApiServer> servers)
{
}

/// <summary>
/// Validates <see cref="OpenApiServer"/>
/// Visits <see cref="OpenApiServer"/>
/// </summary>
public virtual void Visit(OpenApiServer server)
{
}

/// <summary>
/// Validates <see cref="OpenApiPaths"/>
/// Visits <see cref="OpenApiPaths"/>
/// </summary>
public virtual void Visit(OpenApiPaths paths)
{
}

/// <summary>
/// Validates <see cref="OpenApiPathItem"/>
/// Visits <see cref="OpenApiPathItem"/>
/// </summary>
public virtual void Visit(OpenApiPathItem pathItem)
{
}

/// <summary>
/// Validates <see cref="OpenApiServerVariable"/>
/// Visits <see cref="OpenApiServerVariable"/>
/// </summary>
public virtual void Visit(OpenApiServerVariable serverVariable)
{
}

/// <summary>
/// Validates the operations.
/// Visits the operations.
/// </summary>
public virtual void Visit(IDictionary<OperationType, OpenApiOperation> operations)
{
}

/// <summary>
/// Validates <see cref="OpenApiOperation"/>
/// Visits <see cref="OpenApiOperation"/>
/// </summary>
public virtual void Visit(OpenApiOperation operation)
{
}

/// <summary>
/// Validates list of <see cref="OpenApiParameter"/>
/// Visits list of <see cref="OpenApiParameter"/>
/// </summary>
public virtual void Visit(IList<OpenApiParameter> parameters)
{
}

/// <summary>
/// Validates <see cref="OpenApiParameter"/>
/// Visits <see cref="OpenApiParameter"/>
/// </summary>
public virtual void Visit(OpenApiParameter parameter)
{
}

/// <summary>
/// Validates <see cref="OpenApiRequestBody"/>
/// Visits <see cref="OpenApiRequestBody"/>
/// </summary>
public virtual void Visit(OpenApiRequestBody requestBody)
{
}

/// <summary>
/// Validates responses.
/// Visits responses.
/// </summary>
public virtual void Visit(IDictionary<string, OpenApiResponse> responses)
{
}

/// <summary>
/// Validates <see cref="OpenApiResponse"/>
/// Visits <see cref="OpenApiResponse"/>
/// </summary>
public virtual void Visit(OpenApiResponse response)
{
}

/// <summary>
/// Validates media type content.
/// Visits media type content.
/// </summary>
public virtual void Visit(IDictionary<string, OpenApiMediaType> content)
{
}

/// <summary>
/// Validates <see cref="OpenApiMediaType"/>
/// Visits <see cref="OpenApiMediaType"/>
/// </summary>
public virtual void Visit(OpenApiMediaType mediaType)
{
}

/// <summary>
/// Validates the examples.
/// Visits the examples.
/// </summary>
public virtual void Visit(IDictionary<string, OpenApiExample> examples)
{
}

/// <summary>
/// Validates <see cref="OpenApiSchema"/>
/// Visits <see cref="OpenApiComponents"/>
/// </summary>
public virtual void Visit(OpenApiComponents components)
{
}


/// <summary>
/// Visits <see cref="OpenApiComponents"/>
/// </summary>
public virtual void Visit(OpenApiExternalDocs externalDocs)
{
}

/// <summary>
/// Visits <see cref="OpenApiSchema"/>
/// </summary>
public virtual void Visit(OpenApiSchema schema)
{
}

/// <summary>
/// Validates the links.
/// Visits the links.
/// </summary>
public virtual void Visit(IDictionary<string, OpenApiLink> links)
{
}

/// <summary>
/// Validates <see cref="OpenApiLink"/>
/// Visits <see cref="OpenApiLink"/>
/// </summary>
public virtual void Visit(OpenApiLink link)
{
}

/// <summary>
/// Visits <see cref="OpenApiTag"/>
/// </summary>
public virtual void Visit(OpenApiTag tag)
{
}
/// <summary>
/// Visits <see cref="OpenApiOAuthFlow"/>
/// </summary>
public virtual void Visit(OpenApiOAuthFlow openApiOAuthFlow)
{
}
}
}
Loading