Skip to content

Commit

Permalink
Re-generate nodes namespace (opensearch-project#352)
Browse files Browse the repository at this point in the history
* Use specification naming for enums

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Handle deprecated paths

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Re-generate `nodes.hot_threads`

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Handle overloaded param

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Better sorting

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Re-generate `nodes.info`

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Re-generate `nodes.reload_secure_settings`

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Sort URL parts

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Re-generate `nodes.stats`

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Correctly handle URL part enum options

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Make ApiUrls readonly

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Re-generate `nodes.usage`

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

---------

Signed-off-by: Thomas Farr <tsfarr@amazon.com>
  • Loading branch information
Xtansia committed Dec 3, 2023
1 parent a977319 commit 5848604
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 133 deletions.
2 changes: 1 addition & 1 deletion src/ApiGenerator/Configuration/CodeConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public static class CodeConfiguration
{
private static readonly Glob[] OperationsToInclude =
{
// e.g. new Glob("nodes.*"),
new("dangling_indices.*"),
new("ingest.*"),
new("nodes.*"),
new("snapshot.*"),
new("tasks.*")
};
Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion src/ApiGenerator/Domain/ApiQueryParametersPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ IEndpointOverrides overrides
value.QueryStringKey = queryStringKey;

if (!renameLookup.TryGetValue(queryStringKey, out var preferredName)) preferredName = queryStringKey;
value.ClsName = CreateCSharpName(preferredName, endpointName);

value.ClsName ??= CreateCSharpName(preferredName, endpointName);

if (skipList.Contains(queryStringKey)) value.Skip = true;

Expand Down
64 changes: 26 additions & 38 deletions src/ApiGenerator/Domain/RestApiSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class EnumDescription

public class RestApiSpec
{
public IDictionary<string, ApiEndpoint> Endpoints { get; set; }
public ImmutableSortedDictionary<string, ApiEndpoint> Endpoints { get; set; }

public ImmutableSortedDictionary<string, ReadOnlyCollection<ApiEndpoint>> EndpointsPerNamespaceLowLevel =>
Endpoints.Values.GroupBy(e=>e.CsharpNames.Namespace)
Expand All @@ -63,44 +63,32 @@ public IEnumerable<EnumDescription> EnumsInTheSpec
{
if (_enumDescriptions != null) return _enumDescriptions;

string CreateName(string name, string methodName, string @namespace)
{
if (
name.ToLowerInvariant().Contains("metric")
||(name.ToLowerInvariant() == "status")
||(name.ToLowerInvariant() == "format")
)
{
if (methodName.StartsWith(@namespace))
return methodName + name;
else
return @namespace + methodName + name;
}
var urlParameterEnums = Endpoints
.Values
.SelectMany(e => e.Url.Params.Values)
.Where(p => p.Options != null && p.Options.Any())
.Select(p => new EnumDescription
{
Name = p.ClsName,
Options = p.Options
})
.ToList();

return name;
}

var urlParameterEnums = (
from e in Endpoints.Values
from para in e.Url.Params.Values
where para.Options != null && para.Options.Any()
let name = CreateName(para.ClsName, e.CsharpNames.MethodName, e.CsharpNames.Namespace)
where name != "Time"
select new EnumDescription
{
Name = name,
Options = para.Options
}).ToList();

var urlPartEnums = (
from e in Endpoints.Values
from part in e.Url.Parts
where part.Options != null && part.Options.Any()
select new EnumDescription
{
Name = CreateName(part.Name.ToPascalCase(), e.CsharpNames.MethodName, e.CsharpNames.Namespace),
Options = part.Options
}).ToList();
var urlPartEnums = Endpoints
.Values
.SelectMany(e => e.Url.Parts, (e, part) => new { e, part })
.Where(p => p.part.Options != null && p.part.Options.Any())
.Select(p =>
{
var ns = p.e.CsharpNames.Namespace;
var m = p.e.CsharpNames.MethodName;
return new EnumDescription
{
Name = (!m.StartsWith(ns) ? ns : string.Empty) + m + p.part.Name.ToPascalCase(),
Options = p.part.Options
};
}).
ToList();

_enumDescriptions = urlPartEnums
.Concat(urlParameterEnums)
Expand Down
26 changes: 14 additions & 12 deletions src/ApiGenerator/Domain/Specification/ApiEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,44 +62,46 @@ public class ApiEndpoint

public IEndpointOverrides Overrides { get; internal set; }

public RequestInterface RequestInterface => new RequestInterface
{
private IEnumerable<QueryParameters> ParamsToGenerate => Url.Params.Values.Where(p => !p.Skip).OrderBy(p => p.ClsName);

public RequestInterface RequestInterface => new()
{
CsharpNames = CsharpNames,
UrlParts = Url.Parts,
PartialParameters =
Body == null ? Enumerable.Empty<QueryParameters>().ToList() : Url.Params.Values.Where(p => p.RenderPartial && !p.Skip).ToList(),
Body == null ? Enumerable.Empty<QueryParameters>().ToList() : ParamsToGenerate.Where(p => p.RenderPartial).ToList(),
OfficialDocumentationLink = OfficialDocumentationLink?.Url
};

public RequestPartialImplementation RequestPartialImplementation => new RequestPartialImplementation
{
public RequestPartialImplementation RequestPartialImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Stability = Stability,
Paths = Url.Paths,
Parts = Url.Parts,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
Constructors = Constructor.RequestConstructors(CsharpNames, Url, inheritsFromPlainRequestBase: true).ToList(),
GenericConstructors = Constructor.RequestConstructors(CsharpNames, Url, inheritsFromPlainRequestBase: false).ToList(),
HasBody = Body != null,
};

public DescriptorPartialImplementation DescriptorPartialImplementation => new DescriptorPartialImplementation
{
public DescriptorPartialImplementation DescriptorPartialImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Constructors = Constructor.DescriptorConstructors(CsharpNames, Url).ToList(),
Paths = Url.Paths,
Parts = Url.Parts,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
HasBody = Body != null,
};

public RequestParameterImplementation RequestParameterImplementation => new RequestParameterImplementation
{
public RequestParameterImplementation RequestParameterImplementation => new()
{
CsharpNames = CsharpNames,
OfficialDocumentationLink = OfficialDocumentationLink?.Url,
Params = Url.Params.Values.Where(p => !p.Skip).ToList(),
Params = ParamsToGenerate.ToList(),
HttpMethod = PreferredHttpMethod
};

Expand Down
10 changes: 7 additions & 3 deletions src/ApiGenerator/Domain/Specification/UrlInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace ApiGenerator.Domain.Specification
Expand All @@ -42,7 +43,7 @@ public class UrlInformation

public IDictionary<string, UrlPart> OriginalParts { get; set; }

private IReadOnlyCollection<DeprecatedPath> DeprecatedPaths { get; set; }
public IList<DeprecatedPath> DeprecatedPaths { get; set; } = new List<DeprecatedPath>();

private List<UrlPath> _paths;
public IReadOnlyCollection<UrlPath> Paths
Expand Down Expand Up @@ -113,7 +114,11 @@ public IReadOnlyCollection<UrlPath> PathsWithDeprecations
}


public IReadOnlyCollection<UrlPart> Parts => Paths.SelectMany(p => p.Parts).DistinctBy(p => p.Name).ToList();
public IReadOnlyCollection<UrlPart> Parts => Paths
.SelectMany(p => p.Parts)
.DistinctBy(p => p.Name)
.OrderBy(p => p.Name)
.ToList();

public bool IsPartless => !Parts.Any();

Expand All @@ -135,6 +140,5 @@ public bool TryGetDocumentApiPath(out UrlPath path)
path = new UrlPath(mostVerbosePath.Path, OriginalParts, mostVerbosePath.Parts);
return true;
}

}
}
65 changes: 53 additions & 12 deletions src/ApiGenerator/Generator/ApiEndpointFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
using ApiGenerator.Domain.Code;
using ApiGenerator.Domain.Specification;
using NJsonSchema;
using NJsonSchema.References;
using NSwag;

namespace ApiGenerator.Generator
Expand All @@ -55,16 +56,37 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt

foreach (var (httpPath, path, _, operation) in variants.DistinctBy(v => v.HttpPath))
{
urlInfo.OriginalPaths.Add(httpPath);
if (!operation.IsDeprecated)
urlInfo.OriginalPaths.Add(httpPath);
else
{
urlInfo.DeprecatedPaths.Add(new DeprecatedPath
{
Path = httpPath,
Version = operation.GetExtension("x-version-deprecated") as string,
Description = operation.GetExtension("x-deprecation-message") as string
});
}

var pathParams = path.Parameters
.Concat(operation.Parameters)
.Where(p => p.Kind == OpenApiParameterKind.Path)
.ToList();

foreach (var overloadedParam in pathParams.Where(p => p.Schema.XOverloadedParam() != null))
{
urlInfo.OriginalPaths.Add(httpPath.Replace(
$"{{{overloadedParam.Name}}}",
$"{{{overloadedParam.Schema.XOverloadedParam()}}}"
));
}

var paramNames = pathParams.Select(p => p.Name);
if (requiredPathParams != null)
if (requiredPathParams != null)
requiredPathParams.IntersectWith(paramNames);
else
requiredPathParams = new HashSet<string>(paramNames);

allPathParams.AddRange(pathParams);
}

Expand All @@ -84,15 +106,7 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt
urlInfo.Params = variants.SelectMany(v => v.Path.Parameters.Concat(v.Operation.Parameters))
.Where(p => p.Kind == OpenApiParameterKind.Query)
.DistinctBy(p => p.Name)
.ToImmutableSortedDictionary(p => p.Name,
p => new QueryParameters
{
Type = GetOpenSearchType(p.Schema),
Description = p.Description,
Options = GetEnumOptions(p.Schema),
Deprecated = GetDeprecation(p.Schema),
VersionAdded = p.Schema.XVersionAdded()
});
.ToImmutableSortedDictionary(p => p.Name, BuildQueryParam);

var endpoint = new ApiEndpoint
{
Expand Down Expand Up @@ -138,6 +152,25 @@ private static void PatchRequestParameters(ApiEndpoint endpoint) =>
endpoint.Url.Params = ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides)
?? throw new ArgumentNullException("ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides)");

private static QueryParameters BuildQueryParam(OpenApiParameter p)
{
var param = new QueryParameters
{
Type = GetOpenSearchType(p.Schema),
Description = p.Description,
Options = GetEnumOptions(p.Schema),
Deprecated = GetDeprecation(p.Schema),
VersionAdded = p.Schema.XVersionAdded(),
};

if (param.Type == "enum" && p.Schema.HasReference)
{
param.ClsName = ((IJsonReference)p.Schema).ReferencePath.Split('/').Last();
}

return param;
}

private static string GetOpenSearchType(JsonSchema schema)
{
schema = schema.ActualSchema;
Expand All @@ -155,7 +188,9 @@ private static string GetOpenSearchType(JsonSchema schema)
}

private static IEnumerable<string> GetEnumOptions(JsonSchema schema) =>
schema.ActualSchema.Enumeration?.Select(e => e.ToString()) ?? Enumerable.Empty<string>();
schema.ActualSchema.XEnumOptions()
?? schema.ActualSchema.Enumeration?.Select(e => e.ToString())
?? Enumerable.Empty<string>();

private static QueryParameterDeprecation GetDeprecation(IJsonExtensionObject schema) =>
(schema.XDeprecationMessage(), schema.XVersionDeprecated()) switch
Expand Down Expand Up @@ -186,6 +221,12 @@ private static string XVersionAdded(this IJsonExtensionObject schema) =>
private static string XDataType(this IJsonExtensionObject schema) =>
schema.GetExtension("x-data-type") as string;

private static string XOverloadedParam(this IJsonExtensionObject schema) =>
schema.GetExtension("x-overloaded-param") as string;

private static IEnumerable<string> XEnumOptions(this IJsonExtensionObject schema) =>
schema.GetExtension("x-enum-options") is object[] opts ? opts.Cast<string>() : null;

private static object GetExtension(this IJsonExtensionObject schema, string key) =>
schema.ExtensionData?.TryGetValue(key, out var value) ?? false ? value : null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/ApiGenerator/Generator/ApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
using ApiGenerator.Configuration;
using ApiGenerator.Domain;
using ApiGenerator.Generator.Razor;
using NJsonSchema;
using NSwag;
using ShellProgressBar;

Expand Down Expand Up @@ -92,6 +93,7 @@ await DoGenerate(
public static async Task<RestApiSpec> CreateRestApiSpecModel(CancellationToken token = default)
{
var document = await OpenApiYamlDocument.FromFileAsync(GeneratorLocations.OpenApiSpecFile, token);
JsonSchemaReferenceUtilities.UpdateSchemaReferencePaths(document);

var endpoints = document.Paths
.Select(kv => new { HttpPath = kv.Key, PathItem = kv.Value })
Expand Down
Loading

0 comments on commit 5848604

Please sign in to comment.