Skip to content

Commit

Permalink
Merge pull request #2096 from microsoft/fix/path-item-reference
Browse files Browse the repository at this point in the history
fix: path item reference implementation
  • Loading branch information
MaggieKimani1 authored Jan 28, 2025
2 parents ee4d4c3 + 45e40fa commit 56f291b
Show file tree
Hide file tree
Showing 38 changed files with 213 additions and 259 deletions.
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override void Visit(OpenApiSchema schema)
base.Visit(schema);
}

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
if (pathItem.Operations.TryGetValue(OperationType.Put, out var value) &&
value.OperationId != null)
Expand Down Expand Up @@ -81,13 +81,13 @@ public override void Visit(OpenApiOperation operation)
operationId = ResolveODataCastOperationId(operationId);
operationId = ResolveByRefOperationId(operationId);
// Verb segment resolution should always be last. user.get -> user_Get
operationId = ResolveVerbSegmentInOpertationId(operationId);
operationId = ResolveVerbSegmentInOperationId(operationId);

operation.OperationId = operationId;
base.Visit(operation);
}

private static string ResolveVerbSegmentInOpertationId(string operationId)
private static string ResolveVerbSegmentInOperationId(string operationId)
{
var charPos = operationId.LastIndexOf('.', operationId.Length - 1);
if (operationId.Contains('_', StringComparison.OrdinalIgnoreCase) || charPos < 0)
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Hidi/StatsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void Visit(IDictionary<string, IOpenApiHeader> headers)

public int PathItemCount { get; set; }

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
PathItemCount++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Workbench/StatsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void Visit(IDictionary<string, IOpenApiHeader> headers)

public int PathItemCount { get; set; }

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
PathItemCount++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public interface IOpenApiCallback : IOpenApiSerializable, IOpenApiReadOnlyExtens
/// <summary>
/// A Path Item Object used to define a callback request and expected responses.
/// </summary>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get; }
}
28 changes: 28 additions & 0 deletions src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

using System.Collections.Generic;
using Microsoft.OpenApi.Interfaces;

namespace Microsoft.OpenApi.Models.Interfaces;

/// <summary>
/// Defines the base properties for the path item object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
{
/// <summary>
/// Gets the definition of operations on this path.
/// </summary>
public IDictionary<OperationType, OpenApiOperation> Operations { get; }

/// <summary>
/// An alternative server array to service all operations in this path.
/// </summary>
public IList<OpenApiServer> Servers { get; }

/// <summary>
/// A list of parameters that are applicable for all the operations described under this path.
/// These parameters can be overridden at the operation level, but cannot be removed there.
/// </summary>
public IList<IOpenApiParameter> Parameters { get; }
}
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.OpenApi.Models
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiCallback
{
/// <inheritdoc/>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; set; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get; set; }
= [];


Expand All @@ -40,11 +40,11 @@ public OpenApiCallback(IOpenApiCallback callback)
}

/// <summary>
/// Add a <see cref="OpenApiPathItem"/> into the <see cref="PathItems"/>.
/// Add a <see cref="IOpenApiPathItem"/> into the <see cref="PathItems"/>.
/// </summary>
/// <param name="expression">The runtime expression.</param>
/// <param name="pathItem">The path item.</param>
public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
public void AddPathItem(RuntimeExpression expression, IOpenApiPathItem pathItem)
{
Utils.CheckArgumentNull(expression);
Utils.CheckArgumentNull(pathItem);
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; } = new Dictionary<string, IOpenApiCallback>();

/// <summary>
/// An object to hold reusable <see cref="OpenApiPathItem"/> Object.
/// An object to hold reusable <see cref="IOpenApiPathItem"/> Object.
/// </summary>
public IDictionary<string, OpenApiPathItem>? PathItems { get; set; } = new Dictionary<string, OpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? PathItems { get; set; } = new Dictionary<string, IOpenApiPathItem>();

/// <summary>
/// This object MAY be extended with Specification Extensions.
Expand All @@ -94,7 +94,7 @@ public OpenApiComponents(OpenApiComponents? components)
SecuritySchemes = components?.SecuritySchemes != null ? new Dictionary<string, OpenApiSecurityScheme>(components.SecuritySchemes) : null;
Links = components?.Links != null ? new Dictionary<string, IOpenApiLink>(components.Links) : null;
Callbacks = components?.Callbacks != null ? new Dictionary<string, IOpenApiCallback>(components.Callbacks) : null;
PathItems = components?.PathItems != null ? new Dictionary<string, OpenApiPathItem>(components.PathItems) : null;
PathItems = components?.PathItems != null ? new Dictionary<string, IOpenApiPathItem>(components.PathItems) : null;
Extensions = components?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(components.Extensions) : null;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible, IOpenAp
/// A map of requests initiated other than by an API call, for example by an out of band registration.
/// The key name is a unique string to refer to each webhook, while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the expected responses
/// </summary>
public IDictionary<string, OpenApiPathItem>? Webhooks { get; set; } = new Dictionary<string, OpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? Webhooks { get; set; } = new Dictionary<string, IOpenApiPathItem>();

/// <summary>
/// An element to hold various schemas for the specification.
Expand Down Expand Up @@ -113,7 +113,7 @@ public OpenApiDocument(OpenApiDocument? document)
JsonSchemaDialect = document?.JsonSchemaDialect ?? JsonSchemaDialect;
Servers = document?.Servers != null ? new List<OpenApiServer>(document.Servers) : null;
Paths = document?.Paths != null ? new(document?.Paths) : new OpenApiPaths();
Webhooks = document?.Webhooks != null ? new Dictionary<string, OpenApiPathItem>(document.Webhooks) : null;
Webhooks = document?.Webhooks != null ? new Dictionary<string, IOpenApiPathItem>(document.Webhooks) : null;
Components = document?.Components != null ? new(document?.Components) : null;
SecurityRequirements = document?.SecurityRequirements != null ? new List<OpenApiSecurityRequirement>(document.SecurityRequirements) : null;
Tags = document?.Tags != null ? new List<OpenApiTag>(document.Tags) : null;
Expand Down Expand Up @@ -612,7 +612,7 @@ public bool AddComponent<T>(string id, T componentToRegister)
Components.Callbacks.Add(id, openApiCallback);
break;
case OpenApiPathItem openApiPathItem:
Components.PathItems ??= new Dictionary<string, OpenApiPathItem>();
Components.PathItems ??= new Dictionary<string, IOpenApiPathItem>();
Components.PathItems.Add(id, openApiPathItem);
break;
case OpenApiExample openApiExample:
Expand Down
58 changes: 17 additions & 41 deletions src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,26 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Path Item Object: to describe the operations available on a single path.
/// </summary>
public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable
public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable, IOpenApiPathItem
{
/// <summary>
/// An optional, string summary, intended to apply to all operations in this path.
/// </summary>
public virtual string Summary { get; set; }
/// <inheritdoc/>
public string Summary { get; set; }

/// <summary>
/// An optional, string description, intended to apply to all operations in this path.
/// </summary>
public virtual string Description { get; set; }
/// <inheritdoc/>
public string Description { get; set; }

/// <summary>
/// Gets the definition of operations on this path.
/// </summary>
public virtual IDictionary<OperationType, OpenApiOperation> Operations { get; set; }
/// <inheritdoc/>
public IDictionary<OperationType, OpenApiOperation> Operations { get; set; }
= new Dictionary<OperationType, OpenApiOperation>();

/// <summary>
/// An alternative server array to service all operations in this path.
/// </summary>
public virtual IList<OpenApiServer> Servers { get; set; } = new List<OpenApiServer>();

/// <summary>
/// A list of parameters that are applicable for all the operations described under this path.
/// These parameters can be overridden at the operation level, but cannot be removed there.
/// </summary>
public virtual IList<IOpenApiParameter> Parameters { get; set; } = new List<IOpenApiParameter>();
/// <inheritdoc/>
public IList<OpenApiServer> Servers { get; set; } = [];

/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public virtual IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
/// <inheritdoc/>
public IList<IOpenApiParameter> Parameters { get; set; } = [];

/// <summary>
/// Indicates if object is populated with data or is just a reference to the data
/// </summary>
public bool UnresolvedReference { get; set; }

/// <summary>
/// Reference object.
/// </summary>
public OpenApiReference Reference { get; set; }
/// <inheritdoc/>
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();

/// <summary>
/// Add one operation into this path item.
Expand All @@ -75,30 +52,29 @@ public OpenApiPathItem() { }
/// <summary>
/// Initializes a clone of an <see cref="OpenApiPathItem"/> object
/// </summary>
public OpenApiPathItem(OpenApiPathItem pathItem)
public OpenApiPathItem(IOpenApiPathItem pathItem)
{
Utils.CheckArgumentNull(pathItem);
Summary = pathItem?.Summary ?? Summary;
Description = pathItem?.Description ?? Description;
Operations = pathItem?.Operations != null ? new Dictionary<OperationType, OpenApiOperation>(pathItem.Operations) : null;
Servers = pathItem?.Servers != null ? new List<OpenApiServer>(pathItem.Servers) : null;
Parameters = pathItem?.Parameters != null ? new List<IOpenApiParameter>(pathItem.Parameters) : null;
Extensions = pathItem?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(pathItem.Extensions) : null;
UnresolvedReference = pathItem?.UnresolvedReference ?? UnresolvedReference;
Reference = pathItem?.Reference != null ? new(pathItem?.Reference) : null;
}

/// <summary>
/// Serialize <see cref="OpenApiPathItem"/> to Open Api v3.1
/// </summary>
public virtual void SerializeAsV31(IOpenApiWriter writer)
public void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}

/// <summary>
/// Serialize <see cref="OpenApiPathItem"/> to Open Api v3.0
/// </summary>
public virtual void SerializeAsV3(IOpenApiWriter writer)
public void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
Expand Down
4 changes: 3 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiPaths.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Models.Interfaces;

namespace Microsoft.OpenApi.Models
{
/// <summary>
/// Paths object.
/// </summary>
public class OpenApiPaths : OpenApiExtensibleDictionary<OpenApiPathItem>
public class OpenApiPaths : OpenApiExtensibleDictionary<IOpenApiPathItem>
{
/// <summary>
/// Parameterless constructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal OpenApiCallbackReference(OpenApiCallback target, string referenceId):ba
}

/// <inheritdoc/>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get => Target?.PathItems; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get => Target?.PathItems; }

/// <inheritdoc/>
public IDictionary<string, IOpenApiExtension> Extensions { get => Target?.Extensions; }
Expand Down
Loading

0 comments on commit 56f291b

Please sign in to comment.