Skip to content

Commit

Permalink
Merge pull request #1795 from microsoft/vnext
Browse files Browse the repository at this point in the history
Release libs.
  • Loading branch information
irvinesunday authored Aug 23, 2024
2 parents 5842eff + 9a5a415 commit ea7dcd0
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ jobs:
id: getversion
- name: Push to GitHub Packages - Nightly
if: ${{ github.ref == 'refs/heads/vnext' }}
uses: docker/build-push-action@v6.5.0
uses: docker/build-push-action@v6.7.0
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
- name: Push to GitHub Packages - Release
if: ${{ github.ref == 'refs/heads/master' }}
uses: docker/build-push-action@v6.5.0
uses: docker/build-push-action@v6.7.0
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.getversion.outputs.version }}
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Nullable>enable</Nullable>
<ToolCommandName>hidi</ToolCommandName>
<PackageOutputPath>./../../artifacts</PackageOutputPath>
<Version>1.4.7</Version>
<Version>1.4.8</Version>
<Description>OpenAPI.NET CLI tool for slicing OpenAPI documents</Description>
<SignAssembly>true</SignAssembly>
<!-- https://github.com/dotnet/sourcelink/blob/main/docs/README.md#embeduntrackedsources -->
Expand All @@ -34,8 +34,8 @@
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Microsoft.OData.Edm" Version="7.21.3" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.6.8" />
<PackageReference Include="Microsoft.OData.Edm" Version="8.0.1" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="2.0.0-preview.2" />
<PackageReference Include="Microsoft.OpenApi.ApiManifest" Version="0.5.0-preview" />
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.Compatibility" Version="8.0.7" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="8.0.8" />
</ItemGroup>
<ItemGroup>
<Resource Include="Themes\Metro\HowToApplyTheme.txt" />
Expand Down
57 changes: 57 additions & 0 deletions src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Properties;

namespace Microsoft.OpenApi.Extensions;

/// <summary>
/// Extension methods for <see cref="OpenApiServer"/> serialization.
/// </summary>
public static class OpenApiServerExtensions
{
/// <summary>
/// Replaces URL variables in a server's URL
/// </summary>
/// <param name="server">The OpenAPI server object</param>
/// <param name="values">The server variable values that will be used to replace the default values.</param>
/// <returns>A URL with the provided variables substituted.</returns>
/// <exception cref="ArgumentException">
/// Thrown when:
/// 1. A substitution has no valid value in both the supplied dictionary and the default
/// 2. A substitution's value is not available in the enum provided
/// </exception>
public static string ReplaceServerUrlVariables(this OpenApiServer server, IDictionary<string, string> values = null)
{
var parsedUrl = server.Url;
foreach (var variable in server.Variables)
{
// Try to get the value from the provided values
if (values is not { } v || !v.TryGetValue(variable.Key, out var value) || string.IsNullOrEmpty(value))
{
// Fall back to the default value
value = variable.Value.Default;
}

// Validate value
if (string.IsNullOrEmpty(value))
{
// According to the spec, the variable's default value is required.
// This code path should be hit when a value isn't provided & a default value isn't available
throw new ArgumentException(
string.Format(SRResource.ParseServerUrlDefaultValueNotAvailable, variable.Key), nameof(server));
}

// If an enum is provided, the array should not be empty & the value should exist in the enum
if (variable.Value.Enum is {} e && (e.Count == 0 || !e.Contains(value)))
{
throw new ArgumentException(
string.Format(SRResource.ParseServerUrlValueNotValid, value, variable.Key), nameof(values));
}

parsedUrl = parsedUrl.Replace($"{{{variable.Key}}}", value);
}

return parsedUrl;
}
}
10 changes: 2 additions & 8 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Security.Cryptography;
using System.Text;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Services;
using Microsoft.OpenApi.Writers;
Expand Down Expand Up @@ -283,14 +284,7 @@ public void SerializeAsV2(IOpenApiWriter writer)

private static string ParseServerUrl(OpenApiServer server)
{
var parsedUrl = server.Url;

var variables = server.Variables;
foreach (var variable in variables.Where(static x => !string.IsNullOrEmpty(x.Value.Default)))
{
parsedUrl = parsedUrl.Replace($"{{{variable.Key}}}", variable.Value.Default);
}
return parsedUrl;
return server.ReplaceServerUrlVariables(new Dictionary<string, string>(0));
}

private static void WriteHostInfoV2(IOpenApiWriter writer, IList<OpenApiServer> servers)
Expand Down
5 changes: 4 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public class OpenApiServerVariable : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// An enumeration of string values to be used if the substitution options are from a limited set.
/// </summary>
public List<string> Enum { get; set; } = new();
/// <remarks>
/// If the server variable in the OpenAPI document has no <code>enum</code> member, this property will be null.
/// </remarks>
public List<string> Enum { get; set; }

/// <summary>
/// This object MAY be extended with Specification Extensions.
Expand Down
19 changes: 18 additions & 1 deletion src/Microsoft.OpenApi/Properties/SRResource.Designer.cs

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

6 changes: 6 additions & 0 deletions src/Microsoft.OpenApi/Properties/SRResource.resx
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,10 @@
<data name="WorkspaceRequredForExternalReferenceResolution" xml:space="preserve">
<value>OpenAPI document must be added to an OpenApiWorkspace to be able to resolve external references.</value>
</data>
<data name="ParseServerUrlDefaultValueNotAvailable" xml:space="preserve">
<value>Invalid server variable '{0}'. A value was not provided and no default value was provided.</value>
</data>
<data name="ParseServerUrlValueNotValid" xml:space="preserve">
<value>Value '{0}' is not a valid value for variable '{1}'. If an enum is provided, it should not be empty and the value provided should exist in the enum</value>
</data>
</root>
23 changes: 23 additions & 0 deletions src/Microsoft.OpenApi/Validations/Rules/OpenApiServerRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,32 @@ public static class OpenApiServerRules
context.CreateError(nameof(ServerRequiredFields),
String.Format(SRResource.Validation_FieldIsRequired, "url", "server"));
}

context.Exit();
context.Enter("variables");
foreach (var variable in server.Variables)
{
context.Enter(variable.Key);
ValidateServerVariableRequiredFields(context, variable.Key, variable.Value);
context.Exit();
}
context.Exit();
});

// add more rules

/// <summary>
/// Validate required fields in server variable
/// </summary>
private static void ValidateServerVariableRequiredFields(IValidationContext context, string key, OpenApiServerVariable item)
{
context.Enter("default");
if (string.IsNullOrEmpty(item.Default))
{
context.CreateError("ServerVariableMustHaveDefaultValue",
String.Format(SRResource.Validation_FieldIsRequired, "default", key));
}
context.Exit();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" PrivateAssets="all" />
<PackageReference Include="coverlet.collector" Version="6.0.2" PrivateAssets="all" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="coverlet.msbuild" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SharpYaml" Version="2.1.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1367,5 +1367,70 @@ public void ParseDocumetWithWrongReferenceTypeShouldReturnADiagnosticError()
diagnostic.Errors.Should().BeEquivalentTo(new List<OpenApiError> {
new( new OpenApiException("Invalid Reference Type 'Schema'.")) });
}

[Fact]
public void ParseBasicDocumentWithServerVariableShouldSucceed()
{
var openApiDoc = new OpenApiStringReader().Read("""
openapi : 3.0.0
info:
title: The API
version: 0.9.1
servers:
- url: http://www.example.org/api/{version}
description: The http endpoint
variables:
version:
default: v2
enum: [v1, v2]
paths: {}
""", out var diagnostic);

diagnostic.Should().BeEquivalentTo(
new OpenApiDiagnostic { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 });

openApiDoc.Should().BeEquivalentTo(
new OpenApiDocument
{
Info = new()
{
Title = "The API",
Version = "0.9.1",
},
Servers =
{
new OpenApiServer
{
Url = "http://www.example.org/api/{version}",
Description = "The http endpoint",
Variables = new Dictionary<string, OpenApiServerVariable>
{
{"version", new OpenApiServerVariable {Default = "v2", Enum = ["v1", "v2"]}}
}
}
},
Paths = new()
});
}

[Fact]
public void ParseBasicDocumentWithServerVariableAndNoDefaultShouldFail()
{
var openApiDoc = new OpenApiStringReader().Read("""
openapi : 3.0.0
info:
title: The API
version: 0.9.1
servers:
- url: http://www.example.org/api/{version}
description: The http endpoint
variables:
version:
enum: [v1, v2]
paths: {}
""", out var diagnostic);

diagnostic.Errors.Should().NotBeEmpty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="coverlet.msbuild" Version="6.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" PrivateAssets="all" />
Expand Down
Loading

0 comments on commit ea7dcd0

Please sign in to comment.