diff --git a/CHANGELOG.md b/CHANGELOG.md index de5ee104c3..c4b445d802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added support for point-in-time search and associated APIs ([#405](https://github.com/opensearch-project/opensearch-net/pull/405)) - Added support for the component template APIs ([#411](https://github.com/opensearch-project/opensearch-net/pull/411)) - Added support for the composable index template APIs ([#437](https://github.com/opensearch-project/opensearch-net/pull/437)) +- Added high-level DSL for raw HTTP methods ([#447](https://github.com/opensearch-project/opensearch-net/pull/447)) ### Removed - Removed the `Features` API which is not supported by OpenSearch from the low-level client ([#331](https://github.com/opensearch-project/opensearch-net/pull/331)) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index a202f52ffd..1af340d722 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -309,4 +309,8 @@ Note the main difference here is that we are instantiating an `OpenSearchLowLeve ## Advanced Features -- [Making Raw JSON Requests](guides/json.md) \ No newline at end of file +- [Bulk Requests](guides/bulk.md) +- [Document Lifecycle](guides/document-lifecycle.md) +- [Index Template](guides/index-template.md) +- [Making Raw JSON REST Requests](guides/json.md) +- [Search](guides/search.md) diff --git a/guides/document_lifecycle.md b/guides/document-lifecycle.md similarity index 99% rename from guides/document_lifecycle.md rename to guides/document-lifecycle.md index a8031b136f..e0746f7e7c 100644 --- a/guides/document_lifecycle.md +++ b/guides/document-lifecycle.md @@ -1,5 +1,5 @@ # Document Lifecycle -This guide covers OpenSearch Ruby Client API actions for Document Lifecycle. You'll learn how to create, read, update, and delete documents in your OpenSearch cluster. Whether you're new to OpenSearch or an experienced user, this guide provides the information you need to manage your document lifecycle effectively. +This guide covers OpenSearch .NET Client API actions for Document Lifecycle. You'll learn how to create, read, update, and delete documents in your OpenSearch cluster. Whether you're new to OpenSearch or an experienced user, this guide provides the information you need to manage your document lifecycle effectively. ## Setup Assuming you have OpenSearch running locally on port 9200, you can create a client instance with the following code: @@ -238,4 +238,4 @@ To clean up the resources created in this guide, delete the `movies` index: ```csharp var deleteIndexResponse = client.Indices.Delete("movies"); Debug.Assert(deleteIndexResponse.IsValid, deleteIndexResponse.DebugInformation); -``` \ No newline at end of file +``` diff --git a/guides/json.md b/guides/json.md index b946b59000..896ec1779b 100644 --- a/guides/json.md +++ b/guides/json.md @@ -4,14 +4,17 @@ - [PUT](#put) - [POST](#post) - [DELETE](#delete) - - [Using Different Types Of PostData](#using-different-types-of-postdata) - - [PostData.String](#postdatastring) - - [PostData.Bytes](#postdatabytes) - - [PostData.Serializable](#postdataserializable) - - [PostData.MultiJson](#postdatamultijson) + - [Request Bodies](#request-bodies) + - [String](#string) + - [Bytes](#bytes) + - [Serializable](#serializable) + - [Multi Json](#multi-json) + - [Response Bodies](#response-bodies) # Making Raw JSON REST Requests -The OpenSearch client implements many high-level REST DSLs that invoke OpenSearch APIs. However you may find yourself in a situation that requires you to invoke an API that is not supported by the client. You can use `client.LowLevel.DoRequest` to do so. See [samples/Samples/RawJson/RawJsonSample.cs](../samples/Samples/RawJson/RawJsonSample.cs) for a complete working sample. +The OpenSearch client implements many high-level REST DSLs that invoke OpenSearch APIs. However you may find yourself in a situation that requires you to invoke an API that is not supported by the client. You can use the methods defined within `client.Http` to do so. See [samples/Samples/RawJson/RawJsonHighLevelSample.cs](../samples/Samples/RawJson/RawJsonHighLevelSample.cs) and [samples/Samples/RawJson/RawJsonLowLevelSample.cs](../samples/Samples/RawJson/RawJsonLowLevelSample.cs) for complete working samples. + +Older versions of the client that do not support the `client.Http` namespace can use the `client.LowLevel.DoRequest` method instead. ## HTTP Methods @@ -19,18 +22,29 @@ The OpenSearch client implements many high-level REST DSLs that invoke OpenSearc The following example returns the server version information via `GET /`. ```csharp -var info = await client.LowLevel.DoRequestAsync(HttpMethod.GET, "/", CancellationToken.None); +var info = await client.Http.GetAsync("/"); + Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!"); ``` +### HEAD +The following example checks if an index exists via `HEAD /movies`. + +```csharp +var indexExists = await client.Http.HeadAsync("/movies"); + +Console.WriteLine($"Index Exists: {indexExists.HttpStatusCode == 200}"); +``` + ### PUT The following example creates an index. ```csharp var indexBody = new { settings = new { index = new { number_of_shards = 4 } } }; -var createIndex = await client.LowLevel.DoRequestAsync(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Serializable(indexBody)); -Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation); +var createIndex = await client.Http.PutAsync("/movies", d => d.SerializableBody(indexBody)); + +Console.WriteLine($"Create Index: {createIndex.Success && (bool)createIndex.Body.acknowledged}"); ``` ### POST @@ -45,25 +59,26 @@ var query = new query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } } }; -var search = await client.LowLevel.DoRequestAsync(HttpMethod.POST, $"/{indexName}/_search", CancellationToken.None, PostData.Serializable(query)); -Debug.Assert(search.Success, search.DebugInformation); +var search = await client.Http.PostAsync("/movies/_search", d => d.SerializableBody(query)); -foreach (var hit in search.Body.hits.hits) Console.WriteLine(hit["_source"]["title"]); +foreach (var hit in search.Body.hits.hits) Console.WriteLine($"Search Hit: {hit["_source"]["title"]}"); ``` ### DELETE The following example deletes an index. ```csharp -var deleteDocument = await client.LowLevel.DoRequestAsync(HttpMethod.DELETE, $"/{indexName}/_doc/{id}", CancellationToken.None); -Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation); +var deleteIndex = await client.Http.DeleteAsync("/movies"); + +Console.WriteLine($"Delete Index: {deleteIndex.Success && (bool)deleteIndex.Body.acknowledged}"); ``` -## Using Different Types Of PostData -The OpenSearch .NET client provides a `PostData` class that is used to provide the request body for a request. The `PostData` class has several static methods that can be used to create a `PostData` object from different types of data. +## Request Bodies +For the methods that take a request body (PUT/POST/PATCH) it is possible use several different types to specify the body. The high-level methods provided in `OpenSearch.Client` provide overloaded fluent-methods for setting the body. While the lower level methods in `OpenSearch.Net` accept instances of `PostData`. +The `PostData` class has several static methods that can be used to create a `PostData` object from different types of data. -### PostData.String -The following example shows how to use the `PostData.String` method to create a `PostData` object from a string. +### String +The following example shows how to pass a string as a request body: ```csharp string indexBody = @" @@ -75,11 +90,11 @@ string indexBody = @" } }}"; -await client.LowLevel.DoRequestAsync(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.String(indexBody)); +await client.Http.PutAsync("/movies", d => d.Body(indexBody)); ``` -### PostData.Bytes -The following example shows how to use the `PostData.Bytes` method to create a `PostData` object from a byte array. +### Bytes +The following example shows how to pass a byte array as a request body: ```csharp byte[] indexBody = Encoding.UTF8.GetBytes(@" @@ -91,11 +106,11 @@ byte[] indexBody = Encoding.UTF8.GetBytes(@" } }}"); -await client.LowLevel.DoRequestAsync(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Bytes(indexBody)); +await client.Http.PutAsync("/movies", d => d.Body(indexBody)); ``` -### PostData.Serializable -The following example shows how to use the `PostData.Serializable` method to create a `PostData` object from a serializable object. +### Serializable +The following example shows how to pass an object that will be serialized to JSON as a request body: ```csharp var indexBody = new @@ -109,12 +124,12 @@ var indexBody = new } }; -await client.LowLevel.DoRequestAsync(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Serializable(indexBody)); +await client.Http.PutAsync("/movies", d => d.SerializableBody(indexBody)); ``` -### PostData.MultiJson -The following example shows how to use the `PostData.MultiJson` method to create a `PostData` object from a collection of serializable objects. -The `PostData.MultiJson` method is useful when you want to send multiple documents in a bulk request. +### Multi JSON +The following example shows how to pass a collection of objects (or strings) that will be serialized to JSON and then newline-delimited as a request body. +This formatting is primarily used when you want to make a bulk request. ```csharp var bulkBody = new object[] @@ -125,5 +140,13 @@ var bulkBody = new object[] new { title = "The Godfather: Part II", director = "Francis Ford Coppola", year = 1974 } }; -await client.LowLevel.DoRequestAsync(HttpMethod.POST, "/_bulk", CancellationToken.None, PostData.MultiJson(bulkBody)); +await client.Http.PostAsync("/_bulk", d => d.MultiJsonBody(indexBody)); ``` + +## Response Bodies +There are a handful of response type implementations that can be used to retrieve the response body. These are specified as the generic argument to the request methods. The content of the body will then be available via the `Body` property of the response object. The following response types are available: + +- `VoidResponse`: The response body will not be read. Useful when you only care about the response status code, such as a `HEAD` request to check an index exists. +- `StringResponse`: The response body will be read into a string. +- `BytesResponse`: The response body will be read into a byte array. +- `DynamicResponse`: The response body will be deserialized as JSON into a dynamic object. diff --git a/samples/Samples/RawJson/RawJsonHighLevelSample.cs b/samples/Samples/RawJson/RawJsonHighLevelSample.cs new file mode 100644 index 0000000000..b229918559 --- /dev/null +++ b/samples/Samples/RawJson/RawJsonHighLevelSample.cs @@ -0,0 +1,76 @@ +/* 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. +*/ + +using System.Diagnostics; +using OpenSearch.Client; +using OpenSearch.Net; + +namespace Samples.RawJson; + +public class RawJsonHighLevelSample : Sample +{ + public RawJsonHighLevelSample() : base("raw-json-high-level", "A sample demonstrating how to use the high-level client to perform raw JSON requests") { } + + protected override async Task Run(IOpenSearchClient client) + { + var info = await client.Http.GetAsync("/"); + Debug.Assert(info.Success, info.DebugInformation); + Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!"); + + const string indexName = "movies"; + + // Check if the index already exists + + var indexExists = await client.Http.HeadAsync($"/{indexName}"); + Debug.Assert(indexExists.HttpStatusCode == 404, indexExists.DebugInformation); + Console.WriteLine($"Index Exists: {indexExists.HttpStatusCode == 200}"); + + // Create an index + + var indexBody = new { settings = new { index = new { number_of_shards = 4 } } }; + + var createIndex = await client.Http.PutAsync($"/{indexName}", d => d.SerializableBody(indexBody)); + Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation); + Console.WriteLine($"Create Index: {createIndex.Success && (bool)createIndex.Body.acknowledged}"); + + // Add a document to the index + var document = new { title = "Moneyball", director = "Bennett Miller", year = 2011 }; + + const string id = "1"; + + var addDocument = await client.Http.PutAsync( + $"/{indexName}/_doc/{id}", + d => d + .SerializableBody(document) + .QueryString(qs => qs.Add("refresh", true))); + Debug.Assert(addDocument.Success, addDocument.DebugInformation); + + // Search for a document + const string q = "miller"; + + var query = new + { + size = 5, + query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } } + }; + + var search = await client.Http.PostAsync($"/{indexName}/_search", d => d.SerializableBody(query)); + Debug.Assert(search.Success, search.DebugInformation); + + foreach (var hit in search.Body.hits.hits) Console.WriteLine($"Search Hit: {hit["_source"]["title"]}"); + + // Delete the document + var deleteDocument = await client.Http.DeleteAsync($"/{indexName}/_doc/{id}"); + Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation); + Console.WriteLine($"Delete Document: {deleteDocument.Success}"); + + // Delete the index + var deleteIndex = await client.Http.DeleteAsync($"/{indexName}"); + Debug.Assert(deleteIndex.Success && (bool)deleteIndex.Body.acknowledged, deleteIndex.DebugInformation); + Console.WriteLine($"Delete Index: {deleteIndex.Success && (bool)deleteIndex.Body.acknowledged}"); + } +} diff --git a/samples/Samples/RawJson/RawJsonLowLevelSample.cs b/samples/Samples/RawJson/RawJsonLowLevelSample.cs new file mode 100644 index 0000000000..e8248de1d6 --- /dev/null +++ b/samples/Samples/RawJson/RawJsonLowLevelSample.cs @@ -0,0 +1,76 @@ +/* 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. +*/ + +using System.Diagnostics; +using OpenSearch.Client; +using OpenSearch.Net; +using OpenSearch.Net.Specification.HttpApi; + +namespace Samples.RawJson; + +public class RawJsonLowLevelSample : Sample +{ + public RawJsonLowLevelSample() : base("raw-json-low-level", "A sample demonstrating how to use the low-level client to perform raw JSON requests") { } + + protected override async Task Run(IOpenSearchClient client) + { + var info = await client.LowLevel.Http.GetAsync("/"); + Debug.Assert(info.Success, info.DebugInformation); + Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!"); + + const string indexName = "movies"; + + // Check if the index already exists + + var indexExists = await client.LowLevel.Http.HeadAsync($"/{indexName}"); + Debug.Assert(indexExists.HttpStatusCode == 404, indexExists.DebugInformation); + Console.WriteLine($"Index Exists: {indexExists.HttpStatusCode == 200}"); + + // Create an index + + var indexBody = new { settings = new { index = new { number_of_shards = 4 } } }; + + var createIndex = await client.LowLevel.Http.PutAsync($"/{indexName}", PostData.Serializable(indexBody)); + Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation); + Console.WriteLine($"Create Index: {createIndex.Success && (bool)createIndex.Body.acknowledged}"); + + // Add a document to the index + var document = new { title = "Moneyball", director = "Bennett Miller", year = 2011}; + + const string id = "1"; + + var addDocument = await client.LowLevel.Http.PutAsync( + $"/{indexName}/_doc/{id}", + PostData.Serializable(document), + new HttpPutRequestParameters{ QueryString = {{"refresh", true}} }); + Debug.Assert(addDocument.Success, addDocument.DebugInformation); + + // Search for a document + const string q = "miller"; + + var query = new + { + size = 5, + query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } } + }; + + var search = await client.LowLevel.Http.PostAsync($"/{indexName}/_search", PostData.Serializable(query)); + Debug.Assert(search.Success, search.DebugInformation); + + foreach (var hit in search.Body.hits.hits) Console.WriteLine($"Search Hit: {hit["_source"]["title"]}"); + + // Delete the document + var deleteDocument = await client.LowLevel.Http.DeleteAsync($"/{indexName}/_doc/{id}"); + Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation); + Console.WriteLine($"Delete Document: {deleteDocument.Success}"); + + // Delete the index + var deleteIndex = await client.LowLevel.Http.DeleteAsync($"/{indexName}"); + Debug.Assert(deleteIndex.Success && (bool)deleteIndex.Body.acknowledged, deleteIndex.DebugInformation); + Console.WriteLine($"Delete Index: {deleteIndex.Success && (bool)deleteIndex.Body.acknowledged}"); + } +} diff --git a/samples/Samples/RawJson/RawJsonSample.cs b/samples/Samples/RawJson/RawJsonSample.cs deleted file mode 100644 index 62a75719ef..0000000000 --- a/samples/Samples/RawJson/RawJsonSample.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* 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. -*/ - -using System.Diagnostics; -using OpenSearch.Client; -using OpenSearch.Net; -using HttpMethod = OpenSearch.Net.HttpMethod; - -namespace Samples.RawJson; - -public class RawJsonSample : Sample -{ - public RawJsonSample() : base("raw-json", "A sample demonstrating how to use the low-level client to perform raw JSON requests") { } - - protected override async Task Run(IOpenSearchClient client) - { - var info = await client.LowLevel.DoRequestAsync(HttpMethod.GET, "/", CancellationToken.None); - Debug.Assert(info.Success, info.DebugInformation); - Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!"); - - // Create an index - - const string indexName = "movies"; - - var indexBody = new { settings = new { index = new { number_of_shards = 4 } } }; - - var createIndex = await client.LowLevel.DoRequestAsync(HttpMethod.PUT, $"/{indexName}", CancellationToken.None, PostData.Serializable(indexBody)); - Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation); - - // Add a document to the index - var document = new { title = "Moneyball", director = "Bennett Miller", year = 2011}; - - const string id = "1"; - - var addDocument = await client.LowLevel.DoRequestAsync(HttpMethod.PUT, $"/{indexName}/_doc/{id}", CancellationToken.None, PostData.Serializable(document)); - Debug.Assert(addDocument.Success, addDocument.DebugInformation); - - // Refresh the index - var refresh = await client.LowLevel.DoRequestAsync(HttpMethod.POST, $"/{indexName}/_refresh", CancellationToken.None); - Debug.Assert(refresh.Success, refresh.DebugInformation); - - // Search for a document - const string q = "miller"; - - var query = new - { - size = 5, - query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } } - }; - - var search = await client.LowLevel.DoRequestAsync(HttpMethod.POST, $"/{indexName}/_search", CancellationToken.None, PostData.Serializable(query)); - Debug.Assert(search.Success, search.DebugInformation); - - foreach (var hit in search.Body.hits.hits) Console.WriteLine(hit["_source"]["title"]); - - // Delete the document - var deleteDocument = await client.LowLevel.DoRequestAsync(HttpMethod.DELETE, $"/{indexName}/_doc/{id}", CancellationToken.None); - Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation); - - // Delete the index - var deleteIndex = await client.LowLevel.DoRequestAsync(HttpMethod.DELETE, $"/{indexName}", CancellationToken.None); - Debug.Assert(deleteIndex.Success && (bool)deleteIndex.Body.acknowledged, deleteIndex.DebugInformation); - } -} diff --git a/src/ApiGenerator/CodeTemplatePage.cs b/src/ApiGenerator/CodeTemplatePage.cs index 8b14cd1ead..62e88b6de3 100644 --- a/src/ApiGenerator/CodeTemplatePage.cs +++ b/src/ApiGenerator/CodeTemplatePage.cs @@ -29,13 +29,14 @@ using System.Threading.Tasks; using RazorLight; -namespace ApiGenerator +namespace ApiGenerator; + +public abstract class CodeTemplatePage : TemplatePage { - public abstract class CodeTemplatePage : TemplatePage - { - protected new Task IncludeAsync(string key, object model = null) - => base.IncludeAsync(key.Replace('/', '.'), model); + protected new Task IncludeAsync(string key, object model = null) + => base.IncludeAsync(key.Replace('/', '.'), model); + + protected async Task IncludeLegacyGeneratorNotice() => await IncludeAsync("GeneratorNotice", true); - protected async Task IncludeGeneratorNotice() => await IncludeAsync("GeneratorNotice"); - } + protected async Task IncludeGeneratorNotice() => await IncludeAsync("GeneratorNotice", false); } diff --git a/src/ApiGenerator/Domain/Code/HttpMethod.cs b/src/ApiGenerator/Domain/Code/HttpMethod.cs new file mode 100644 index 0000000000..390aa1e7e1 --- /dev/null +++ b/src/ApiGenerator/Domain/Code/HttpMethod.cs @@ -0,0 +1,42 @@ +/* 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. +*/ + +namespace ApiGenerator.Domain.Code; + +public class HttpMethod +{ + public static readonly HttpMethod Delete = new("Delete", false); + public static readonly HttpMethod Get = new("Get", false); + public static readonly HttpMethod Head = new("Head", false); + public static readonly HttpMethod Patch = new("Patch", true); + public static readonly HttpMethod Post = new("Post", true); + public static readonly HttpMethod Put = new("Put", true); + public static readonly HttpMethod[] All = { Delete, Get, Head, Patch, Post, Put }; + + private readonly string _method; + + private HttpMethod(string method, bool takesBody) + { + _method = method; + TakesBody = takesBody; + } + + public bool TakesBody { get; private set; } + + // ReSharper disable once InconsistentNaming + public string IRequest => $"I{Request}"; + + public string Request => $"Http{_method}Request"; + + public string RequestParameters => $"Http{_method}RequestParameters"; + + public string Descriptor => $"Http{_method}Descriptor"; + + public string MethodEnum => $"HttpMethod.{_method.ToUpperInvariant()}"; + + public override string ToString() => _method; +} diff --git a/src/ApiGenerator/Generator/Razor/DescriptorsGenerator.cs b/src/ApiGenerator/Generator/Razor/DescriptorsGenerator.cs index 4ea3773855..647022027d 100644 --- a/src/ApiGenerator/Generator/Razor/DescriptorsGenerator.cs +++ b/src/ApiGenerator/Generator/Razor/DescriptorsGenerator.cs @@ -26,30 +26,39 @@ * under the License. */ -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using ApiGenerator.Configuration; using ApiGenerator.Domain; +using ApiGenerator.Domain.Code; using ShellProgressBar; -namespace ApiGenerator.Generator.Razor +namespace ApiGenerator.Generator.Razor; + +public class DescriptorsGenerator : RazorGeneratorBase { - public class DescriptorsGenerator : RazorGeneratorBase - { - public override string Title => "OpenSearch.Client descriptors"; - - public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) - { - var view = ViewLocations.HighLevel("Descriptors", "RequestDescriptorBase.cshtml"); - var target = GeneratorLocations.HighLevel("Descriptors.cs"); - await DoRazor(spec, view, target, token); - - var dependantView = ViewLocations.HighLevel("Descriptors", "Descriptors.cshtml"); - string Target(string id) => GeneratorLocations.HighLevel($"Descriptors.{id}.cs"); - var namespaced = spec.EndpointsPerNamespaceHighLevel.ToList(); - await DoRazorDependantFiles(progressBar, namespaced, dependantView, kv => kv.Key, id => Target(id), token); - } - } + public override string Title => "OpenSearch.Client descriptors"; + + public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) + { + await DoRazor(spec, View("RequestDescriptorBase"), Target(), token); + + await DoRazor(HttpMethod.All, View("Descriptors.Http"), Target("Http"), token); + + await DoRazorDependantFiles( + progressBar, + spec.EndpointsPerNamespaceHighLevel.ToList(), + View("Descriptors"), + kv => kv.Key, + Target, + token + ); + + return; + + string View(string name) => ViewLocations.HighLevel("Descriptors", $"{name}.cshtml"); + + string Target(string id = null) => GeneratorLocations.HighLevel($"Descriptors{(id != null ? $".{id}" : string.Empty)}.cs"); + } } diff --git a/src/ApiGenerator/Generator/Razor/HighLevelClientImplementationGenerator.cs b/src/ApiGenerator/Generator/Razor/HighLevelClientImplementationGenerator.cs index fe5a37ef96..945de9ae74 100644 --- a/src/ApiGenerator/Generator/Razor/HighLevelClientImplementationGenerator.cs +++ b/src/ApiGenerator/Generator/Razor/HighLevelClientImplementationGenerator.cs @@ -26,33 +26,42 @@ * under the License. */ -using System.IO; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using ApiGenerator.Configuration; using ApiGenerator.Domain; using ApiGenerator.Domain.Code; +using ApiGenerator.Domain.Specification; using ShellProgressBar; -namespace ApiGenerator.Generator.Razor +namespace ApiGenerator.Generator.Razor; + +public class HighLevelClientImplementationGenerator : RazorGeneratorBase { - public class HighLevelClientImplementationGenerator : RazorGeneratorBase - { - public override string Title => "OpenSearch.Client client implementation"; + public override string Title => "OpenSearch.Client client implementation"; + + public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) + { + await DoRazor(spec, View(), Target(), token); + + await DoRazor(HttpMethod.All, View("Http"), Target("Http"), token); - public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) - { - var view = ViewLocations.HighLevel("Client", "Implementation", "OpenSearchClient.cshtml"); - var target = GeneratorLocations.HighLevel($"OpenSearchClient.cs"); - await DoRazor(spec, view, target, token); + await DoRazorDependantFiles( + progressBar, + spec.EndpointsPerNamespaceHighLevel.Where(kv => kv.Key != CsharpNames.RootNamespace).ToList(), + View("Namespace"), + kv => kv.Key, + Target, + token + ); - string Target(string id) => GeneratorLocations.HighLevel($"OpenSearchClient.{id}.cs"); + return; - var namespaced = spec.EndpointsPerNamespaceHighLevel.Where(kv => kv.Key != CsharpNames.RootNamespace).ToList(); - var dependantView = ViewLocations.HighLevel("Client", "Implementation", "OpenSearchClient.Namespace.cshtml"); - await DoRazorDependantFiles(progressBar, namespaced, dependantView, kv => kv.Key, id => Target(id), token); + string View(string ns = null) => ViewLocations.HighLevel("Client", "Implementation", $"OpenSearchClient{(ns != null ? $".{ns}" : string.Empty)}.cshtml"); - } - } + string Target(string ns = null) => GeneratorLocations.HighLevel($"OpenSearchClient{(ns != null ? $".{ns}" : string.Empty)}.cs"); + } } diff --git a/src/ApiGenerator/Generator/Razor/LowLevelClientImplementationGenerator.cs b/src/ApiGenerator/Generator/Razor/LowLevelClientImplementationGenerator.cs index 8136fa30f0..c5d6328c41 100644 --- a/src/ApiGenerator/Generator/Razor/LowLevelClientImplementationGenerator.cs +++ b/src/ApiGenerator/Generator/Razor/LowLevelClientImplementationGenerator.cs @@ -26,7 +26,6 @@ * under the License. */ -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -35,22 +34,32 @@ using ApiGenerator.Domain.Code; using ShellProgressBar; -namespace ApiGenerator.Generator.Razor +namespace ApiGenerator.Generator.Razor; + +public class LowLevelClientImplementationGenerator : RazorGeneratorBase { - public class LowLevelClientImplementationGenerator : RazorGeneratorBase - { - public override string Title { get; } = "OpenSearch.Net client implementation"; - - public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) - { - var view = ViewLocations.LowLevel("Client", "Implementation", "OpenSearchLowLevelClient.cshtml"); - var target = GeneratorLocations.LowLevel("OpenSearchLowLevelClient.cs"); - await DoRazor(spec, view, target, token); - - var namespaced = spec.EndpointsPerNamespaceLowLevel.Where(kv => kv.Key != CsharpNames.RootNamespace).ToList(); - var namespacedView = ViewLocations.LowLevel("Client", "Implementation", "OpenSearchLowLevelClient.Namespace.cshtml"); - await DoRazorDependantFiles(progressBar, namespaced, namespacedView, kv => kv.Key, - id => GeneratorLocations.LowLevel($"OpenSearchLowLevelClient.{id}.cs"), token); - } - } + public override string Title => "OpenSearch.Net client implementation"; + + public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) + { + await DoRazor(spec, View(), Target(), token); + + await DoRazor(HttpMethod.All, View("Http"), Target("Http"), token); + + await DoRazorDependantFiles( + progressBar, + spec.EndpointsPerNamespaceLowLevel.Where(kv => kv.Key != CsharpNames.RootNamespace).ToList(), + View("Namespace"), + kv => kv.Key, + Target, + token + ); + + return; + + string View(string id = null) => + ViewLocations.LowLevel("Client", "Implementation", $"OpenSearchLowLevelClient{(id != null ? $".{id}" : string.Empty)}.cshtml"); + + string Target(string id = null) => GeneratorLocations.LowLevel($"OpenSearchLowLevelClient{(id != null ? $".{id}" : string.Empty)}.cs"); + } } diff --git a/src/ApiGenerator/Generator/Razor/RequestParametersGenerator.cs b/src/ApiGenerator/Generator/Razor/RequestParametersGenerator.cs index 0edd2cd9ac..9187f22739 100644 --- a/src/ApiGenerator/Generator/Razor/RequestParametersGenerator.cs +++ b/src/ApiGenerator/Generator/Razor/RequestParametersGenerator.cs @@ -26,27 +26,37 @@ * under the License. */ -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using ApiGenerator.Configuration; using ApiGenerator.Domain; +using ApiGenerator.Domain.Code; using ShellProgressBar; -namespace ApiGenerator.Generator.Razor +namespace ApiGenerator.Generator.Razor; + +public class RequestParametersGenerator : RazorGeneratorBase { - public class RequestParametersGenerator : RazorGeneratorBase - { - public override string Title { get; } = "OpenSearch.Net request parameters"; - - public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) - { - var view = ViewLocations.LowLevel("RequestParameters", "RequestParameters.cshtml"); - string Target(string id) => GeneratorLocations.LowLevel("Api", "RequestParameters", $"RequestParameters.{id}.cs"); - - var namespaced = spec.EndpointsPerNamespaceLowLevel.ToList(); - await DoRazorDependantFiles(progressBar, namespaced, view, kv => kv.Key, id => Target(id), token); - } - } + public override string Title => "OpenSearch.Net request parameters"; + + public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) + { + await DoRazor(HttpMethod.All, View("Http"), Target("Http"), token); + + await DoRazorDependantFiles( + progressBar, + spec.EndpointsPerNamespaceLowLevel.ToList(), + View(), + kv => kv.Key, + Target, + token + ); + + return; + + string View(string id = null) => ViewLocations.LowLevel("RequestParameters", $"RequestParameters{(id != null ? $".{id}" : string.Empty)}.cshtml"); + + string Target(string id) => GeneratorLocations.LowLevel("Api", "RequestParameters", $"RequestParameters.{id}.cs"); + } } diff --git a/src/ApiGenerator/Generator/Razor/RequestsGenerator.cs b/src/ApiGenerator/Generator/Razor/RequestsGenerator.cs index dc54bf101f..0e4d0c45fe 100644 --- a/src/ApiGenerator/Generator/Razor/RequestsGenerator.cs +++ b/src/ApiGenerator/Generator/Razor/RequestsGenerator.cs @@ -26,12 +26,16 @@ * under the License. */ +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using ApiGenerator.Configuration; using ApiGenerator.Domain; +using ApiGenerator.Domain.Code; +using ApiGenerator.Domain.Specification; using ShellProgressBar; namespace ApiGenerator.Generator.Razor @@ -42,14 +46,23 @@ public class RequestsGenerator : RazorGeneratorBase public override async Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token) { - var view = ViewLocations.HighLevel("Requests", "PlainRequestBase.cshtml"); - var target = GeneratorLocations.HighLevel("Requests.cs"); - await DoRazor(spec, view, target, token); - - var dependantView = ViewLocations.HighLevel("Requests", "Requests.cshtml"); - string Target(string id) => GeneratorLocations.HighLevel($"Requests.{id}.cs"); - var namespaced = spec.EndpointsPerNamespaceHighLevel.ToList(); - await DoRazorDependantFiles(progressBar, namespaced, dependantView, kv => kv.Key, id => Target(id), token); - } + await DoRazor(spec, View("PlainRequestBase"), Target(), token); + + await DoRazor(HttpMethod.All, View("Requests.Http"), Target("Http"), token); + + await DoRazorDependantFiles( + progressBar, + spec.EndpointsPerNamespaceHighLevel.ToList(), + View("Requests"), + kv => kv.Key, + Target, + token); + + return; + + string View(string name) => ViewLocations.HighLevel("Requests", $"{name}.cshtml"); + + string Target(string id = null) => GeneratorLocations.HighLevel($"Requests{(id != null ? $".{id}" : string.Empty)}.cs"); + } } } diff --git a/src/ApiGenerator/Views/GeneratorNotice.cshtml b/src/ApiGenerator/Views/GeneratorNotice.cshtml index fc624a8e9e..039524ceae 100644 --- a/src/ApiGenerator/Views/GeneratorNotice.cshtml +++ b/src/ApiGenerator/Views/GeneratorNotice.cshtml @@ -1,11 +1,12 @@ @using ApiGenerator -@inherits CodeTemplatePage +@inherits CodeTemplatePage /* 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. -*/ +*/@if (Model) +{ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. @@ -27,15 +28,16 @@ * specific language governing permissions and limitations * under the License. */ +} // ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ // ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ -// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ -// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ // ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ // ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ // ----------------------------------------------- -// -// This file is automatically generated +// +// This file is automatically generated // Please do not edit these files manually // Run the following in the root of the repos: // diff --git a/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Http.cshtml b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Http.cshtml new file mode 100644 index 0000000000..da8f6bc160 --- /dev/null +++ b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Http.cshtml @@ -0,0 +1,53 @@ +@using ApiGenerator +@using ApiGenerator.Domain.Code +@inherits ApiGenerator.CodeTemplatePage> +@{ + const string ns = "Http"; +} +@{ await IncludeGeneratorNotice(); } + +using System; +using System.Threading; +using System.Threading.Tasks; +using OpenSearch.Net; + +namespace OpenSearch.Client.@(CsharpNames.ApiNamespace).@ns@(CsharpNames.ApiNamespaceSuffix); + +/// +/// @ns.SplitPascalCase() APIs. +/// Not intended to be instantiated directly. Use the property +/// on . +/// +/// +public class @(CsharpNames.HighLevelClientNamespacePrefix)@ns@(CsharpNames.ClientNamespaceSuffix) : NamespacedClientProxy +{ + internal @(CsharpNames.HighLevelClientNamespacePrefix)@ns@(CsharpNames.ClientNamespaceSuffix)(OpenSearchClient client) : base(client) {} +@{ + var generic = Raw(""); + + foreach (var m in Model) + { + var bodySelector = Raw(m.TakesBody ? "r => r.Body" : "_ => null"); + var selector = Raw($"Func<{m.Descriptor}, {m.IRequest}> selector = null"); + + + public TResponse @(m)@(generic)(string path, @(selector)) + where TResponse : class, IOpenSearchResponse, new() => + @(m)@(generic)(selector.InvokeOrDefault(new @(m.Descriptor)(path))); + + public Task@(generic) @(m)Async@(generic)(string path, @(selector), CancellationToken ct = default) + where TResponse : class, IOpenSearchResponse, new() => + @(m)Async@(generic)(selector.InvokeOrDefault(new @(m.Descriptor)(path)), ct); + + public TResponse @(m)@(generic)(@m.IRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest@(Raw($"<{m.IRequest}, TResponse>"))(request, request.RequestParameters, @(bodySelector)); + + public Task@(generic) @(m)Async@(generic)(@m.IRequest request, CancellationToken ct = default) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync@(Raw($"<{m.IRequest}, TResponse>"))(request, request.RequestParameters, @(bodySelector), ct); + + + } +} +} diff --git a/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Namespace.cshtml b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Namespace.cshtml index c3c8e5d31b..ebbbf3bc60 100644 --- a/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Namespace.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.Namespace.cshtml @@ -7,7 +7,7 @@ @{ var (ns, endpoints) = Model; } -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Threading; diff --git a/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.cshtml b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.cshtml index c57e3e1dfe..d4c6cd28e3 100644 --- a/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Client/Implementation/OpenSearchClient.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator @using ApiGenerator.Domain.Code @inherits CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Threading; @@ -12,7 +12,10 @@ using OpenSearch.Client; @{ await IncludeAsync("HighLevel/Client/Usings.cshtml", Model);} @{ - var namespaces = Model.EndpointsPerNamespaceHighLevel.Keys.Where(k => k != CsharpNames.RootNamespace).ToList(); + var namespaces = Model.EndpointsPerNamespaceHighLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); + // ReSharper disable RedundantTypeArgumentsOfMethod namespace OpenSearch.Client @@ -35,27 +38,20 @@ namespace OpenSearch.Client foreach (var ns in namespaces) { - @ns = new @(CsharpNames.HighLevelClientNamespacePrefix)@(ns)@(CsharpNames.ClientNamespaceSuffix)(this); + @(ns) = new @(CsharpNames.HighLevelClientNamespacePrefix)@(ns)@(CsharpNames.ClientNamespaceSuffix)(this); } } - - foreach (var kv in Model.EndpointsPerNamespaceHighLevel) - { - if (kv.Key != CsharpNames.RootNamespace) - { - continue; - } - var endpoints = kv.Value; - var models = endpoints.Select(e=>e.HighLevelModel).ToList(); - foreach (var m in models) - { - await IncludeAsync("HighLevel/Client/Implementation/MethodImplementation.cshtml", m); - } - } + if(Model.EndpointsPerNamespaceHighLevel.TryGetValue(CsharpNames.RootNamespace, out var endpoints)) + { + foreach(var m in endpoints.Select(e => e.HighLevelModel)) + { + await IncludeAsync("HighLevel/Client/Implementation/MethodImplementation.cshtml", m); + } + } } } diff --git a/src/ApiGenerator/Views/HighLevel/Client/Interface/IOpenSearchClient.cshtml b/src/ApiGenerator/Views/HighLevel/Client/Interface/IOpenSearchClient.cshtml index 3dd2c0ba9d..fc35066b57 100644 --- a/src/ApiGenerator/Views/HighLevel/Client/Interface/IOpenSearchClient.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Client/Interface/IOpenSearchClient.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator.Domain @using ApiGenerator.Domain.Code @inherits ApiGenerator.CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; @@ -19,21 +19,26 @@ namespace OpenSearch.Client /// OpenSearch high level client /// public partial interface IOpenSearchClient - { - @foreach(var (ns, endpoints) in Model.EndpointsPerNamespaceHighLevel) - { - if (ns != CsharpNames.RootNamespace) - { + { + @{ + var namespaces = Model.EndpointsPerNamespaceHighLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); + + foreach (var ns in namespaces) + { /// @ns.SplitPascalCase() APIs - @CsharpNames.HighLevelClientNamespacePrefix@(ns)@CsharpNames.ClientNamespaceSuffix @ns { get; } + @CsharpNames.HighLevelClientNamespacePrefix@(ns)@CsharpNames.ClientNamespaceSuffix @ns { get; } - continue; - } - var models = endpoints.Select(e=>e.HighLevelModel).ToList(); - foreach(var m in models) - { - await IncludeAsync("HighLevel/Client/Interface/MethodInterface.cshtml", m); - } - } - } + } + + if(Model.EndpointsPerNamespaceHighLevel.TryGetValue(CsharpNames.RootNamespace, out var endpoints)) + { + foreach(var m in endpoints.Select(e => e.HighLevelModel)) + { + await IncludeAsync("HighLevel/Client/Interface/MethodInterface.cshtml", m); + } + } + } + } } diff --git a/src/ApiGenerator/Views/HighLevel/Client/Usings.cshtml b/src/ApiGenerator/Views/HighLevel/Client/Usings.cshtml index 807e3e4ed5..65b76adb6e 100644 --- a/src/ApiGenerator/Views/HighLevel/Client/Usings.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Client/Usings.cshtml @@ -1,11 +1,14 @@ @using ApiGenerator.Domain @using ApiGenerator.Domain.Code @inherits ApiGenerator.CodeTemplatePage -@foreach(var ns in Model.EndpointsPerNamespaceHighLevel.Keys) -{ - if (ns != CsharpNames.RootNamespace) - { +@{ + var namespaces = Model.EndpointsPerNamespaceHighLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); + + foreach (var ns in namespaces) + { using OpenSearch.Client.@(CsharpNames.ApiNamespace).@(ns)@(CsharpNames.ApiNamespaceSuffix); - } + } } diff --git a/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.Http.cshtml b/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.Http.cshtml new file mode 100644 index 0000000000..b9b54df51b --- /dev/null +++ b/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.Http.cshtml @@ -0,0 +1,22 @@ +@using ApiGenerator.Domain.Code +@inherits ApiGenerator.CodeTemplatePage> +@{ + const string ns = "Http"; +} +@{ await IncludeGeneratorNotice(); } + +using OpenSearch.Net.@(CsharpNames.ApiNamespace).@ns@(CsharpNames.ApiNamespaceSuffix); + +namespace OpenSearch.Client; + +@foreach (var m in Model) +{ + + + public class @m.Descriptor : @Raw($"Arbitrary{(m.TakesBody ? "Body" : string.Empty)}HttpRequestDescriptorBase<{m.Descriptor}, {m.RequestParameters}, {m.IRequest}>"), @m.IRequest + { + public @(m.Descriptor)(string path) : base(path) { } + } + + +} diff --git a/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.cshtml b/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.cshtml index 9cc724477e..46c8bcba21 100644 --- a/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Descriptors/Descriptors.cshtml @@ -7,7 +7,7 @@ var (ns, endpoints) = Model; ns = ns != CsharpNames.RootNamespace ? $".{CsharpNames.ApiNamespace}.{ns}{CsharpNames.ApiNamespaceSuffix}" : null; } -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; diff --git a/src/ApiGenerator/Views/HighLevel/Descriptors/RequestDescriptorBase.cshtml b/src/ApiGenerator/Views/HighLevel/Descriptors/RequestDescriptorBase.cshtml index 14ffe82e89..43d6ed6d08 100644 --- a/src/ApiGenerator/Views/HighLevel/Descriptors/RequestDescriptorBase.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Descriptors/RequestDescriptorBase.cshtml @@ -1,6 +1,6 @@ @using ApiGenerator.Domain @inherits ApiGenerator.CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } using System.Collections.Generic; namespace OpenSearch.Client diff --git a/src/ApiGenerator/Views/HighLevel/Requests/ApiUrlsLookup.cshtml b/src/ApiGenerator/Views/HighLevel/Requests/ApiUrlsLookup.cshtml index 4cebf146e9..eaca2173f2 100644 --- a/src/ApiGenerator/Views/HighLevel/Requests/ApiUrlsLookup.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Requests/ApiUrlsLookup.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator @using ApiGenerator.Configuration @inherits CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } namespace OpenSearch.Client { internal static partial class ApiUrlsLookups diff --git a/src/ApiGenerator/Views/HighLevel/Requests/PlainRequestBase.cshtml b/src/ApiGenerator/Views/HighLevel/Requests/PlainRequestBase.cshtml index b042d9c1e5..8a0fbafbc6 100644 --- a/src/ApiGenerator/Views/HighLevel/Requests/PlainRequestBase.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Requests/PlainRequestBase.cshtml @@ -1,6 +1,6 @@ @using ApiGenerator.Domain @inherits ApiGenerator.CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; diff --git a/src/ApiGenerator/Views/HighLevel/Requests/Requests.Http.cshtml b/src/ApiGenerator/Views/HighLevel/Requests/Requests.Http.cshtml new file mode 100644 index 0000000000..249c2d3ef5 --- /dev/null +++ b/src/ApiGenerator/Views/HighLevel/Requests/Requests.Http.cshtml @@ -0,0 +1,28 @@ +@using ApiGenerator.Domain.Code +@inherits ApiGenerator.CodeTemplatePage> +@{ + const string ns = "Http"; +} +@{ await IncludeGeneratorNotice(); } + +using OpenSearch.Net.@(CsharpNames.ApiNamespace).@ns@(CsharpNames.ApiNamespaceSuffix); +using OpenSearch.Net.Utf8Json; + +namespace OpenSearch.Client; + +@foreach (var m in Model) +{ + + + public interface @m.IRequest : @Raw($"IArbitrary{(m.TakesBody ? "Body" : string.Empty)}HttpRequest<{m.RequestParameters}>") { } + + public class @m.Request : @Raw($"Arbitrary{(m.TakesBody ? "Body" : string.Empty)}HttpRequestBase<{m.RequestParameters}>"), @m.IRequest + { + [SerializationConstructor] + protected @(m.Request)() { } + + public @(m.Request)(string path) : base(path) { } + } + + +} diff --git a/src/ApiGenerator/Views/HighLevel/Requests/Requests.cshtml b/src/ApiGenerator/Views/HighLevel/Requests/Requests.cshtml index aad12489f7..ceb8018eca 100644 --- a/src/ApiGenerator/Views/HighLevel/Requests/Requests.cshtml +++ b/src/ApiGenerator/Views/HighLevel/Requests/Requests.cshtml @@ -7,7 +7,7 @@ var (ns, endpoints) = Model; ns = ns != CsharpNames.RootNamespace ? $".{CsharpNames.ApiNamespace}.{ns}{CsharpNames.ApiNamespaceSuffix}" : null; } -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; diff --git a/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Http.cshtml b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Http.cshtml new file mode 100644 index 0000000000..9203b83f6d --- /dev/null +++ b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Http.cshtml @@ -0,0 +1,51 @@ +@using ApiGenerator +@using ApiGenerator.Domain.Code +@inherits ApiGenerator.CodeTemplatePage> +@{ + const string ns = "Http"; +} +@{ await IncludeGeneratorNotice(); } + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenSearch.Net.@(CsharpNames.ApiNamespace).@ns@(CsharpNames.ApiNamespaceSuffix); + +/// +/// @ns.SplitPascalCase() APIs. +/// Not intended to be instantiated directly. Use the property +/// on . +/// +/// +public class @(CsharpNames.LowLevelClientNamespacePrefix)@ns@(CsharpNames.ClientNamespaceSuffix) : NamespacedClientProxy +{ + internal @(CsharpNames.LowLevelClientNamespacePrefix)@ns@(CsharpNames.ClientNamespaceSuffix)(OpenSearchLowLevelClient client) : base(client) {} +@{ + var generic = Raw(""); + + foreach (var m in Model) + { + var bodyParam = m.TakesBody ? ", PostData body = null" : string.Empty; + + + public TResponse @(m)@(generic)(FormattableString path@(bodyParam), @m.RequestParameters parameters = null) + where TResponse : class, IOpenSearchResponse, new() => + @(m)@(generic)(Url(path)@(m.TakesBody ? ", body" : string.Empty), parameters); + + public Task@(generic) @(m)Async@(generic)(FormattableString path@(bodyParam), @m.RequestParameters parameters = null, CancellationToken ctx = default) + where TResponse : class, IOpenSearchResponse, new() => + @(m)Async@(generic)(Url(path)@(m.TakesBody ? ", body" : string.Empty), parameters, ctx); + + public TResponse @(m)@(generic)(string path@(bodyParam), @m.RequestParameters parameters = null) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest@(generic)(@m.MethodEnum, path, @(m.TakesBody ? "body" : "null"), RequestParams(parameters)); + + public Task@(generic) @(m)Async@(generic)(string path@(bodyParam), @m.RequestParameters parameters = null, CancellationToken ctx = default) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync@(generic)(@m.MethodEnum, path, ctx, @(m.TakesBody ? "body" : "null"), RequestParams(parameters)); + + + } +} +} diff --git a/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Namespace.cshtml b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Namespace.cshtml index 7711359b87..ebfd4cb1a8 100644 --- a/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Namespace.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.Namespace.cshtml @@ -4,7 +4,7 @@ @using ApiGenerator.Domain.Code @using ApiGenerator.Domain.Specification @inherits CodeTemplatePage>> -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } @{ var (ns, endpoints) = Model; } diff --git a/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.cshtml b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.cshtml index 2795157ec4..655d586510 100644 --- a/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Client/Implementation/OpenSearchLowLevelClient.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator @using ApiGenerator.Domain.Code @inherits CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; @@ -17,7 +17,9 @@ using OpenSearch.Net; using static OpenSearch.Net.HttpMethod; @{ - var namespaces = Model.EndpointsPerNamespaceLowLevel.Keys.Where(k => k != CsharpNames.RootNamespace).ToList(); + var namespaces = Model.EndpointsPerNamespaceLowLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); // ReSharper disable InterpolatedStringExpressionIsNotIFormattable // ReSharper disable RedundantExtendsListEntry @@ -47,19 +49,13 @@ namespace OpenSearch.Net } - - foreach (var (ns, endpoints) in Model.EndpointsPerNamespaceLowLevel) - { - if (ns != CsharpNames.RootNamespace) - { - continue; - } - var methods = endpoints.SelectMany(e=>e.LowLevelClientMethods).ToList(); - foreach (var method in methods) - { - await IncludeAsync("LowLevel/Client/Methods/MethodImplementation.cshtml", method); - } - } + if(Model.EndpointsPerNamespaceLowLevel.TryGetValue(CsharpNames.RootNamespace, out var endpoints)) + { + foreach(var m in endpoints.SelectMany(e => e.LowLevelClientMethods)) + { + await IncludeAsync("LowLevel/Client/Methods/MethodImplementation.cshtml", m); + } + } } } diff --git a/src/ApiGenerator/Views/LowLevel/Client/Interface/IOpenSearchLowLevelClient.cshtml b/src/ApiGenerator/Views/LowLevel/Client/Interface/IOpenSearchLowLevelClient.cshtml index 4a90af2fb8..399f4984f7 100644 --- a/src/ApiGenerator/Views/LowLevel/Client/Interface/IOpenSearchLowLevelClient.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Client/Interface/IOpenSearchLowLevelClient.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator.Domain @using ApiGenerator.Domain.Code @inherits ApiGenerator.CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } // ReSharper disable RedundantUsingDirective using System; using System.Collections.Generic; @@ -21,22 +21,27 @@ namespace OpenSearch.Net /// OpenSearch low level client /// public partial interface IOpenSearchLowLevelClient - { - @foreach(var (ns, endpoints) in Model.EndpointsPerNamespaceLowLevel) - { - if (ns != CsharpNames.RootNamespace) - { + { + @{ + var namespaces = Model.EndpointsPerNamespaceLowLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); + + foreach (var ns in namespaces) + { - /// @ns.SplitPascalCase() APIs - @CsharpNames.LowLevelClientNamespacePrefix@(ns)@CsharpNames.ClientNamespaceSuffix @ns { get; } + /// @ns.SplitPascalCase() APIs + @CsharpNames.LowLevelClientNamespacePrefix@(ns)@CsharpNames.ClientNamespaceSuffix @ns { get; } - continue; - } - var methods = endpoints.SelectMany(e=>e.LowLevelClientMethods).ToList(); - foreach(var method in methods) - { - await IncludeAsync("LowLevel/Client/Methods/MethodInterface.cshtml", method); - } - } + } + + if(Model.EndpointsPerNamespaceHighLevel.TryGetValue(CsharpNames.RootNamespace, out var endpoints)) + { + foreach(var m in endpoints.SelectMany(e => e.LowLevelClientMethods)) + { + await IncludeAsync("LowLevel/Client/Methods/MethodInterface.cshtml", m); + } + } + } } } diff --git a/src/ApiGenerator/Views/LowLevel/Client/Usings.cshtml b/src/ApiGenerator/Views/LowLevel/Client/Usings.cshtml index 7dcc951284..5abe91e7ab 100644 --- a/src/ApiGenerator/Views/LowLevel/Client/Usings.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Client/Usings.cshtml @@ -1,11 +1,14 @@ @using ApiGenerator.Domain @using ApiGenerator.Domain.Code @inherits ApiGenerator.CodeTemplatePage -@foreach(var ns in Model.EndpointsPerNamespaceLowLevel.Keys) -{ - if (ns != CsharpNames.RootNamespace) - { +@{ + var namespaces = Model.EndpointsPerNamespaceLowLevel.Keys.ToHashSet(); + namespaces.Remove(CsharpNames.RootNamespace); + namespaces.Add("Http"); + + foreach (var ns in namespaces) + { using OpenSearch.Net.@(CsharpNames.ApiNamespace).@(ns)@(CsharpNames.ApiNamespaceSuffix); - } + } } diff --git a/src/ApiGenerator/Views/LowLevel/Enums.cshtml b/src/ApiGenerator/Views/LowLevel/Enums.cshtml index 5bb81aa7c1..65bc11fe9f 100644 --- a/src/ApiGenerator/Views/LowLevel/Enums.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Enums.cshtml @@ -4,7 +4,7 @@ @using ApiGenerator @using ApiGenerator.Configuration.Overrides @inherits CodeTemplatePage -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } @functions { private const string RawSize = "Raw"; private const string SizeEnum = "Size"; diff --git a/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.Http.cshtml b/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.Http.cshtml new file mode 100644 index 0000000000..243c65c4d4 --- /dev/null +++ b/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.Http.cshtml @@ -0,0 +1,35 @@ +@using ApiGenerator.Domain.Code +@inherits ApiGenerator.CodeTemplatePage> +@{ + const string ns = "Http"; +} +@{ await IncludeGeneratorNotice(); } + +using OpenSearch.Net; + +namespace OpenSearch.Net.@(CsharpNames.ApiNamespace).@ns@(CsharpNames.ApiNamespaceSuffix); + +public abstract class ArbitraryHttpRequestParameters@(Raw("")) : RequestParameters@(Raw("")) + where TSelf : ArbitraryHttpRequestParameters@(Raw("")) +{ + protected ArbitraryHttpRequestParameters(HttpMethod method, bool supportsBody) + { + DefaultHttpMethod = method; + SupportsBody = supportsBody; + } + + public override HttpMethod DefaultHttpMethod { get; } + public override bool SupportsBody { get; } +} + +@foreach (var m in Model) +{ + + + public class @m.RequestParameters : ArbitraryHttpRequestParameters@(Raw($"<{m.RequestParameters}>")) + { + public @(m.RequestParameters)() : base(@(m.MethodEnum), @(m.TakesBody.ToString().ToLowerInvariant())) { } + } + + +} diff --git a/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.cshtml b/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.cshtml index fd477d54ef..110f7f51bc 100644 --- a/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.cshtml +++ b/src/ApiGenerator/Views/LowLevel/RequestParameters/RequestParameters.cshtml @@ -3,7 +3,7 @@ @using ApiGenerator.Domain.Code @using ApiGenerator.Domain.Specification @inherits CodeTemplatePage>> -@{ await IncludeGeneratorNotice(); } +@{ await IncludeLegacyGeneratorNotice(); } @{ var (ns, endpoints) = Model; ns = ns != CsharpNames.RootNamespace ? $".{CsharpNames.ApiNamespace}.{ns}{CsharpNames.ApiNamespaceSuffix}" : null; diff --git a/src/OpenSearch.Client/Http/ArbitraryHttpRequestBase.cs b/src/OpenSearch.Client/Http/ArbitraryHttpRequestBase.cs new file mode 100644 index 0000000000..1f130b2f26 --- /dev/null +++ b/src/OpenSearch.Client/Http/ArbitraryHttpRequestBase.cs @@ -0,0 +1,142 @@ +/* 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. +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Threading; +using System.Threading.Tasks; +using OpenSearch.Net; +using OpenSearch.Net.Specification.HttpApi; + +namespace OpenSearch.Client; + +public interface IArbitraryHttpRequest : IRequest + where T : ArbitraryHttpRequestParameters, new() +{ + [IgnoreDataMember] + string Path { get; set; } +} + +public interface IArbitraryBodyHttpRequest : IArbitraryHttpRequest + where T : ArbitraryHttpRequestParameters, new() +{ + [IgnoreDataMember] + PostData Body { get; set; } +} + +public abstract class ArbitraryHttpRequestBase + : PlainRequestBase, IArbitraryHttpRequest + where TParams : ArbitraryHttpRequestParameters, new() +{ + private string _path; + + protected ArbitraryHttpRequestBase() { } + + protected ArbitraryHttpRequestBase(string path) => Path = path; + + public string Path + { + get => _path; + set + { + if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Path), "Path cannot be null or empty"); + _path = value; + } + } + + public Dictionary QueryString + { + get => RequestState.RequestParameters.QueryString; + set => RequestState.RequestParameters.QueryString = value; + } + + internal override ApiUrls ApiUrls => throw new NotImplementedException(); + + protected override string ResolveUrl(RouteValues routeValues, IConnectionSettingsValues settings) => throw new NotImplementedException(); + + string IRequest.GetUrl(IConnectionSettingsValues settings) => Path; +} + +public abstract class ArbitraryBodyHttpRequestBase + : ArbitraryHttpRequestBase, IArbitraryBodyHttpRequest + where TParams : ArbitraryHttpRequestParameters, new() +{ + protected ArbitraryBodyHttpRequestBase() { } + + protected ArbitraryBodyHttpRequestBase(string path) : base(path) { } + + public PostData Body { get; set; } +} + +public abstract class ArbitraryHttpRequestDescriptorBase + : RequestDescriptorBase, IArbitraryHttpRequest + where TSelf : ArbitraryHttpRequestDescriptorBase, TInterface + where TParams : ArbitraryHttpRequestParameters, new() + where TInterface : IArbitraryHttpRequest +{ + private string _path; + + protected ArbitraryHttpRequestDescriptorBase(string path) => Path = path; + + public string Path + { + get => _path; + set + { + if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Path), "Path cannot be null or empty"); + _path = value; + } + } + + public TSelf QueryString(Dictionary queryString) => + Assign(queryString, (a, v) => a.RequestParameters.QueryString = v); + + public TSelf QueryString(Func, FluentDictionary> selector) => + Assign(selector, (a, v) => a.RequestParameters.QueryString = v?.Invoke(new FluentDictionary())); + + internal override ApiUrls ApiUrls => throw new NotImplementedException(); + + protected override string ResolveUrl(RouteValues routeValues, IConnectionSettingsValues settings) => throw new NotImplementedException(); + + string IRequest.GetUrl(IConnectionSettingsValues settings) => Path; +} + +public abstract class ArbitraryBodyHttpRequestDescriptorBase + : ArbitraryHttpRequestDescriptorBase, IArbitraryBodyHttpRequest + where TSelf : ArbitraryBodyHttpRequestDescriptorBase, TInterface + where TParams : ArbitraryHttpRequestParameters, new() + where TInterface : IArbitraryBodyHttpRequest +{ + protected ArbitraryBodyHttpRequestDescriptorBase(string path) : base(path) { } + + PostData IArbitraryBodyHttpRequest.Body { get; set; } + + public TSelf Body(PostData body) => Assign(body, (a, v) => a.Body = v); + + private TSelf Body(T data, Func factory) where T: class => Body(data != null ? factory(data) : null); + + private TSelf Body(T? data, Func factory) where T: struct => Body(data.HasValue ? factory(data.Value) : null); + + public TSelf Body(byte[] bytes) => Body(bytes, PostData.Bytes); + + public TSelf Body(string body) => Body(body, PostData.String); + +#if NETSTANDARD2_1 + public TSelf Body(ReadOnlyMemory? bytes) => Body(bytes, PostData.ReadOnlyMemory); +#endif + + public TSelf MultiJsonBody(IEnumerable items) => Body(items, PostData.MultiJson); + + public TSelf MultiJsonBody(IEnumerable items) => Body(items, PostData.MultiJson); + + public TSelf StreamableBody(T state, Action syncWriter, Func asyncWriter) => + Body(PostData.StreamHandler(state, syncWriter, asyncWriter)); + + public TSelf SerializableBody(T o) => Body(PostData.Serializable(o)); +} diff --git a/src/OpenSearch.Client/OpenSearch.Client.csproj b/src/OpenSearch.Client/OpenSearch.Client.csproj index f2519f6e9c..0054c0e8a3 100644 --- a/src/OpenSearch.Client/OpenSearch.Client.csproj +++ b/src/OpenSearch.Client/OpenSearch.Client.csproj @@ -13,7 +13,7 @@ true true - netstandard2.0 + netstandard2.0;netstandard2.1 diff --git a/src/OpenSearch.Client/OpenSearchClient.cs b/src/OpenSearch.Client/OpenSearchClient.cs index 8beeb140fc..77ca1c7206 100644 --- a/src/OpenSearch.Client/OpenSearchClient.cs +++ b/src/OpenSearch.Client/OpenSearchClient.cs @@ -29,7 +29,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using OpenSearch.Client.Specification.CatApi; using OpenSearch.Net; namespace OpenSearch.Client @@ -42,23 +41,44 @@ public class NamespacedClientProxy protected NamespacedClientProxy(OpenSearchClient client) => _client = client; internal TResponse DoRequest( - TRequest p, + TRequest request, IRequestParameters parameters, Action forceConfiguration = null ) where TRequest : class, IRequest where TResponse : class, IOpenSearchResponse, new() => - _client.DoRequest(p, parameters, forceConfiguration); + _client.DoRequest(request, parameters, forceConfiguration); internal Task DoRequestAsync( - TRequest p, + TRequest request, IRequestParameters parameters, CancellationToken ct, Action forceConfiguration = null ) where TRequest : class, IRequest where TResponse : class, IOpenSearchResponse, new() => - _client.DoRequestAsync(p, parameters, ct, forceConfiguration); + _client.DoRequestAsync(request, parameters, ct, forceConfiguration); + + internal TResponse DoRequest( + TRequest request, + IRequestParameters parameters, + Func bodySelector, + Action forceConfiguration = null + ) + where TRequest : class, IRequest + where TResponse : class, IOpenSearchResponse, new() => + _client.DoRequest(request, parameters, bodySelector, forceConfiguration); + + internal Task DoRequestAsync( + TRequest request, + IRequestParameters parameters, + Func bodySelector, + CancellationToken ct, + Action forceConfiguration = null + ) + where TRequest : class, IRequest + where TResponse : class, IOpenSearchResponse, new() => + _client.DoRequestAsync(request, parameters, bodySelector, ct, forceConfiguration); protected CatResponse DoCat(TRequest request) where TCatRecord : ICatRecord @@ -141,35 +161,68 @@ public OpenSearchClient(ITransport transport) private ITransport Transport { get; } - internal TResponse DoRequest(TRequest p, IRequestParameters parameters, Action forceConfiguration = null) + internal TResponse DoRequest( + TRequest request, + IRequestParameters parameters, + Action forceConfiguration = null + ) where TRequest : class, IRequest - where TResponse : class, IOpenSearchResponse, new() - { - if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration); - if (p.ContentType != null) ForceContentType(p, p.ContentType); + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, parameters, PostData.Serializable, forceConfiguration); - var url = p.GetUrl(ConnectionSettings); - var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD || !parameters.SupportsBody) ? null : new SerializableData(p); + internal Task DoRequestAsync( + TRequest request, + IRequestParameters parameters, + CancellationToken ct, + Action forceConfiguration = null + ) + where TRequest : class, IRequest + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(request, parameters, PostData.Serializable, ct, forceConfiguration); - return LowLevel.DoRequest(p.HttpMethod, url, b, parameters); + internal TResponse DoRequest( + TRequest request, + IRequestParameters parameters, + Func bodySelector, + Action forceConfiguration = null + ) + where TRequest : class, IRequest + where TResponse : class, IOpenSearchResponse, new() + { + var (method, url, body) = PrepareRequest(request, parameters, bodySelector, forceConfiguration); + return LowLevel.DoRequest(method, url, body, parameters); } internal Task DoRequestAsync( - TRequest p, + TRequest request, IRequestParameters parameters, + Func bodySelector, CancellationToken ct, Action forceConfiguration = null ) where TRequest : class, IRequest where TResponse : class, IOpenSearchResponse, new() { - if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration); - if (p.ContentType != null) ForceContentType(p, p.ContentType); + var (method, url, body) = PrepareRequest(request, parameters, bodySelector, forceConfiguration); + return LowLevel.DoRequestAsync(method, url, ct, body, parameters); + } + + private (HttpMethod method, string url, PostData body) PrepareRequest( + TRequest request, + IRequestParameters parameters, + Func bodySelector, + Action forceConfiguration + ) + where TRequest: class, IRequest + { + if (forceConfiguration != null) ForceConfiguration(request, forceConfiguration); + if (request.ContentType != null) ForceContentType(request, request.ContentType); - var url = p.GetUrl(ConnectionSettings); - var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD || !parameters.SupportsBody) ? null : new SerializableData(p); + var url = request.GetUrl(ConnectionSettings); + var method = request.HttpMethod; + var body = method == HttpMethod.GET || method == HttpMethod.HEAD || !parameters.SupportsBody ? null : bodySelector(request); - return LowLevel.DoRequestAsync(p.HttpMethod, url, ct, b, parameters); + return (method, url, body); } private static void ForceConfiguration(IRequest request, Action forceConfiguration) diff --git a/src/OpenSearch.Client/_Generated/Descriptors.Http.cs b/src/OpenSearch.Client/_Generated/Descriptors.Http.cs new file mode 100644 index 0000000000..dd46e6e4d4 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/Descriptors.Http.cs @@ -0,0 +1,98 @@ +/* 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. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// This file is automatically generated +// Please do not edit these files manually +// Run the following in the root of the repos: +// +// *NIX : ./build.sh codegen +// Windows : build.bat codegen +// +// ----------------------------------------------- + +using OpenSearch.Net.Specification.HttpApi; + +namespace OpenSearch.Client; + +public class HttpDeleteDescriptor + : ArbitraryHttpRequestDescriptorBase< + HttpDeleteDescriptor, + HttpDeleteRequestParameters, + IHttpDeleteRequest + >, + IHttpDeleteRequest +{ + public HttpDeleteDescriptor(string path) + : base(path) { } +} + +public class HttpGetDescriptor + : ArbitraryHttpRequestDescriptorBase< + HttpGetDescriptor, + HttpGetRequestParameters, + IHttpGetRequest + >, + IHttpGetRequest +{ + public HttpGetDescriptor(string path) + : base(path) { } +} + +public class HttpHeadDescriptor + : ArbitraryHttpRequestDescriptorBase< + HttpHeadDescriptor, + HttpHeadRequestParameters, + IHttpHeadRequest + >, + IHttpHeadRequest +{ + public HttpHeadDescriptor(string path) + : base(path) { } +} + +public class HttpPatchDescriptor + : ArbitraryBodyHttpRequestDescriptorBase< + HttpPatchDescriptor, + HttpPatchRequestParameters, + IHttpPatchRequest + >, + IHttpPatchRequest +{ + public HttpPatchDescriptor(string path) + : base(path) { } +} + +public class HttpPostDescriptor + : ArbitraryBodyHttpRequestDescriptorBase< + HttpPostDescriptor, + HttpPostRequestParameters, + IHttpPostRequest + >, + IHttpPostRequest +{ + public HttpPostDescriptor(string path) + : base(path) { } +} + +public class HttpPutDescriptor + : ArbitraryBodyHttpRequestDescriptorBase< + HttpPutDescriptor, + HttpPutRequestParameters, + IHttpPutRequest + >, + IHttpPutRequest +{ + public HttpPutDescriptor(string path) + : base(path) { } +} diff --git a/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs b/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs index 989f5d993f..22732f559a 100644 --- a/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs +++ b/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs @@ -50,6 +50,7 @@ using OpenSearch.Client; using OpenSearch.Client.Specification.ClusterApi; using OpenSearch.Client.Specification.DanglingIndicesApi; +using OpenSearch.Client.Specification.HttpApi; using OpenSearch.Client.Specification.IndicesApi; using OpenSearch.Client.Specification.IngestApi; using OpenSearch.Client.Specification.NodesApi; @@ -78,6 +79,15 @@ public partial interface IOpenSearchClient /// Nodes APIs NodesNamespace Nodes { get; } + /// Http APIs + HttpNamespace Http { get; } + + /// Snapshot APIs + SnapshotNamespace Snapshot { get; } + + /// Tasks APIs + TasksNamespace Tasks { get; } + /// /// POST request to the create_pit API, read more about this API online: /// @@ -237,11 +247,5 @@ Task GetAllPitsAsync( IGetAllPitsRequest request, CancellationToken ct = default ); - - /// Snapshot APIs - SnapshotNamespace Snapshot { get; } - - /// Tasks APIs - TasksNamespace Tasks { get; } } } diff --git a/src/OpenSearch.Client/_Generated/OpenSearchClient.Http.cs b/src/OpenSearch.Client/_Generated/OpenSearchClient.Http.cs new file mode 100644 index 0000000000..340074cb59 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/OpenSearchClient.Http.cs @@ -0,0 +1,227 @@ +/* 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. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// This file is automatically generated +// Please do not edit these files manually +// Run the following in the root of the repos: +// +// *NIX : ./build.sh codegen +// Windows : build.bat codegen +// +// ----------------------------------------------- + +using System; +using System.Threading; +using System.Threading.Tasks; +using OpenSearch.Net; + +namespace OpenSearch.Client.Specification.HttpApi; + +/// +/// Http APIs. +/// Not intended to be instantiated directly. Use the property +/// on . +/// +/// +public class HttpNamespace : NamespacedClientProxy +{ + internal HttpNamespace(OpenSearchClient client) + : base(client) { } + + public TResponse Delete( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Delete(selector.InvokeOrDefault(new HttpDeleteDescriptor(path))); + + public Task DeleteAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DeleteAsync(selector.InvokeOrDefault(new HttpDeleteDescriptor(path)), ct); + + public TResponse Delete(IHttpDeleteRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, _ => null); + + public Task DeleteAsync( + IHttpDeleteRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + _ => null, + ct + ); + + public TResponse Get( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Get(selector.InvokeOrDefault(new HttpGetDescriptor(path))); + + public Task GetAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + GetAsync(selector.InvokeOrDefault(new HttpGetDescriptor(path)), ct); + + public TResponse Get(IHttpGetRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, _ => null); + + public Task GetAsync( + IHttpGetRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + _ => null, + ct + ); + + public TResponse Head( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Head(selector.InvokeOrDefault(new HttpHeadDescriptor(path))); + + public Task HeadAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + HeadAsync(selector.InvokeOrDefault(new HttpHeadDescriptor(path)), ct); + + public TResponse Head(IHttpHeadRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, _ => null); + + public Task HeadAsync( + IHttpHeadRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + _ => null, + ct + ); + + public TResponse Patch( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Patch(selector.InvokeOrDefault(new HttpPatchDescriptor(path))); + + public Task PatchAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PatchAsync(selector.InvokeOrDefault(new HttpPatchDescriptor(path)), ct); + + public TResponse Patch(IHttpPatchRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, r => r.Body); + + public Task PatchAsync( + IHttpPatchRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + r => r.Body, + ct + ); + + public TResponse Post( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Post(selector.InvokeOrDefault(new HttpPostDescriptor(path))); + + public Task PostAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PostAsync(selector.InvokeOrDefault(new HttpPostDescriptor(path)), ct); + + public TResponse Post(IHttpPostRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, r => r.Body); + + public Task PostAsync( + IHttpPostRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + r => r.Body, + ct + ); + + public TResponse Put( + string path, + Func selector = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Put(selector.InvokeOrDefault(new HttpPutDescriptor(path))); + + public Task PutAsync( + string path, + Func selector = null, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PutAsync(selector.InvokeOrDefault(new HttpPutDescriptor(path)), ct); + + public TResponse Put(IHttpPutRequest request) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(request, request.RequestParameters, r => r.Body); + + public Task PutAsync( + IHttpPutRequest request, + CancellationToken ct = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + request, + request.RequestParameters, + r => r.Body, + ct + ); +} diff --git a/src/OpenSearch.Client/_Generated/OpenSearchClient.cs b/src/OpenSearch.Client/_Generated/OpenSearchClient.cs index 76a81b7772..28f5994f96 100644 --- a/src/OpenSearch.Client/_Generated/OpenSearchClient.cs +++ b/src/OpenSearch.Client/_Generated/OpenSearchClient.cs @@ -48,6 +48,7 @@ using OpenSearch.Client; using OpenSearch.Client.Specification.ClusterApi; using OpenSearch.Client.Specification.DanglingIndicesApi; +using OpenSearch.Client.Specification.HttpApi; using OpenSearch.Client.Specification.IndicesApi; using OpenSearch.Client.Specification.IngestApi; using OpenSearch.Client.Specification.NodesApi; @@ -77,6 +78,9 @@ public partial class OpenSearchClient : IOpenSearchClient /// Nodes APIs public NodesNamespace Nodes { get; private set; } + /// Http APIs + public HttpNamespace Http { get; private set; } + /// Snapshot APIs public SnapshotNamespace Snapshot { get; private set; } @@ -90,6 +94,7 @@ partial void SetupGeneratedNamespaces() Indices = new IndicesNamespace(this); Ingest = new IngestNamespace(this); Nodes = new NodesNamespace(this); + Http = new HttpNamespace(this); Snapshot = new SnapshotNamespace(this); Tasks = new TasksNamespace(this); } diff --git a/src/OpenSearch.Client/_Generated/Requests.Http.cs b/src/OpenSearch.Client/_Generated/Requests.Http.cs new file mode 100644 index 0000000000..2565cc1210 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/Requests.Http.cs @@ -0,0 +1,101 @@ +/* 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. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// This file is automatically generated +// Please do not edit these files manually +// Run the following in the root of the repos: +// +// *NIX : ./build.sh codegen +// Windows : build.bat codegen +// +// ----------------------------------------------- + +using OpenSearch.Net.Specification.HttpApi; +using OpenSearch.Net.Utf8Json; + +namespace OpenSearch.Client; + +public interface IHttpDeleteRequest : IArbitraryHttpRequest { } + +public class HttpDeleteRequest + : ArbitraryHttpRequestBase, + IHttpDeleteRequest +{ + [SerializationConstructor] + protected HttpDeleteRequest() { } + + public HttpDeleteRequest(string path) + : base(path) { } +} + +public interface IHttpGetRequest : IArbitraryHttpRequest { } + +public class HttpGetRequest : ArbitraryHttpRequestBase, IHttpGetRequest +{ + [SerializationConstructor] + protected HttpGetRequest() { } + + public HttpGetRequest(string path) + : base(path) { } +} + +public interface IHttpHeadRequest : IArbitraryHttpRequest { } + +public class HttpHeadRequest : ArbitraryHttpRequestBase, IHttpHeadRequest +{ + [SerializationConstructor] + protected HttpHeadRequest() { } + + public HttpHeadRequest(string path) + : base(path) { } +} + +public interface IHttpPatchRequest : IArbitraryBodyHttpRequest { } + +public class HttpPatchRequest + : ArbitraryBodyHttpRequestBase, + IHttpPatchRequest +{ + [SerializationConstructor] + protected HttpPatchRequest() { } + + public HttpPatchRequest(string path) + : base(path) { } +} + +public interface IHttpPostRequest : IArbitraryBodyHttpRequest { } + +public class HttpPostRequest + : ArbitraryBodyHttpRequestBase, + IHttpPostRequest +{ + [SerializationConstructor] + protected HttpPostRequest() { } + + public HttpPostRequest(string path) + : base(path) { } +} + +public interface IHttpPutRequest : IArbitraryBodyHttpRequest { } + +public class HttpPutRequest + : ArbitraryBodyHttpRequestBase, + IHttpPutRequest +{ + [SerializationConstructor] + protected HttpPutRequest() { } + + public HttpPutRequest(string path) + : base(path) { } +} diff --git a/src/OpenSearch.Client/_Generated/Requests.cs b/src/OpenSearch.Client/_Generated/Requests.cs index df4087c669..2c386704aa 100644 --- a/src/OpenSearch.Client/_Generated/Requests.cs +++ b/src/OpenSearch.Client/_Generated/Requests.cs @@ -51,6 +51,7 @@ using OpenSearch.Net; using OpenSearch.Net.Specification.ClusterApi; using OpenSearch.Net.Specification.DanglingIndicesApi; +using OpenSearch.Net.Specification.HttpApi; using OpenSearch.Net.Specification.IndicesApi; using OpenSearch.Net.Specification.IngestApi; using OpenSearch.Net.Specification.NodesApi; diff --git a/src/OpenSearch.Net/Connection/HttpMethod.cs b/src/OpenSearch.Net/Connection/HttpMethod.cs index 5f4d6fa467..3b3cb05b38 100644 --- a/src/OpenSearch.Net/Connection/HttpMethod.cs +++ b/src/OpenSearch.Net/Connection/HttpMethod.cs @@ -26,27 +26,30 @@ * under the License. */ +using System; using System.Runtime.Serialization; // ReSharper disable InconsistentNaming -namespace OpenSearch.Net +namespace OpenSearch.Net; + +public enum HttpMethod { - public enum HttpMethod - { - [EnumMember(Value = "GET")] - GET, + [EnumMember(Value = "GET")] + GET, + + [EnumMember(Value = "POST")] + POST, - [EnumMember(Value = "POST")] - POST, + [EnumMember(Value = "PUT")] + PUT, - [EnumMember(Value = "PUT")] - PUT, + [EnumMember(Value = "DELETE")] + DELETE, - [EnumMember(Value = "DELETE")] - DELETE, + [EnumMember(Value = "HEAD")] + HEAD, - [EnumMember(Value = "HEAD")] - HEAD - } + [EnumMember(Value = "PATCH")] + PATCH } diff --git a/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Http.cs b/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Http.cs new file mode 100644 index 0000000000..fff7192bc3 --- /dev/null +++ b/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Http.cs @@ -0,0 +1,76 @@ +/* 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. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// This file is automatically generated +// Please do not edit these files manually +// Run the following in the root of the repos: +// +// *NIX : ./build.sh codegen +// Windows : build.bat codegen +// +// ----------------------------------------------- + +using OpenSearch.Net; + +namespace OpenSearch.Net.Specification.HttpApi; + +public abstract class ArbitraryHttpRequestParameters : RequestParameters + where TSelf : ArbitraryHttpRequestParameters +{ + protected ArbitraryHttpRequestParameters(HttpMethod method, bool supportsBody) + { + DefaultHttpMethod = method; + SupportsBody = supportsBody; + } + + public override HttpMethod DefaultHttpMethod { get; } + public override bool SupportsBody { get; } +} + +public class HttpDeleteRequestParameters + : ArbitraryHttpRequestParameters +{ + public HttpDeleteRequestParameters() + : base(HttpMethod.DELETE, false) { } +} + +public class HttpGetRequestParameters : ArbitraryHttpRequestParameters +{ + public HttpGetRequestParameters() + : base(HttpMethod.GET, false) { } +} + +public class HttpHeadRequestParameters : ArbitraryHttpRequestParameters +{ + public HttpHeadRequestParameters() + : base(HttpMethod.HEAD, false) { } +} + +public class HttpPatchRequestParameters : ArbitraryHttpRequestParameters +{ + public HttpPatchRequestParameters() + : base(HttpMethod.PATCH, true) { } +} + +public class HttpPostRequestParameters : ArbitraryHttpRequestParameters +{ + public HttpPostRequestParameters() + : base(HttpMethod.POST, true) { } +} + +public class HttpPutRequestParameters : ArbitraryHttpRequestParameters +{ + public HttpPutRequestParameters() + : base(HttpMethod.PUT, true) { } +} diff --git a/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs b/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs index 1c6459e465..8d7f5692b3 100644 --- a/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs +++ b/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs @@ -52,6 +52,7 @@ using OpenSearch.Net; using OpenSearch.Net.Specification.ClusterApi; using OpenSearch.Net.Specification.DanglingIndicesApi; +using OpenSearch.Net.Specification.HttpApi; using OpenSearch.Net.Specification.IndicesApi; using OpenSearch.Net.Specification.IngestApi; using OpenSearch.Net.Specification.NodesApi; @@ -80,6 +81,15 @@ public partial interface IOpenSearchLowLevelClient /// Nodes APIs LowLevelNodesNamespace Nodes { get; } + /// Http APIs + LowLevelHttpNamespace Http { get; } + + /// Snapshot APIs + LowLevelSnapshotNamespace Snapshot { get; } + + /// Tasks APIs + LowLevelTasksNamespace Tasks { get; } + /// POST on /{index}/_search/point_in_time https://opensearch.org/docs/latest/search-plugins/point-in-time-api/#create-a-pit /// Comma-separated list of indices; use the special string `_all` or Indices.All to perform the operation on all indices. /// Request specific configuration such as querystring parameters & request specific connection settings. @@ -151,11 +161,5 @@ Task GetAllPitsAsync( CancellationToken ctx = default ) where TResponse : class, IOpenSearchResponse, new(); - - /// Snapshot APIs - LowLevelSnapshotNamespace Snapshot { get; } - - /// Tasks APIs - LowLevelTasksNamespace Tasks { get; } } } diff --git a/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Http.cs b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Http.cs new file mode 100644 index 0000000000..262e989875 --- /dev/null +++ b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Http.cs @@ -0,0 +1,223 @@ +/* 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. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// This file is automatically generated +// Please do not edit these files manually +// Run the following in the root of the repos: +// +// *NIX : ./build.sh codegen +// Windows : build.bat codegen +// +// ----------------------------------------------- + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenSearch.Net.Specification.HttpApi; + +/// +/// Http APIs. +/// Not intended to be instantiated directly. Use the property +/// on . +/// +/// +public class LowLevelHttpNamespace : NamespacedClientProxy +{ + internal LowLevelHttpNamespace(OpenSearchLowLevelClient client) + : base(client) { } + + public TResponse Delete( + FormattableString path, + HttpDeleteRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Delete(Url(path), parameters); + + public Task DeleteAsync( + FormattableString path, + HttpDeleteRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DeleteAsync(Url(path), parameters, ctx); + + public TResponse Delete(string path, HttpDeleteRequestParameters parameters = null) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.DELETE, path, null, RequestParams(parameters)); + + public Task DeleteAsync( + string path, + HttpDeleteRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.DELETE, path, ctx, null, RequestParams(parameters)); + + public TResponse Get( + FormattableString path, + HttpGetRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Get(Url(path), parameters); + + public Task GetAsync( + FormattableString path, + HttpGetRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + GetAsync(Url(path), parameters, ctx); + + public TResponse Get(string path, HttpGetRequestParameters parameters = null) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.GET, path, null, RequestParams(parameters)); + + public Task GetAsync( + string path, + HttpGetRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.GET, path, ctx, null, RequestParams(parameters)); + + public TResponse Head( + FormattableString path, + HttpHeadRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Head(Url(path), parameters); + + public Task HeadAsync( + FormattableString path, + HttpHeadRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + HeadAsync(Url(path), parameters, ctx); + + public TResponse Head(string path, HttpHeadRequestParameters parameters = null) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.HEAD, path, null, RequestParams(parameters)); + + public Task HeadAsync( + string path, + HttpHeadRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.HEAD, path, ctx, null, RequestParams(parameters)); + + public TResponse Patch( + FormattableString path, + PostData body = null, + HttpPatchRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Patch(Url(path), body, parameters); + + public Task PatchAsync( + FormattableString path, + PostData body = null, + HttpPatchRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PatchAsync(Url(path), body, parameters, ctx); + + public TResponse Patch( + string path, + PostData body = null, + HttpPatchRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.PATCH, path, body, RequestParams(parameters)); + + public Task PatchAsync( + string path, + PostData body = null, + HttpPatchRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.PATCH, path, ctx, body, RequestParams(parameters)); + + public TResponse Post( + FormattableString path, + PostData body = null, + HttpPostRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Post(Url(path), body, parameters); + + public Task PostAsync( + FormattableString path, + PostData body = null, + HttpPostRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PostAsync(Url(path), body, parameters, ctx); + + public TResponse Post( + string path, + PostData body = null, + HttpPostRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.POST, path, body, RequestParams(parameters)); + + public Task PostAsync( + string path, + PostData body = null, + HttpPostRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.POST, path, ctx, body, RequestParams(parameters)); + + public TResponse Put( + FormattableString path, + PostData body = null, + HttpPutRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + Put(Url(path), body, parameters); + + public Task PutAsync( + FormattableString path, + PostData body = null, + HttpPutRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + PutAsync(Url(path), body, parameters, ctx); + + public TResponse Put( + string path, + PostData body = null, + HttpPutRequestParameters parameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(HttpMethod.PUT, path, body, RequestParams(parameters)); + + public Task PutAsync( + string path, + PostData body = null, + HttpPutRequestParameters parameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync(HttpMethod.PUT, path, ctx, body, RequestParams(parameters)); +} diff --git a/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs index 734baabf4a..3b60d35f12 100644 --- a/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs +++ b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs @@ -52,6 +52,7 @@ using OpenSearch.Net; using OpenSearch.Net.Specification.ClusterApi; using OpenSearch.Net.Specification.DanglingIndicesApi; +using OpenSearch.Net.Specification.HttpApi; using OpenSearch.Net.Specification.IndicesApi; using OpenSearch.Net.Specification.IngestApi; using OpenSearch.Net.Specification.NodesApi; @@ -73,6 +74,7 @@ public partial class OpenSearchLowLevelClient : IOpenSearchLowLevelClient public LowLevelIndicesNamespace Indices { get; private set; } public LowLevelIngestNamespace Ingest { get; private set; } public LowLevelNodesNamespace Nodes { get; private set; } + public LowLevelHttpNamespace Http { get; private set; } public LowLevelSnapshotNamespace Snapshot { get; private set; } public LowLevelTasksNamespace Tasks { get; private set; } @@ -83,6 +85,7 @@ partial void SetupGeneratedNamespaces() Indices = new LowLevelIndicesNamespace(this); Ingest = new LowLevelIngestNamespace(this); Nodes = new LowLevelNodesNamespace(this); + Http = new LowLevelHttpNamespace(this); Snapshot = new LowLevelSnapshotNamespace(this); Tasks = new LowLevelTasksNamespace(this); } diff --git a/tests/Tests/CodeStandards/NamingConventions.doc.cs b/tests/Tests/CodeStandards/NamingConventions.doc.cs index 9dcb6fcb9e..8e877c204a 100644 --- a/tests/Tests/CodeStandards/NamingConventions.doc.cs +++ b/tests/Tests/CodeStandards/NamingConventions.doc.cs @@ -133,6 +133,13 @@ public void ParityBetweenRequestsAndResponses() //TODO MAP THIS //typeof(RankEvalRequest), //TODO add unit tests that we have no requests starting with Exists + typeof(HttpDeleteRequest), + typeof(HttpGetRequest), + typeof(HttpHeadRequest), + typeof(HttpPatchRequest), + typeof(HttpPostRequest), + typeof(HttpPutRequest), + typeof(SourceExistsRequest), typeof(SourceExistsRequest<>), typeof(DocumentExistsRequest),