Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3af819a
Bump Microsoft.NET.Test.Sdk from 17.3.1 to 17.3.2
dependabot[bot] Sep 26, 2022
cba0d4f
Merge pull request #1024 from microsoft/dependabot/nuget/Microsoft.NE…
baywet Sep 26, 2022
da040f4
Update access modifier
MaggieKimani1 Oct 3, 2022
f9fc28f
Update public Api
MaggieKimani1 Oct 3, 2022
485c45c
Add XML comments
MaggieKimani1 Oct 3, 2022
d1580a3
Update src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
baywet Oct 3, 2022
224a67d
Bump actions/setup-dotnet from 2 to 3
dependabot[bot] Oct 3, 2022
03c8aa5
Merge pull request #1029 from microsoft/dependabot/github_actions/act…
baywet Oct 3, 2022
b1fca56
Merge pull request #1027 from microsoft/mk/make-openapi-reference-res…
MaggieKimani1 Oct 4, 2022
a76d1c9
Bump version for preview release
MaggieKimani1 Oct 6, 2022
f0f0efe
Merge pull request #1032 from microsoft/mk/bump-lib-version
MaggieKimani1 Oct 6, 2022
42ffc77
Setting it to 1.4.4-preview1 so that it's consistent with the Object …
MaggieKimani1 Oct 6, 2022
80785a2
- bumps hidi version and updates reference to conversion lib
baywet Oct 6, 2022
d3bf322
- moves hidi test project to test directory
baywet Oct 6, 2022
cc98657
Merge pull request #1034 from microsoft/mk/bump-readers-version
baywet Oct 6, 2022
b1b68f5
Insert null check validation when response header does not contain an…
MaggieKimani1 Oct 6, 2022
bdced92
- bumps odata to latest
baywet Oct 6, 2022
9c7f3c4
Merge pull request #1036 from microsoft/mk/resolve-null-reference-exc…
MaggieKimani1 Oct 6, 2022
ed740c8
- fixes references to projects in tests projects
baywet Oct 6, 2022
680ee90
Merge pull request #1035 from microsoft/feature/hidi-release
baywet Oct 6, 2022
76321be
Fix $ref serialization errors for requestBodies and responses (#1033)
millicentachieng Oct 6, 2022
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
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
GITHUB_RUN_NUMBER: ${{ github.run_number }}
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v3

- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x

Expand Down
2 changes: 1 addition & 1 deletion Microsoft.OpenApi.sln
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.SmokeTest
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.Hidi", "src\Microsoft.OpenApi.Hidi\Microsoft.OpenApi.Hidi.csproj", "{254841B5-7DAC-4D1D-A9C5-44FE5CE467BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.Hidi.Tests", "Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj", "{D8F799DD-04AC-4A13-B344-45A5B944450A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.Hidi.Tests", "test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj", "{D8F799DD-04AC-4A13-B344-45A5B944450A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageId>Microsoft.OpenApi.Hidi</PackageId>
<ToolCommandName>hidi</ToolCommandName>
<PackageOutputPath>./../../artifacts</PackageOutputPath>
<Version>1.1.0-preview1</Version>
<Version>1.1.0-preview2</Version>
<Description>OpenAPI.NET CLI tool for slicing OpenAPI documents</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down Expand Up @@ -43,7 +43,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Microsoft.OData.Edm" Version="7.12.3" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.1.0" />
<PackageReference Include="Microsoft.OpenApi.OData" Version="1.2.0-preview4" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Company>Microsoft</Company>
<Title>Microsoft.OpenApi.Readers</Title>
<PackageId>Microsoft.OpenApi.Readers</PackageId>
<Version>1.4.1</Version>
<Version>1.4.4-preview1</Version>
<Description>OpenAPI.NET Readers for JSON and YAML documents</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down
18 changes: 13 additions & 5 deletions src/Microsoft.OpenApi.Readers/V2/OpenApiHeaderDeserializer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
Expand Down Expand Up @@ -139,8 +139,12 @@ internal static partial class OpenApiV2Deserializer
{
OpenApiConstants.Default,
new AnyFieldMapParameter<OpenApiHeader>(
p => p.Schema.Default,
(p, v) => p.Schema.Default = v,
p => p.Schema?.Default,
(p, v) =>
{
if(p.Schema == null) return;
p.Schema.Default = v;
},
p => p.Schema)
}
};
Expand All @@ -151,8 +155,12 @@ internal static partial class OpenApiV2Deserializer
{
OpenApiConstants.Enum,
new AnyListFieldMapParameter<OpenApiHeader>(
p => p.Schema.Enum,
(p, v) => p.Schema.Enum = v,
p => p.Schema?.Enum,
(p, v) =>
{
if(p.Schema == null) return;
p.Schema.Enum = v;
},
p => p.Schema)
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Company>Microsoft</Company>
<Title>Microsoft.OpenApi</Title>
<PackageId>Microsoft.OpenApi</PackageId>
<Version>1.4.3</Version>
<Version>1.4.4-preview1</Version>
<Description>.NET models with JSON and YAML writers for OpenAPI specification</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>OpenAPI .NET</PackageTags>
Expand Down
15 changes: 13 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void SerializeAsV2(IOpenApiWriter writer)
// paths
writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => p.SerializeAsV2(w));

// If references have been inlined we don't need the to render the components section
// If references have been inlined we don't need to render the components section
// however if they have cycles, then we will need a component rendered
if (writer.GetSettings().InlineLocalReferences)
{
Expand Down Expand Up @@ -208,9 +208,20 @@ public void SerializeAsV2(IOpenApiWriter writer)
});
}
// parameters
var parameters = Components?.Parameters != null
? new Dictionary<string, OpenApiParameter>(Components.Parameters)
: new Dictionary<string, OpenApiParameter>();

if (Components?.RequestBodies != null)
{
foreach (var requestBody in Components.RequestBodies.Where(b => !parameters.ContainsKey(b.Key)))
{
parameters.Add(requestBody.Key, requestBody.Value.ConvertToBodyParameter());
}
}
writer.WriteOptionalMap(
OpenApiConstants.Parameters,
Components?.Parameters,
parameters,
(w, key, component) =>
{
if (component.Reference != null &&
Expand Down
88 changes: 38 additions & 50 deletions src/Microsoft.OpenApi/Models/OpenApiOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public void SerializeAsV2(IOpenApiWriter writer)
// operationId
writer.WriteProperty(OpenApiConstants.OperationId, OperationId);

IList<OpenApiParameter> parameters;
List<OpenApiParameter> parameters;
if (Parameters == null)
{
parameters = new List<OpenApiParameter>();
Expand All @@ -237,70 +237,58 @@ public void SerializeAsV2(IOpenApiWriter writer)
if (RequestBody != null)
{
// consumes
writer.WritePropertyName(OpenApiConstants.Consumes);
writer.WriteStartArray();
var consumes = RequestBody.Content.Keys.Distinct().ToList();
foreach (var mediaType in consumes)
if (consumes.Any())
{
writer.WriteValue(mediaType);
}

writer.WriteEndArray();

// This is form data. We need to split the request body into multiple parameters.
if (consumes.Contains("application/x-www-form-urlencoded") ||
consumes.Contains("multipart/form-data"))
{
foreach (var property in RequestBody.Content.First().Value.Schema.Properties)
// This is form data. We need to split the request body into multiple parameters.
if (consumes.Contains("application/x-www-form-urlencoded") ||
consumes.Contains("multipart/form-data"))
{
var paramSchema = property.Value;
if ("string".Equals(paramSchema.Type, StringComparison.OrdinalIgnoreCase)
&& ("binary".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)
|| "base64".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)))
{
paramSchema.Type = "file";
paramSchema.Format = null;
}
parameters.Add(
new OpenApiFormDataParameter
{
Description = property.Value.Description,
Name = property.Key,
Schema = property.Value,
Required = RequestBody.Content.First().Value.Schema.Required.Contains(property.Key)

});
parameters.AddRange(RequestBody.ConvertToFormDataParameters());
}
else
{
parameters.Add(RequestBody.ConvertToBodyParameter());
}
}
else
else if (RequestBody.Reference != null)
{
var content = RequestBody.Content.Values.FirstOrDefault();
parameters.Add(
new OpenApiParameter
{
UnresolvedReference = true,
Reference = RequestBody.Reference
});

var bodyParameter = new OpenApiBodyParameter
if (RequestBody.Reference.HostDocument != null)
{
Description = RequestBody.Description,
// V2 spec actually allows the body to have custom name.
// To allow round-tripping we use an extension to hold the name
Name = "body",
Schema = content?.Schema ?? new OpenApiSchema(),
Required = RequestBody.Required,
Extensions = RequestBody.Extensions.ToDictionary(k => k.Key, v => v.Value) // Clone extensions so we can remove the x-bodyName extensions from the output V2 model.
};

if (bodyParameter.Extensions.ContainsKey(OpenApiConstants.BodyName))
var effectiveRequestBody = RequestBody.GetEffective(RequestBody.Reference.HostDocument);
if (effectiveRequestBody != null)
consumes = effectiveRequestBody.Content.Keys.Distinct().ToList();
}
}

if (consumes.Any())
{
writer.WritePropertyName(OpenApiConstants.Consumes);
writer.WriteStartArray();
foreach (var mediaType in consumes)
{
bodyParameter.Name = (RequestBody.Extensions[OpenApiConstants.BodyName] as OpenApiString)?.Value ?? "body";
bodyParameter.Extensions.Remove(OpenApiConstants.BodyName);
writer.WriteValue(mediaType);
}

parameters.Add(bodyParameter);
writer.WriteEndArray();
}
}

if (Responses != null)
{
var produces = Responses.Where(r => r.Value.Content != null)
.SelectMany(r => r.Value.Content?.Keys)
var produces = Responses
.Where(static r => r.Value.Content != null)
.SelectMany(static r => r.Value.Content?.Keys)
.Concat(
Responses
.Where(static r => r.Value.Reference != null && r.Value.Reference.HostDocument != null)
.SelectMany(static r => r.Value.GetEffective(r.Value.Reference.HostDocument)?.Content?.Keys))
.Distinct()
.ToList();

Expand Down
34 changes: 10 additions & 24 deletions src/Microsoft.OpenApi/Models/OpenApiReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,31 +214,17 @@ private string GetExternalReferenceV2()

private string GetReferenceTypeNameAsV2(ReferenceType type)
{
switch (type)
return type switch
{
case ReferenceType.Schema:
return OpenApiConstants.Definitions;

case ReferenceType.Parameter:
return OpenApiConstants.Parameters;

case ReferenceType.Response:
return OpenApiConstants.Responses;

case ReferenceType.Header:
return OpenApiConstants.Headers;

case ReferenceType.Tag:
return OpenApiConstants.Tags;

case ReferenceType.SecurityScheme:
return OpenApiConstants.SecurityDefinitions;

default:
// If the reference type is not supported in V2, simply return null
// to indicate that the reference is not pointing to any object.
return null;
}
ReferenceType.Schema => OpenApiConstants.Definitions,
ReferenceType.Parameter or ReferenceType.RequestBody => OpenApiConstants.Parameters,
ReferenceType.Response => OpenApiConstants.Responses,
ReferenceType.Header => OpenApiConstants.Headers,
ReferenceType.Tag => OpenApiConstants.Tags,
ReferenceType.SecurityScheme => OpenApiConstants.SecurityDefinitions,
_ => null,// If the reference type is not supported in V2, simply return null
// to indicate that the reference is not pointing to any object.
};
}
}
}
47 changes: 47 additions & 0 deletions src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;
Expand Down Expand Up @@ -144,5 +146,50 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
{
// RequestBody object does not exist in V2.
}

internal OpenApiBodyParameter ConvertToBodyParameter()
{
var bodyParameter = new OpenApiBodyParameter
{
Description = Description,
// V2 spec actually allows the body to have custom name.
// To allow round-tripping we use an extension to hold the name
Name = "body",
Schema = Content.Values.FirstOrDefault()?.Schema ?? new OpenApiSchema(),
Required = Required,
Extensions = Extensions.ToDictionary(static k => k.Key, static v => v.Value) // Clone extensions so we can remove the x-bodyName extensions from the output V2 model.
};
if (bodyParameter.Extensions.ContainsKey(OpenApiConstants.BodyName))
{
bodyParameter.Name = (Extensions[OpenApiConstants.BodyName] as OpenApiString)?.Value ?? "body";
bodyParameter.Extensions.Remove(OpenApiConstants.BodyName);
}
return bodyParameter;
}

internal IEnumerable<OpenApiFormDataParameter> ConvertToFormDataParameters()
{
if (Content == null || !Content.Any())
yield break;

foreach (var property in Content.First().Value.Schema.Properties)
{
var paramSchema = property.Value;
if ("string".Equals(paramSchema.Type, StringComparison.OrdinalIgnoreCase)
&& ("binary".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)
|| "base64".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase)))
{
paramSchema.Type = "file";
paramSchema.Format = null;
}
yield return new OpenApiFormDataParameter
{
Description = property.Value.Description,
Name = property.Key,
Schema = property.Value,
Required = Content.First().Value.Schema.Required.Contains(property.Key)
};
}
}
}
}
Loading