/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System.Collections.Generic; using System.Linq; using ApiGenerator.Configuration.Overrides; using ApiGenerator.Domain.Code; using ApiGenerator.Domain.Code.HighLevel.Methods; using ApiGenerator.Domain.Code.HighLevel.Requests; using ApiGenerator.Domain.Code.LowLevel; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace ApiGenerator.Domain.Specification { public class ApiEndpoint { /// The original name as declared in the spec public string Name { get; set; } /// The original namespace as declared in the spec public string Namespace { get; set; } /// The original method name as declared in the spec public string MethodName { get; set; } /// Computed Csharp identifier names public CsharpNames CsharpNames { get; set; } [JsonConverter(typeof(StringEnumConverter))] [JsonProperty("stability")] public Stability Stability { get; set; } [JsonProperty("documentation")] public Documentation OfficialDocumentationLink { get; set; } public UrlInformation Url { get; set; } public Body Body { get; set; } [JsonProperty("methods")] public IReadOnlyCollection HttpMethods { get; set; } public IEndpointOverrides Overrides { get; internal set; } public RequestInterface RequestInterface => new RequestInterface { CsharpNames = CsharpNames, UrlParts = Url.Parts, PartialParameters = Body == null ? Enumerable.Empty().ToList() : Url.Params.Values.Where(p => p.RenderPartial && !p.Skip).ToList(), OfficialDocumentationLink = OfficialDocumentationLink?.Url }; public RequestPartialImplementation RequestPartialImplementation => new RequestPartialImplementation { CsharpNames = CsharpNames, OfficialDocumentationLink = OfficialDocumentationLink?.Url, Stability = Stability, Paths = Url.Paths, Parts = Url.Parts, Params = Url.Params.Values.Where(p => !p.Skip).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 { 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(), HasBody = Body != null, }; public RequestParameterImplementation RequestParameterImplementation => new RequestParameterImplementation { CsharpNames = CsharpNames, OfficialDocumentationLink = OfficialDocumentationLink?.Url, Params = Url.Params.Values.Where(p => !p.Skip).ToList(), HttpMethod = PreferredHttpMethod }; public string PreferredHttpMethod { get { var first = HttpMethods.First(); if (HttpMethods.Count > 1 && first.ToUpperInvariant() == "GET") return HttpMethods.Last(); return first; } } public string HighLevelMethodXmlDocDescription => $"{PreferredHttpMethod} request to the {Name} API, read more about this API online:"; public HighLevelModel HighLevelModel => new HighLevelModel { CsharpNames = CsharpNames, Fluent = new FluentMethod(CsharpNames, Url.Parts, selectorIsOptional: Body == null || !Body.Required || HttpMethods.Contains("GET"), link: OfficialDocumentationLink?.Url, summary: HighLevelMethodXmlDocDescription ), FluentBound = !CsharpNames.DescriptorBindsOverMultipleDocuments ? null : new BoundFluentMethod(CsharpNames, Url.Parts, selectorIsOptional: Body == null || !Body.Required || HttpMethods.Contains("GET"), link: OfficialDocumentationLink?.Url, summary: HighLevelMethodXmlDocDescription ), Initializer = new InitializerMethod(CsharpNames, link: OfficialDocumentationLink?.Url, summary: HighLevelMethodXmlDocDescription ) }; private List _lowLevelClientMethods; public IReadOnlyCollection LowLevelClientMethods { get { if (_lowLevelClientMethods != null && _lowLevelClientMethods.Count > 0) return _lowLevelClientMethods; // enumerate once and cache _lowLevelClientMethods = new List(); if (OfficialDocumentationLink == null) Generator.ApiGenerator.Warnings.Add($"API '{Name}' has no documentation"); var httpMethod = PreferredHttpMethod; foreach (var path in Url.PathsWithDeprecations) { var methodName = CsharpNames.PerPathMethodName(path.Path); var parts = new List(path.Parts); var mapsApiArgumentHints = parts.Select(p => p.Name).ToList(); // TODO This is hack until we stop transforming the new spec format into the old if (Name == "index" && !mapsApiArgumentHints.Contains("id")) httpMethod = "POST"; else if (Name == "index") httpMethod = PreferredHttpMethod; if (Body != null) { parts.Add(new UrlPart { Name = "body", Type = "PostData", Description = Body.Description }); mapsApiArgumentHints.Add("body"); } var args = parts .Select(p => p.Argument) .Concat(new[] { CsharpNames.ParametersName + " requestParameters = null" }) .ToList(); var apiMethod = new LowLevelClientMethod { Arguments = string.Join(", ", args), MapsApiArguments = string.Join(", ", mapsApiArgumentHints), CsharpNames = CsharpNames, PerPathMethodName = methodName, HttpMethod = httpMethod, OfficialDocumentationLink = OfficialDocumentationLink?.Url, Stability = Stability, DeprecatedPath = path.Deprecation, Path = path.Path, Parts = parts, Url = Url, HasBody = Body != null }; _lowLevelClientMethods.Add(apiMethod); } return _lowLevelClientMethods; } } } }