From 2f73247d522cca8e9b4f7c626a90d0e1b12e6cdd Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 18:28:43 +1300 Subject: [PATCH 01/16] Allow renaming URL path parts in generator Signed-off-by: Thomas Farr --- .../Overrides/EndpointOverridesBase.cs | 2 + .../Overrides/GlobalOverrides.cs | 6 +- .../Overrides/IEndpointOverrides.cs | 7 +- ...cher.cs => ApiRequestParametersPatcher.cs} | 63 ++++++++------ .../Domain/Specification/UrlPath.cs | 2 +- .../Generator/ApiEndpointFactory.cs | 82 +++++++++---------- src/ApiGenerator/Views/LowLevel/Enums.cshtml | 15 ++-- 7 files changed, 97 insertions(+), 80 deletions(-) rename src/ApiGenerator/Domain/{ApiQueryParametersPatcher.cs => ApiRequestParametersPatcher.cs} (71%) diff --git a/src/ApiGenerator/Configuration/Overrides/EndpointOverridesBase.cs b/src/ApiGenerator/Configuration/Overrides/EndpointOverridesBase.cs index d7066a7dc1..db2f891293 100644 --- a/src/ApiGenerator/Configuration/Overrides/EndpointOverridesBase.cs +++ b/src/ApiGenerator/Configuration/Overrides/EndpointOverridesBase.cs @@ -33,6 +33,8 @@ namespace ApiGenerator.Configuration.Overrides { public abstract class EndpointOverridesBase : IEndpointOverrides { + public virtual IDictionary RenameUrlParts { get; } = new SortedDictionary(); + public virtual IDictionary ObsoleteQueryStringParams { get; set; } = new SortedDictionary(); public virtual IDictionary RenameQueryStringParams { get; } = new SortedDictionary(); diff --git a/src/ApiGenerator/Configuration/Overrides/GlobalOverrides.cs b/src/ApiGenerator/Configuration/Overrides/GlobalOverrides.cs index 9cda96e15d..22fa44eb5e 100644 --- a/src/ApiGenerator/Configuration/Overrides/GlobalOverrides.cs +++ b/src/ApiGenerator/Configuration/Overrides/GlobalOverrides.cs @@ -31,7 +31,11 @@ namespace ApiGenerator.Configuration.Overrides { public class GlobalOverrides : EndpointOverridesBase - { + { + public static readonly GlobalOverrides Instance = new(); + + private GlobalOverrides() { } + public IDictionary> ObsoleteEnumMembers { get; set; } = new Dictionary>() { { "VersionType", new Dictionary() { { "force", "Force is no longer accepted by the server as of 7.5.0 and will result in an error when used" } } } diff --git a/src/ApiGenerator/Configuration/Overrides/IEndpointOverrides.cs b/src/ApiGenerator/Configuration/Overrides/IEndpointOverrides.cs index 5c5838638a..82946907db 100644 --- a/src/ApiGenerator/Configuration/Overrides/IEndpointOverrides.cs +++ b/src/ApiGenerator/Configuration/Overrides/IEndpointOverrides.cs @@ -35,10 +35,15 @@ namespace ApiGenerator.Configuration.Overrides /// public interface IEndpointOverrides { + /// + /// Override how the url part is exposed to the client. + /// + IDictionary RenameUrlParts { get; } + /// /// A map of key -> obsolete message for properties in the spec that should not be used any longer /// - IDictionary ObsoleteQueryStringParams { get; set; } + IDictionary ObsoleteQueryStringParams { get; } /// /// Override how the query param name is exposed to the client. diff --git a/src/ApiGenerator/Domain/ApiQueryParametersPatcher.cs b/src/ApiGenerator/Domain/ApiRequestParametersPatcher.cs similarity index 71% rename from src/ApiGenerator/Domain/ApiQueryParametersPatcher.cs rename to src/ApiGenerator/Domain/ApiRequestParametersPatcher.cs index d5757a3a23..e4be8819ac 100644 --- a/src/ApiGenerator/Domain/ApiQueryParametersPatcher.cs +++ b/src/ApiGenerator/Domain/ApiRequestParametersPatcher.cs @@ -34,23 +34,37 @@ namespace ApiGenerator.Domain { - public static class ApiQueryParametersPatcher + public static class ApiRequestParametersPatcher { - public static SortedDictionary Patch( + public static void PatchUrlPaths(string endpointName, IList source, IEndpointOverrides overrides) + { + var declaredKeys = source.SelectMany(p => p.Parts).Select(p => p.Name).ToHashSet(); + var renameLookup = CreateUrlPartRenameLookup(overrides, declaredKeys); + + foreach (var path in source) + { + foreach (var part in path.Parts) + { + if (!renameLookup.TryGetValue(part.Name, out var newName)) continue; + + path.Path = path.Path.Replace($"{{{part.Name}}}", $"{{{newName}}}"); + part.Name = newName; + } + } + } + + public static SortedDictionary PatchQueryParameters( string endpointName, IDictionary source, IEndpointOverrides overrides ) { - if (source == null) return null; - - var globalOverrides = new GlobalOverrides(); var declaredKeys = source.Keys; - var skipList = CreateSkipList(globalOverrides, overrides, declaredKeys); - var partialList = CreatePartialList(globalOverrides, overrides, declaredKeys); + var skipList = CreateSkipList(overrides, declaredKeys); + var partialList = CreatePartialList(overrides, declaredKeys); - var renameLookup = CreateRenameLookup(globalOverrides, overrides, declaredKeys); - var obsoleteLookup = CreateObsoleteLookup(globalOverrides, overrides, declaredKeys); + var renameLookup = CreateRenameLookup(overrides, declaredKeys); + var obsoleteLookup = CreateObsoleteLookup(overrides, declaredKeys); var patchedParams = new SortedDictionary(); foreach (var (queryStringKey, value) in source) @@ -96,18 +110,18 @@ private static string CreateCSharpName(string queryStringKey, string endpointNam } } - private static IList CreateSkipList(IEndpointOverrides global, IEndpointOverrides local, ICollection declaredKeys) => - CreateList(global, local, "skip", e => e.SkipQueryStringParams, declaredKeys); + private static IList CreateSkipList(IEndpointOverrides local, ICollection declaredKeys) => + CreateList(local, "skip", e => e.SkipQueryStringParams, declaredKeys); - private static IList CreatePartialList(IEndpointOverrides global, IEndpointOverrides local, ICollection declaredKeys) => - CreateList(global, local, "partial", e => e.RenderPartial, declaredKeys); + private static IList CreatePartialList(IEndpointOverrides local, ICollection declaredKeys) => + CreateList(local, "partial", e => e.RenderPartial, declaredKeys); - private static IDictionary CreateLookup(IEndpointOverrides global, IEndpointOverrides local, string type, + private static IDictionary CreateLookup(IEndpointOverrides local, string type, Func> @from, ICollection declaredKeys ) { var d = new SortedDictionary(); - foreach (var kv in from(global)) d[kv.Key] = kv.Value; + foreach (var kv in from(GlobalOverrides.Instance)) d[kv.Key] = kv.Value; if (local == null) return d; @@ -121,12 +135,12 @@ Func> @from, ICollection return d; } - private static IList CreateList(IEndpointOverrides global, IEndpointOverrides local, string type, + private static IList CreateList(IEndpointOverrides local, string type, Func> @from, ICollection declaredKeys ) { var list = new List(); - if (global != null) list.AddRange(from(global)); + list.AddRange(from(GlobalOverrides.Instance)); if (local != null) { var localList = from(local).ToList(); @@ -138,14 +152,13 @@ Func> @from, ICollection declare return list.Distinct().ToList(); } - private static IDictionary CreateRenameLookup(IEndpointOverrides global, IEndpointOverrides local, - ICollection declaredKeys - ) => - CreateLookup(global, local, "rename", e => e.RenameQueryStringParams, declaredKeys); + private static IDictionary CreateUrlPartRenameLookup(IEndpointOverrides local, ICollection declaredKeys) => + CreateLookup(local, "url_part_rename", e => e.RenameUrlParts, declaredKeys); + + private static IDictionary CreateRenameLookup(IEndpointOverrides local, ICollection declaredKeys) => + CreateLookup(local, "rename", e => e.RenameQueryStringParams, declaredKeys); - private static IDictionary CreateObsoleteLookup(IEndpointOverrides global, IEndpointOverrides local, - ICollection declaredKeys - ) => - CreateLookup(global, local, "obsolete", e => e.ObsoleteQueryStringParams, declaredKeys); + private static IDictionary CreateObsoleteLookup(IEndpointOverrides local, ICollection declaredKeys) => + CreateLookup(local, "obsolete", e => e.ObsoleteQueryStringParams, declaredKeys); } } diff --git a/src/ApiGenerator/Domain/Specification/UrlPath.cs b/src/ApiGenerator/Domain/Specification/UrlPath.cs index 63f215ea07..7d77290b07 100644 --- a/src/ApiGenerator/Domain/Specification/UrlPath.cs +++ b/src/ApiGenerator/Domain/Specification/UrlPath.cs @@ -35,7 +35,7 @@ namespace ApiGenerator.Domain.Specification public class UrlPath { private readonly IList _additionalPartsForConstructor; - public string Path { get; } + public string Path { get; set; } public Deprecation Deprecation { get; } public Version VersionAdded { get; } public IList Parts { get; } diff --git a/src/ApiGenerator/Generator/ApiEndpointFactory.cs b/src/ApiGenerator/Generator/ApiEndpointFactory.cs index f7827792c5..bb6915f39f 100644 --- a/src/ApiGenerator/Generator/ApiEndpointFactory.cs +++ b/src/ApiGenerator/Generator/ApiEndpointFactory.cs @@ -28,10 +28,8 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; using System.Net.Mime; -using System.Text.RegularExpressions; using ApiGenerator.Configuration; using ApiGenerator.Configuration.Overrides; using ApiGenerator.Domain; @@ -40,7 +38,6 @@ using NJsonSchema; using NJsonSchema.References; using NSwag; -using SemanticVersioning; using Version = SemanticVersioning.Version; namespace ApiGenerator.Generator @@ -52,6 +49,8 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt var tokens = name.Split("."); var methodName = tokens[^1]; var ns = tokens.Length > 1 ? tokens[0] : null; + var names = new CsharpNames(name, methodName, ns); + var overrides = LoadOverrides(name, names.MethodName); HashSet requiredPathParts = null; var allParts = new Dictionary(); @@ -126,6 +125,9 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt .Where(p => !canonicalPaths.ContainsKey(p.Key)) .Select(p => p.Value)) .ToList(); + + ApiRequestParametersPatcher.PatchUrlPaths(name, paths, overrides); + paths.Sort((p1, p2) => p1.Parts .Zip(p2.Parts) .Select(t => string.Compare(t.First.Name, t.Second.Name, StringComparison.Ordinal)) @@ -151,58 +153,52 @@ public static ApiEndpoint From(string name, List<(string HttpPath, OpenApiPathIt foreach (var partName in requiredPathParts ?? Enumerable.Empty()) allParts[partName].Required = true; - var endpoint = new ApiEndpoint - { - Name = name, - Namespace = ns, - MethodName = methodName, - CsharpNames = new CsharpNames(name, methodName, ns), - Stability = Stability.Stable, // TODO: for realsies - OfficialDocumentationLink = new Documentation - { - Description = variants[0].Operation.Description, - Url = variants[0].Operation.ExternalDocumentation?.Url - }, - Url = new UrlInformation + IDictionary queryParams = variants.SelectMany(v => v.Path.Parameters.Concat(v.Operation.Parameters)) + .Where(p => p.Kind == OpenApiParameterKind.Query) + .DistinctBy(p => p.Name) + .ToDictionary(p => p.Name, BuildQueryParam); + queryParams = ApiRequestParametersPatcher.PatchQueryParameters(name, queryParams, overrides); + + return new ApiEndpoint + { + Name = name, + Namespace = ns, + MethodName = methodName, + CsharpNames = names, + Overrides = overrides, + Stability = Stability.Stable, // TODO: for realsies + OfficialDocumentationLink = new Documentation + { + Description = variants[0].Operation.Description, + Url = variants[0].Operation.ExternalDocumentation?.Url + }, + Url = new UrlInformation { AllPaths = paths, - Params = variants.SelectMany(v => v.Path.Parameters.Concat(v.Operation.Parameters)) - .Where(p => p.Kind == OpenApiParameterKind.Query) - .DistinctBy(p => p.Name) - .ToImmutableSortedDictionary(p => p.Name, BuildQueryParam) + Params = queryParams }, - Body = variants + Body = variants .Select(v => v.Operation.RequestBody) .FirstOrDefault(b => b != null) is { } reqBody ? new Body { Description = GetDescription(reqBody), Required = reqBody.IsRequired } : null, - HttpMethods = variants.Select(v => v.HttpMethod.ToString().ToUpper()).Distinct().ToList(), - }; - - LoadOverridesOnEndpoint(endpoint); - PatchRequestParameters(endpoint); - - return endpoint; + HttpMethods = variants.Select(v => v.HttpMethod.ToString().ToUpper()).Distinct().ToList(), + }; } - private static void LoadOverridesOnEndpoint(ApiEndpoint endpoint) + private static IEndpointOverrides LoadOverrides(string endpointName, string methodName) { - var method = endpoint.CsharpNames.MethodName; - if (CodeConfiguration.ApiNameMapping.TryGetValue(endpoint.Name, out var mapsApiMethodName)) - method = mapsApiMethodName; + if (CodeConfiguration.ApiNameMapping.TryGetValue(endpointName, out var mapsApiMethodName)) + methodName = mapsApiMethodName; var namespacePrefix = $"{typeof(GlobalOverrides).Namespace}.Endpoints."; - var typeName = $"{namespacePrefix}{method}Overrides"; + var typeName = $"{namespacePrefix}{methodName}Overrides"; var type = GeneratorLocations.Assembly.GetType(typeName); - if (type != null && Activator.CreateInstance(type) is IEndpointOverrides overrides) - endpoint.Overrides = overrides; - } - private static void PatchRequestParameters(ApiEndpoint endpoint) => - endpoint.Url.Params = ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides) - ?? throw new ArgumentNullException("ApiQueryParametersPatcher.Patch(endpoint.Name, endpoint.Url.Params, endpoint.Overrides)"); + return type != null && Activator.CreateInstance(type) is IEndpointOverrides overrides ? overrides : null; + } - private static QueryParameters BuildQueryParam(OpenApiParameter p) + private static QueryParameters BuildQueryParam(OpenApiParameter p) { var param = new QueryParameters { @@ -214,11 +210,9 @@ private static QueryParameters BuildQueryParam(OpenApiParameter p) }; if (param.Type == "enum" && p.Schema.HasReference) - { - param.ClsName = ((IJsonReference)p.Schema).ReferencePath.Split('/').Last(); - } + param.ClsName = ((IJsonReference)p.Schema).ReferencePath.Split('/').Last(); - return param; + return param; } private static string GetOpenSearchType(JsonSchema schema) diff --git a/src/ApiGenerator/Views/LowLevel/Enums.cshtml b/src/ApiGenerator/Views/LowLevel/Enums.cshtml index 30ba1f0109..5bb81aa7c1 100644 --- a/src/ApiGenerator/Views/LowLevel/Enums.cshtml +++ b/src/ApiGenerator/Views/LowLevel/Enums.cshtml @@ -8,13 +8,12 @@ @functions { private const string RawSize = "Raw"; private const string SizeEnum = "Size"; - private static GlobalOverrides GlobalOverrides = new GlobalOverrides(); private string CreateEnum(string enumName, string value, int? i) { var enumValue = (enumName == SizeEnum && value == string.Empty) ? RawSize : value.ToPascalCase(true); var enumCsharp = string.Format("[EnumMember(Value = \"{0}\")] {1}{2}", value, enumValue, i.HasValue ? " = 1 << " + i.Value : null); - if (GlobalOverrides.ObsoleteEnumMembers.TryGetValue(enumName, out var d) && d.TryGetValue(value, out var obsolete)) + if (GlobalOverrides.Instance.ObsoleteEnumMembers.TryGetValue(enumName, out var d) && d.TryGetValue(value, out var obsolete)) { return string.Format("[Obsolete(\"{0}\")]{2}\t\t{1}", obsolete, enumCsharp, Environment.NewLine); } @@ -23,7 +22,7 @@ private string CreateCase(string e, string o) { var enumValue = GetEnumValue(e, o); - var isObsolete = GlobalOverrides.ObsoleteEnumMembers.TryGetValue(e, out var d) && d.TryGetValue(o, out _); + var isObsolete = GlobalOverrides.Instance.ObsoleteEnumMembers.TryGetValue(e, out var d) && d.TryGetValue(o, out _); var sb = new StringBuilder(); if (isObsolete) sb.AppendLine("#pragma warning disable 618"); sb.Append(string.Format("case {0}.{1}: return \"{2}\";", e, enumValue, o)); @@ -37,8 +36,8 @@ private string GetEnumValue(string enumName, string value) { - return enumName == SizeEnum && value == string.Empty - ? RawSize + return enumName == SizeEnum && value == string.Empty + ? RawSize : value.ToPascalCase(true); } } @@ -91,7 +90,7 @@ namespace OpenSearch.Net } var list = new @(Raw("List()")); - var g = GlobalOverrides.ObsoleteEnumMembers.TryGetValue(e.Name, out var d); + var g = GlobalOverrides.Instance.ObsoleteEnumMembers.TryGetValue(e.Name, out var d); foreach (var option in e.Options.Where(o => o != "_all")) { var value = GetEnumValue(e.Name, option); @@ -99,12 +98,12 @@ namespace OpenSearch.Net #pragma warning disable 618 if ((enumValue & @(e.Name).@(value)) != 0) list.Add("@(option)"); #pragma warning restore 618 - + } else { if ((enumValue & @(e.Name).@(value)) != 0) list.Add("@(option)"); - } + } } return string.Join(",", list); } From c7853274c48be83b7c3d17eeaa01724380a24fd2 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 18:38:44 +1300 Subject: [PATCH 02/16] Generate {delete,exists,get,put}_index_template as *ComposableTemplate Signed-off-by: Thomas Farr --- .../Configuration/CodeConfiguration.cs | 10 +- .../IOpenSearchClient.Generated.cs | 6 - .../OpenSearchClient.Indices.cs | 6 +- .../OpenSearchClient.NoNamespace.cs | 13 +- .../_Generated/ApiUrlsLookup.cs | 12 + .../_Generated/Descriptors.Indices.cs | 245 ++++++++++++++ .../_Generated/IOpenSearchClient.cs | 4 + .../_Generated/OpenSearchClient.Indices.cs | 310 ++++++++++++++++++ .../_Generated/OpenSearchClient.cs | 5 + .../_Generated/Requests.Indices.cs | 308 +++++++++++++++++ src/OpenSearch.Client/_Generated/Requests.cs | 1 + .../RequestParameters.Indices.cs | 65 ---- .../IOpenSearchLowLevelClient.Generated.cs | 6 - .../OpenSearchLowLevelClient.Indices.cs | 36 +- .../OpenSearchLowLevelClient.NoNamespace.cs | 12 +- .../RequestParameters.Indices.cs | 207 ++++++++++++ .../_Generated/IOpenSearchLowLevelClient.cs | 4 + .../OpenSearchLowLevelClient.Indices.cs | 232 +++++++++++++ .../_Generated/OpenSearchLowLevelClient.cs | 3 + 19 files changed, 1343 insertions(+), 142 deletions(-) create mode 100644 src/OpenSearch.Client/_Generated/Descriptors.Indices.cs create mode 100644 src/OpenSearch.Client/_Generated/OpenSearchClient.Indices.cs create mode 100644 src/OpenSearch.Client/_Generated/Requests.Indices.cs create mode 100644 src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Indices.cs create mode 100644 src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Indices.cs diff --git a/src/ApiGenerator/Configuration/CodeConfiguration.cs b/src/ApiGenerator/Configuration/CodeConfiguration.cs index beafe56cae..758473e7b7 100644 --- a/src/ApiGenerator/Configuration/CodeConfiguration.cs +++ b/src/ApiGenerator/Configuration/CodeConfiguration.cs @@ -51,6 +51,9 @@ public static class CodeConfiguration new("cluster.*_component_template"), new("dangling_indices.*"), + + new("indices.{delete,exists,get,put}_index_template"), + new("ingest.*"), new("nodes.*"), new("snapshot.*"), @@ -62,11 +65,8 @@ public static class CodeConfiguration /// /// Map API default names for API's we are only supporting on the low level client first /// - private static readonly Dictionary LowLevelApiNameMapping = new Dictionary - { - { "indices.delete_index_template", "DeleteIndexTemplateV2" }, - { "indices.get_index_template", "GetIndexTemplateV2" }, - { "indices.put_index_template", "PutIndexTemplateV2" } + private static readonly Dictionary LowLevelApiNameMapping = new() + { }; /// diff --git a/src/OpenSearch.Client/IOpenSearchClient.Generated.cs b/src/OpenSearch.Client/IOpenSearchClient.Generated.cs index c9cecbaad7..c582459651 100644 --- a/src/OpenSearch.Client/IOpenSearchClient.Generated.cs +++ b/src/OpenSearch.Client/IOpenSearchClient.Generated.cs @@ -70,12 +70,6 @@ CatNamespace Cat get; } - ///Indices APIs - IndicesNamespace Indices - { - get; - } - /// /// POST request to the bulk API, read more about this API online: /// diff --git a/src/OpenSearch.Client/OpenSearchClient.Indices.cs b/src/OpenSearch.Client/OpenSearchClient.Indices.cs index 609d79d558..df83a26136 100644 --- a/src/OpenSearch.Client/OpenSearchClient.Indices.cs +++ b/src/OpenSearch.Client/OpenSearchClient.Indices.cs @@ -57,12 +57,8 @@ namespace OpenSearch.Client.Specification.IndicesApi /// on . /// /// - public class IndicesNamespace : NamespacedClientProxy + public partial class IndicesNamespace : NamespacedClientProxy { - internal IndicesNamespace(OpenSearchClient client): base(client) - { - } - /// /// PUT request to the indices.add_block API, read more about this API online: /// diff --git a/src/OpenSearch.Client/OpenSearchClient.NoNamespace.cs b/src/OpenSearch.Client/OpenSearchClient.NoNamespace.cs index 7f268282a8..6d2d7b0f71 100644 --- a/src/OpenSearch.Client/OpenSearchClient.NoNamespace.cs +++ b/src/OpenSearch.Client/OpenSearchClient.NoNamespace.cs @@ -70,18 +70,7 @@ public CatNamespace Cat private set; } - ///Indices APIs - public IndicesNamespace Indices - { - get; - private set; - } - - partial void SetupNamespaces() - { - Cat = new CatNamespace(this); - Indices = new IndicesNamespace(this); - } + partial void SetupNamespaces() => Cat = new CatNamespace(this); /// /// POST request to the bulk API, read more about this API online: diff --git a/src/OpenSearch.Client/_Generated/ApiUrlsLookup.cs b/src/OpenSearch.Client/_Generated/ApiUrlsLookup.cs index b849882adf..311bb682e8 100644 --- a/src/OpenSearch.Client/_Generated/ApiUrlsLookup.cs +++ b/src/OpenSearch.Client/_Generated/ApiUrlsLookup.cs @@ -91,6 +91,18 @@ internal static partial class ApiUrlsLookups internal static readonly ApiUrls NoNamespaceGetAllPits = new(new[] { "_search/point_in_time/_all" }); + internal static readonly ApiUrls IndicesDeleteComposableTemplate = + new(new[] { "_index_template/{name}" }); + + internal static readonly ApiUrls IndicesComposableTemplateExists = + new(new[] { "_index_template/{name}" }); + + internal static readonly ApiUrls IndicesGetComposableTemplate = + new(new[] { "_index_template", "_index_template/{name}" }); + + internal static readonly ApiUrls IndicesPutComposableTemplate = + new(new[] { "_index_template/{name}" }); + internal static readonly ApiUrls IngestDeletePipeline = new(new[] { "_ingest/pipeline/{id}" }); diff --git a/src/OpenSearch.Client/_Generated/Descriptors.Indices.cs b/src/OpenSearch.Client/_Generated/Descriptors.Indices.cs new file mode 100644 index 0000000000..04abec4fc3 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/Descriptors.Indices.cs @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +* +* Licensed to Elasticsearch B.V. under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch B.V. licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// 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 +// +// ----------------------------------------------- +// ReSharper disable RedundantUsingDirective +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Linq.Expressions; + +using OpenSearch.Net; +using OpenSearch.Net.Utf8Json; +using OpenSearch.Net.Specification.IndicesApi; + +// ReSharper disable RedundantBaseConstructorCall +// ReSharper disable UnusedTypeParameter +// ReSharper disable PartialMethodWithSinglePart +// ReSharper disable RedundantNameQualifier +namespace OpenSearch.Client +{ + /// Descriptor for DeleteComposableTemplate https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + public partial class DeleteComposableIndexTemplateDescriptor + : RequestDescriptorBase< + DeleteComposableIndexTemplateDescriptor, + DeleteComposableIndexTemplateRequestParameters, + IDeleteComposableIndexTemplateRequest + >, + IDeleteComposableIndexTemplateRequest + { + internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesDeleteComposableTemplate; + + /// /_index_template/{name} + /// this parameter is required + public DeleteComposableIndexTemplateDescriptor(Name name) + : base(r => r.Required("name", name)) { } + + /// Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected DeleteComposableIndexTemplateDescriptor() + : base() { } + + // values part of the url path + Name IDeleteComposableIndexTemplateRequest.Name => Self.RouteValues.Get("name"); + + // Request parameters + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public DeleteComposableIndexTemplateDescriptor ClusterManagerTimeout( + Time clustermanagertimeout + ) => Qs("cluster_manager_timeout", clustermanagertimeout); + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public DeleteComposableIndexTemplateDescriptor MasterTimeout(Time mastertimeout) => + Qs("master_timeout", mastertimeout); + + /// Operation timeout. + public DeleteComposableIndexTemplateDescriptor Timeout(Time timeout) => + Qs("timeout", timeout); + } + + /// Descriptor for ComposableTemplateExists https://opensearch.org/docs/latest/im-plugin/index-templates/ + public partial class ComposableIndexTemplateExistsDescriptor + : RequestDescriptorBase< + ComposableIndexTemplateExistsDescriptor, + ComposableIndexTemplateExistsRequestParameters, + IComposableIndexTemplateExistsRequest + >, + IComposableIndexTemplateExistsRequest + { + internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesComposableTemplateExists; + + /// /_index_template/{name} + /// this parameter is required + public ComposableIndexTemplateExistsDescriptor(Name name) + : base(r => r.Required("name", name)) { } + + /// Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected ComposableIndexTemplateExistsDescriptor() + : base() { } + + // values part of the url path + Name IComposableIndexTemplateExistsRequest.Name => Self.RouteValues.Get("name"); + + // Request parameters + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public ComposableIndexTemplateExistsDescriptor ClusterManagerTimeout( + Time clustermanagertimeout + ) => Qs("cluster_manager_timeout", clustermanagertimeout); + + /// Return settings in flat format. + public ComposableIndexTemplateExistsDescriptor FlatSettings(bool? flatsettings = true) => + Qs("flat_settings", flatsettings); + + /// Return local information, do not retrieve the state from cluster-manager node. + public ComposableIndexTemplateExistsDescriptor Local(bool? local = true) => + Qs("local", local); + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public ComposableIndexTemplateExistsDescriptor MasterTimeout(Time mastertimeout) => + Qs("master_timeout", mastertimeout); + } + + /// Descriptor for GetComposableTemplate https://opensearch.org/docs/latest/im-plugin/index-templates/ + public partial class GetComposableIndexTemplateDescriptor + : RequestDescriptorBase< + GetComposableIndexTemplateDescriptor, + GetComposableIndexTemplateRequestParameters, + IGetComposableIndexTemplateRequest + >, + IGetComposableIndexTemplateRequest + { + internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesGetComposableTemplate; + + /// /_index_template + public GetComposableIndexTemplateDescriptor() + : base() { } + + /// /_index_template/{name} + /// Optional, accepts null + public GetComposableIndexTemplateDescriptor(Names name) + : base(r => r.Optional("name", name)) { } + + // values part of the url path + Names IGetComposableIndexTemplateRequest.Name => Self.RouteValues.Get("name"); + + /// Comma-separated names of the index templates. + public GetComposableIndexTemplateDescriptor Name(Names name) => + Assign(name, (a, v) => a.RouteValues.Optional("name", v)); + + // Request parameters + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public GetComposableIndexTemplateDescriptor ClusterManagerTimeout( + Time clustermanagertimeout + ) => Qs("cluster_manager_timeout", clustermanagertimeout); + + /// Return settings in flat format. + public GetComposableIndexTemplateDescriptor FlatSettings(bool? flatsettings = true) => + Qs("flat_settings", flatsettings); + + /// Return local information, do not retrieve the state from cluster-manager node. + public GetComposableIndexTemplateDescriptor Local(bool? local = true) => Qs("local", local); + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public GetComposableIndexTemplateDescriptor MasterTimeout(Time mastertimeout) => + Qs("master_timeout", mastertimeout); + } + + /// Descriptor for PutComposableTemplate + public partial class PutComposableIndexTemplateDescriptor + : RequestDescriptorBase< + PutComposableIndexTemplateDescriptor, + PutComposableIndexTemplateRequestParameters, + IPutComposableIndexTemplateRequest + >, + IPutComposableIndexTemplateRequest + { + internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesPutComposableTemplate; + + /// /_index_template/{name} + /// this parameter is required + public PutComposableIndexTemplateDescriptor(Name name) + : base(r => r.Required("name", name)) { } + + /// Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected PutComposableIndexTemplateDescriptor() + : base() { } + + // values part of the url path + Name IPutComposableIndexTemplateRequest.Name => Self.RouteValues.Get("name"); + + // Request parameters + /// User defined reason for creating/updating the index template. + public PutComposableIndexTemplateDescriptor Cause(string cause) => Qs("cause", cause); + + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public PutComposableIndexTemplateDescriptor ClusterManagerTimeout( + Time clustermanagertimeout + ) => Qs("cluster_manager_timeout", clustermanagertimeout); + + /// Whether the index template should only be added if new or can also replace an existing one. + public PutComposableIndexTemplateDescriptor Create(bool? create = true) => + Qs("create", create); + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public PutComposableIndexTemplateDescriptor MasterTimeout(Time mastertimeout) => + Qs("master_timeout", mastertimeout); + } +} diff --git a/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs b/src/OpenSearch.Client/_Generated/IOpenSearchClient.cs index 8fa9a0bccc..8df6226e31 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.IndicesApi; using OpenSearch.Client.Specification.IngestApi; using OpenSearch.Client.Specification.NodesApi; using OpenSearch.Client.Specification.SnapshotApi; @@ -68,6 +69,9 @@ public partial interface IOpenSearchClient /// Dangling Indices APIs DanglingIndicesNamespace DanglingIndices { get; } + /// Indices APIs + IndicesNamespace Indices { get; } + /// Ingest APIs IngestNamespace Ingest { get; } diff --git a/src/OpenSearch.Client/_Generated/OpenSearchClient.Indices.cs b/src/OpenSearch.Client/_Generated/OpenSearchClient.Indices.cs new file mode 100644 index 0000000000..624ce9d9b7 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/OpenSearchClient.Indices.cs @@ -0,0 +1,310 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +* +* Licensed to Elasticsearch B.V. under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch B.V. licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// 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 +// +// ----------------------------------------------- +// ReSharper disable RedundantUsingDirective +using System; +using System.Threading; +using System.Threading.Tasks; +using OpenSearch.Net.Specification.IndicesApi; + +// ReSharper disable once CheckNamespace +// ReSharper disable RedundantTypeArgumentsOfMethod +namespace OpenSearch.Client.Specification.IndicesApi +{ + /// + /// Indices APIs. + /// Not intended to be instantiated directly. Use the property + /// on . + /// + /// + public partial class IndicesNamespace : NamespacedClientProxy + { + internal IndicesNamespace(OpenSearchClient client) + : base(client) { } + + /// + /// DELETE request to the indices.delete_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// + public DeleteComposableIndexTemplateResponse DeleteComposableTemplate( + Name name, + Func< + DeleteComposableIndexTemplateDescriptor, + IDeleteComposableIndexTemplateRequest + > selector = null + ) => + DeleteComposableTemplate( + selector.InvokeOrDefault(new DeleteComposableIndexTemplateDescriptor(name: name)) + ); + + /// + /// DELETE request to the indices.delete_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// + public Task DeleteComposableTemplateAsync( + Name name, + Func< + DeleteComposableIndexTemplateDescriptor, + IDeleteComposableIndexTemplateRequest + > selector = null, + CancellationToken ct = default + ) => + DeleteComposableTemplateAsync( + selector.InvokeOrDefault(new DeleteComposableIndexTemplateDescriptor(name: name)), + ct + ); + + /// + /// DELETE request to the indices.delete_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// + public DeleteComposableIndexTemplateResponse DeleteComposableTemplate( + IDeleteComposableIndexTemplateRequest request + ) => + DoRequest( + request, + request.RequestParameters + ); + + /// + /// DELETE request to the indices.delete_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// + public Task DeleteComposableTemplateAsync( + IDeleteComposableIndexTemplateRequest request, + CancellationToken ct = default + ) => + DoRequestAsync< + IDeleteComposableIndexTemplateRequest, + DeleteComposableIndexTemplateResponse + >(request, request.RequestParameters, ct); + + /// + /// HEAD request to the indices.exists_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public ExistsResponse ComposableTemplateExists( + Name name, + Func< + ComposableIndexTemplateExistsDescriptor, + IComposableIndexTemplateExistsRequest + > selector = null + ) => + ComposableTemplateExists( + selector.InvokeOrDefault(new ComposableIndexTemplateExistsDescriptor(name: name)) + ); + + /// + /// HEAD request to the indices.exists_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public Task ComposableTemplateExistsAsync( + Name name, + Func< + ComposableIndexTemplateExistsDescriptor, + IComposableIndexTemplateExistsRequest + > selector = null, + CancellationToken ct = default + ) => + ComposableTemplateExistsAsync( + selector.InvokeOrDefault(new ComposableIndexTemplateExistsDescriptor(name: name)), + ct + ); + + /// + /// HEAD request to the indices.exists_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public ExistsResponse ComposableTemplateExists( + IComposableIndexTemplateExistsRequest request + ) => + DoRequest( + request, + request.RequestParameters + ); + + /// + /// HEAD request to the indices.exists_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public Task ComposableTemplateExistsAsync( + IComposableIndexTemplateExistsRequest request, + CancellationToken ct = default + ) => + DoRequestAsync( + request, + request.RequestParameters, + ct + ); + + /// + /// GET request to the indices.get_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public GetComposableIndexTemplateResponse GetComposableTemplate( + Names name = null, + Func< + GetComposableIndexTemplateDescriptor, + IGetComposableIndexTemplateRequest + > selector = null + ) => + GetComposableTemplate( + selector.InvokeOrDefault( + new GetComposableIndexTemplateDescriptor().Name(name: name) + ) + ); + + /// + /// GET request to the indices.get_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public Task GetComposableTemplateAsync( + Names name = null, + Func< + GetComposableIndexTemplateDescriptor, + IGetComposableIndexTemplateRequest + > selector = null, + CancellationToken ct = default + ) => + GetComposableTemplateAsync( + selector.InvokeOrDefault( + new GetComposableIndexTemplateDescriptor().Name(name: name) + ), + ct + ); + + /// + /// GET request to the indices.get_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public GetComposableIndexTemplateResponse GetComposableTemplate( + IGetComposableIndexTemplateRequest request + ) => + DoRequest( + request, + request.RequestParameters + ); + + /// + /// GET request to the indices.get_index_template API, read more about this API online: + /// + /// https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// + public Task GetComposableTemplateAsync( + IGetComposableIndexTemplateRequest request, + CancellationToken ct = default + ) => + DoRequestAsync( + request, + request.RequestParameters, + ct + ); + + /// + /// PUT request to the indices.put_index_template API, read more about this API online: + /// + /// + /// + public PutComposableIndexTemplateResponse PutComposableTemplate( + Name name, + Func selector + ) => + PutComposableTemplate( + selector.InvokeOrDefault(new PutComposableIndexTemplateDescriptor(name: name)) + ); + + /// + /// PUT request to the indices.put_index_template API, read more about this API online: + /// + /// + /// + public Task PutComposableTemplateAsync( + Name name, + Func selector, + CancellationToken ct = default + ) => + PutComposableTemplateAsync( + selector.InvokeOrDefault(new PutComposableIndexTemplateDescriptor(name: name)), + ct + ); + + /// + /// PUT request to the indices.put_index_template API, read more about this API online: + /// + /// + /// + public PutComposableIndexTemplateResponse PutComposableTemplate( + IPutComposableIndexTemplateRequest request + ) => + DoRequest( + request, + request.RequestParameters + ); + + /// + /// PUT request to the indices.put_index_template API, read more about this API online: + /// + /// + /// + public Task PutComposableTemplateAsync( + IPutComposableIndexTemplateRequest request, + CancellationToken ct = default + ) => + DoRequestAsync( + request, + request.RequestParameters, + ct + ); + } +} diff --git a/src/OpenSearch.Client/_Generated/OpenSearchClient.cs b/src/OpenSearch.Client/_Generated/OpenSearchClient.cs index 1d52dc3340..76a81b7772 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.IndicesApi; using OpenSearch.Client.Specification.IngestApi; using OpenSearch.Client.Specification.NodesApi; using OpenSearch.Client.Specification.SnapshotApi; @@ -67,6 +68,9 @@ public partial class OpenSearchClient : IOpenSearchClient /// Dangling Indices APIs public DanglingIndicesNamespace DanglingIndices { get; private set; } + /// Indices APIs + public IndicesNamespace Indices { get; private set; } + /// Ingest APIs public IngestNamespace Ingest { get; private set; } @@ -83,6 +87,7 @@ partial void SetupGeneratedNamespaces() { Cluster = new ClusterNamespace(this); DanglingIndices = new DanglingIndicesNamespace(this); + Indices = new IndicesNamespace(this); Ingest = new IngestNamespace(this); Nodes = new NodesNamespace(this); Snapshot = new SnapshotNamespace(this); diff --git a/src/OpenSearch.Client/_Generated/Requests.Indices.cs b/src/OpenSearch.Client/_Generated/Requests.Indices.cs new file mode 100644 index 0000000000..ec9e67a340 --- /dev/null +++ b/src/OpenSearch.Client/_Generated/Requests.Indices.cs @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +* +* Licensed to Elasticsearch B.V. under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch B.V. licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// 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 +// +// ----------------------------------------------- +// ReSharper disable RedundantUsingDirective +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Linq.Expressions; +using System.Runtime.Serialization; +using OpenSearch.Net; +using OpenSearch.Net.Utf8Json; +using OpenSearch.Net.Specification.IndicesApi; + +// ReSharper disable RedundantBaseConstructorCall +// ReSharper disable UnusedTypeParameter +// ReSharper disable PartialMethodWithSinglePart +// ReSharper disable RedundantNameQualifier +namespace OpenSearch.Client +{ + [InterfaceDataContract] + public partial interface IDeleteComposableIndexTemplateRequest + : IRequest + { + [IgnoreDataMember] + Name Name { get; } + } + + /// Request for DeleteComposableTemplate https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + public partial class DeleteComposableIndexTemplateRequest + : PlainRequestBase, + IDeleteComposableIndexTemplateRequest + { + protected IDeleteComposableIndexTemplateRequest Self => this; + internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesDeleteComposableTemplate; + + /// /_index_template/{name} + /// this parameter is required + public DeleteComposableIndexTemplateRequest(Name name) + : base(r => r.Required("name", name)) { } + + /// Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected DeleteComposableIndexTemplateRequest() + : base() { } + + // values part of the url path + [IgnoreDataMember] + Name IDeleteComposableIndexTemplateRequest.Name => Self.RouteValues.Get("name"); + + // Request parameters + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public Time ClusterManagerTimeout + { + get => Q public partial class LowLevelIndicesNamespace : NamespacedClientProxy { - internal LowLevelIndicesNamespace(OpenSearchLowLevelClient client): base(client) - { - } - ///PUT on /{index}/_block/{block} ///A comma separated list of indices to add a block to ///The block to add (one of read, write, read_only or metadata) @@ -190,17 +186,6 @@ public TResponse DeleteAlias(string index, string name, DeleteAliasRe [MapsApi("indices.delete_alias", "index, name")] public Task DeleteAliasAsync(string index, string name, DeleteAliasRequestParameters requestParameters = null, CancellationToken ctx = default) where TResponse : class, IOpenSearchResponse, new() => DoRequestAsync(DELETE, Url($"{index:index}/_alias/{name:name}"), ctx, null, RequestParams(requestParameters)); - ///DELETE on /_index_template/{name} https://opensearch.org/docs/latest/opensearch/rest-api/cat/cat-templates/ - ///The name of the template - ///Request specific configuration such as querystring parameters & request specific connection settings. - public TResponse DeleteTemplateV2ForAll(string name, DeleteIndexTemplateV2RequestParameters requestParameters = null) - where TResponse : class, IOpenSearchResponse, new() => DoRequest(DELETE, Url($"_index_template/{name:name}"), null, RequestParams(requestParameters)); - ///DELETE on /_index_template/{name} https://opensearch.org/docs/latest/opensearch/rest-api/cat/cat-templates/ - ///The name of the template - ///Request specific configuration such as querystring parameters & request specific connection settings. - [MapsApi("indices.delete_index_template", "name")] - public Task DeleteTemplateV2ForAllAsync(string name, DeleteIndexTemplateV2RequestParameters requestParameters = null, CancellationToken ctx = default) - where TResponse : class, IOpenSearchResponse, new() => DoRequestAsync(DELETE, Url($"_index_template/{name:name}"), ctx, null, RequestParams(requestParameters)); ///DELETE on /_template/{name} https://opensearch.org/docs/latest/opensearch/rest-api/cat/cat-templates/ ///The name of the template ///Request specific configuration such as querystring parameters & request specific connection settings. @@ -533,19 +518,6 @@ public TResponse PutAlias(string index, string name, PostData body, P [MapsApi("indices.put_alias", "index, name, body")] public Task PutAliasAsync(string index, string name, PostData body, PutAliasRequestParameters requestParameters = null, CancellationToken ctx = default) where TResponse : class, IOpenSearchResponse, new() => DoRequestAsync(PUT, Url($"{index:index}/_alias/{name:name}"), ctx, body, RequestParams(requestParameters)); - ///PUT on /_index_template/{name} https://opensearch.org/docs/latest/opensearch/rest-api/cat/cat-templates/ - ///The name of the template - ///The template definition - ///Request specific configuration such as querystring parameters & request specific connection settings. - public TResponse PutTemplateV2ForAll(string name, PostData body, PutIndexTemplateV2RequestParameters requestParameters = null) - where TResponse : class, IOpenSearchResponse, new() => DoRequest(PUT, Url($"_index_template/{name:name}"), body, RequestParams(requestParameters)); - ///PUT on /_index_template/{name} https://opensearch.org/docs/latest/opensearch/rest-api/cat/cat-templates/ - ///The name of the template - ///The template definition - ///Request specific configuration such as querystring parameters & request specific connection settings. - [MapsApi("indices.put_index_template", "name, body")] - public Task PutTemplateV2ForAllAsync(string name, PostData body, PutIndexTemplateV2RequestParameters requestParameters = null, CancellationToken ctx = default) - where TResponse : class, IOpenSearchResponse, new() => DoRequestAsync(PUT, Url($"_index_template/{name:name}"), ctx, body, RequestParams(requestParameters)); ///PUT on /{index}/_mapping https://opensearch.org/docs/latest/opensearch/rest-api/update-mapping/ ///A comma-separated list of index names the mapping should be added to (supports wildcards); use `_all` or omit to add the mapping on all indices. ///The mapping definition diff --git a/src/OpenSearch.Net/OpenSearchLowLevelClient.NoNamespace.cs b/src/OpenSearch.Net/OpenSearchLowLevelClient.NoNamespace.cs index 567e63a192..f8afe925cd 100644 --- a/src/OpenSearch.Net/OpenSearchLowLevelClient.NoNamespace.cs +++ b/src/OpenSearch.Net/OpenSearchLowLevelClient.NoNamespace.cs @@ -75,17 +75,7 @@ public LowLevelCatNamespace Cat private set; } - public LowLevelIndicesNamespace Indices - { - get; - private set; - } - - partial void SetupNamespaces() - { - Cat = new LowLevelCatNamespace(this); - Indices = new LowLevelIndicesNamespace(this); - } + partial void SetupNamespaces() => Cat = new LowLevelCatNamespace(this); ///POST on /_bulk https://opensearch.org/docs/latest/opensearch/rest-api/document-apis/bulk/ ///The operation definition and data (action-data pairs), separated by newlines diff --git a/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Indices.cs b/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Indices.cs new file mode 100644 index 0000000000..c5fbdc0f30 --- /dev/null +++ b/src/OpenSearch.Net/_Generated/Api/RequestParameters/RequestParameters.Indices.cs @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +* +* Licensed to Elasticsearch B.V. under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch B.V. licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// 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 +// +// ----------------------------------------------- + +// ReSharper disable RedundantUsingDirective +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Linq.Expressions; + +// ReSharper disable once CheckNamespace +namespace OpenSearch.Net.Specification.IndicesApi +{ + /// Request options for DeleteComposableTemplate https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + public partial class DeleteComposableIndexTemplateRequestParameters + : RequestParameters + { + public override HttpMethod DefaultHttpMethod => HttpMethod.DELETE; + public override bool SupportsBody => false; + + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public TimeSpan ClusterManagerTimeout + { + get => Q("cluster_manager_timeout"); + set => Q("cluster_manager_timeout", value); + } + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public TimeSpan MasterTimeout + { + get => Q("master_timeout"); + set => Q("master_timeout", value); + } + + /// Operation timeout. + public TimeSpan Timeout + { + get => Q("timeout"); + set => Q("timeout", value); + } + } + + /// Request options for ComposableTemplateExists https://opensearch.org/docs/latest/im-plugin/index-templates/ + public partial class ComposableIndexTemplateExistsRequestParameters + : RequestParameters + { + public override HttpMethod DefaultHttpMethod => HttpMethod.HEAD; + public override bool SupportsBody => false; + + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public TimeSpan ClusterManagerTimeout + { + get => Q("cluster_manager_timeout"); + set => Q("cluster_manager_timeout", value); + } + + /// Return settings in flat format. + public bool? FlatSettings + { + get => Q("flat_settings"); + set => Q("flat_settings", value); + } + + /// Return local information, do not retrieve the state from cluster-manager node. + public bool? Local + { + get => Q("local"); + set => Q("local", value); + } + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public TimeSpan MasterTimeout + { + get => Q("master_timeout"); + set => Q("master_timeout", value); + } + } + + /// Request options for GetComposableTemplate https://opensearch.org/docs/latest/im-plugin/index-templates/ + public partial class GetComposableIndexTemplateRequestParameters + : RequestParameters + { + public override HttpMethod DefaultHttpMethod => HttpMethod.GET; + public override bool SupportsBody => false; + + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public TimeSpan ClusterManagerTimeout + { + get => Q("cluster_manager_timeout"); + set => Q("cluster_manager_timeout", value); + } + + /// Return settings in flat format. + public bool? FlatSettings + { + get => Q("flat_settings"); + set => Q("flat_settings", value); + } + + /// Return local information, do not retrieve the state from cluster-manager node. + public bool? Local + { + get => Q("local"); + set => Q("local", value); + } + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public TimeSpan MasterTimeout + { + get => Q("master_timeout"); + set => Q("master_timeout", value); + } + } + + /// Request options for PutComposableTemplate + public partial class PutComposableIndexTemplateRequestParameters + : RequestParameters + { + public override HttpMethod DefaultHttpMethod => HttpMethod.PUT; + public override bool SupportsBody => true; + + /// User defined reason for creating/updating the index template. + public string Cause + { + get => Q("cause"); + set => Q("cause", value); + } + + /// Operation timeout for connection to cluster-manager node. + /// Supported by OpenSearch servers of version 2.0.0 or greater. + public TimeSpan ClusterManagerTimeout + { + get => Q("cluster_manager_timeout"); + set => Q("cluster_manager_timeout", value); + } + + /// Whether the index template should only be added if new or can also replace an existing one. + public bool? Create + { + get => Q("create"); + set => Q("create", value); + } + + /// Operation timeout for connection to master node. + [Obsolete( + "Deprecated as of: 2.0.0, reason: To promote inclusive language, use 'cluster_manager_timeout' instead." + )] + public TimeSpan MasterTimeout + { + get => Q("master_timeout"); + set => Q("master_timeout", value); + } + } +} diff --git a/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs b/src/OpenSearch.Net/_Generated/IOpenSearchLowLevelClient.cs index bbc04c7c32..1c6459e465 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.IndicesApi; using OpenSearch.Net.Specification.IngestApi; using OpenSearch.Net.Specification.NodesApi; using OpenSearch.Net.Specification.SnapshotApi; @@ -70,6 +71,9 @@ public partial interface IOpenSearchLowLevelClient /// Dangling Indices APIs LowLevelDanglingIndicesNamespace DanglingIndices { get; } + /// Indices APIs + LowLevelIndicesNamespace Indices { get; } + /// Ingest APIs LowLevelIngestNamespace Ingest { get; } diff --git a/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Indices.cs b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Indices.cs new file mode 100644 index 0000000000..a7cc63b02e --- /dev/null +++ b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.Indices.cs @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +*/ +/* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +* +* Licensed to Elasticsearch B.V. under one or more contributor +* license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright +* ownership. Elasticsearch B.V. licenses this file to you under +* the Apache License, Version 2.0 (the "License"); you may +* not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗ +// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝ +// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗ +// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝ +// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗ +// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ +// ----------------------------------------------- +// +// 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 +// +// ----------------------------------------------- +// ReSharper disable RedundantUsingDirective +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using OpenSearch.Net; +using static OpenSearch.Net.HttpMethod; + +// ReSharper disable InterpolatedStringExpressionIsNotIFormattable +// ReSharper disable once CheckNamespace +// ReSharper disable InterpolatedStringExpressionIsNotIFormattable +// ReSharper disable RedundantExtendsListEntry +namespace OpenSearch.Net.Specification.IndicesApi +{ + /// + /// Indices APIs. + /// Not intended to be instantiated directly. Use the property + /// on . + /// + /// + public partial class LowLevelIndicesNamespace : NamespacedClientProxy + { + internal LowLevelIndicesNamespace(OpenSearchLowLevelClient client) + : base(client) { } + + /// DELETE on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// The name of the template. + /// Request specific configuration such as querystring parameters & request specific connection settings. + public TResponse DeleteComposableTemplateForAll( + string name, + DeleteComposableIndexTemplateRequestParameters requestParameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest( + DELETE, + Url($"_index_template/{name:name}"), + null, + RequestParams(requestParameters) + ); + + /// DELETE on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/#delete-a-template + /// The name of the template. + /// Request specific configuration such as querystring parameters & request specific connection settings. + [MapsApi("indices.delete_index_template", "name")] + public Task DeleteComposableTemplateForAllAsync( + string name, + DeleteComposableIndexTemplateRequestParameters requestParameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + DELETE, + Url($"_index_template/{name:name}"), + ctx, + null, + RequestParams(requestParameters) + ); + + /// HEAD on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// The name of the template. + /// Request specific configuration such as querystring parameters & request specific connection settings. + public TResponse ComposableTemplateExistsForAll( + string name, + ComposableIndexTemplateExistsRequestParameters requestParameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest( + HEAD, + Url($"_index_template/{name:name}"), + null, + RequestParams(requestParameters) + ); + + /// HEAD on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// The name of the template. + /// Request specific configuration such as querystring parameters & request specific connection settings. + [MapsApi("indices.exists_index_template", "name")] + public Task ComposableTemplateExistsForAllAsync( + string name, + ComposableIndexTemplateExistsRequestParameters requestParameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + HEAD, + Url($"_index_template/{name:name}"), + ctx, + null, + RequestParams(requestParameters) + ); + + /// GET on /_index_template https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// Request specific configuration such as querystring parameters & request specific connection settings. + public TResponse GetComposableTemplateForAll( + GetComposableIndexTemplateRequestParameters requestParameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest(GET, "_index_template", null, RequestParams(requestParameters)); + + /// GET on /_index_template https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// Request specific configuration such as querystring parameters & request specific connection settings. + [MapsApi("indices.get_index_template", "")] + public Task GetComposableTemplateForAllAsync( + GetComposableIndexTemplateRequestParameters requestParameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + GET, + "_index_template", + ctx, + null, + RequestParams(requestParameters) + ); + + /// GET on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// Comma-separated names of the index templates. + /// Request specific configuration such as querystring parameters & request specific connection settings. + public TResponse GetComposableTemplateForAll( + string name, + GetComposableIndexTemplateRequestParameters requestParameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest( + GET, + Url($"_index_template/{name:name}"), + null, + RequestParams(requestParameters) + ); + + /// GET on /_index_template/{name} https://opensearch.org/docs/latest/im-plugin/index-templates/ + /// Comma-separated names of the index templates. + /// Request specific configuration such as querystring parameters & request specific connection settings. + [MapsApi("indices.get_index_template", "name")] + public Task GetComposableTemplateForAllAsync( + string name, + GetComposableIndexTemplateRequestParameters requestParameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + GET, + Url($"_index_template/{name:name}"), + ctx, + null, + RequestParams(requestParameters) + ); + + /// PUT on /_index_template/{name} + /// The name of the template. + /// The template definition + /// Request specific configuration such as querystring parameters & request specific connection settings. + public TResponse PutComposableTemplateForAll( + string name, + PostData body, + PutComposableIndexTemplateRequestParameters requestParameters = null + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequest( + PUT, + Url($"_index_template/{name:name}"), + body, + RequestParams(requestParameters) + ); + + /// PUT on /_index_template/{name} + /// The name of the template. + /// The template definition + /// Request specific configuration such as querystring parameters & request specific connection settings. + [MapsApi("indices.put_index_template", "name, body")] + public Task PutComposableTemplateForAllAsync( + string name, + PostData body, + PutComposableIndexTemplateRequestParameters requestParameters = null, + CancellationToken ctx = default + ) + where TResponse : class, IOpenSearchResponse, new() => + DoRequestAsync( + PUT, + Url($"_index_template/{name:name}"), + ctx, + body, + RequestParams(requestParameters) + ); + } +} diff --git a/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs b/src/OpenSearch.Net/_Generated/OpenSearchLowLevelClient.cs index bd85c1c3de..734baabf4a 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.IndicesApi; using OpenSearch.Net.Specification.IngestApi; using OpenSearch.Net.Specification.NodesApi; using OpenSearch.Net.Specification.SnapshotApi; @@ -69,6 +70,7 @@ public partial class OpenSearchLowLevelClient : IOpenSearchLowLevelClient { public LowLevelClusterNamespace Cluster { get; private set; } public LowLevelDanglingIndicesNamespace DanglingIndices { get; private set; } + public LowLevelIndicesNamespace Indices { get; private set; } public LowLevelIngestNamespace Ingest { get; private set; } public LowLevelNodesNamespace Nodes { get; private set; } public LowLevelSnapshotNamespace Snapshot { get; private set; } @@ -78,6 +80,7 @@ partial void SetupGeneratedNamespaces() { Cluster = new LowLevelClusterNamespace(this); DanglingIndices = new LowLevelDanglingIndicesNamespace(this); + Indices = new LowLevelIndicesNamespace(this); Ingest = new LowLevelIngestNamespace(this); Nodes = new LowLevelNodesNamespace(this); Snapshot = new LowLevelSnapshotNamespace(this); From b9a90086bd6648d525b43da36af458f91c12957a Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 18:39:55 +1300 Subject: [PATCH 03/16] Add resp/req bodies for *ComposableIndexTemplate Signed-off-by: Thomas Farr --- .../ComponentTemplate/ComponentTemplate.cs | 40 --------- .../ComposableIndexTemplateExistsRequest.cs | 15 ++++ .../DeleteComposableIndexTemplateRequest.cs | 15 ++++ .../DeleteComposableIndexTemplateResponse.cs | 10 +++ .../ComposableIndexTemplate.cs | 90 +++++++++++++++++++ .../DataStreamTemplate.cs | 50 +++++++++++ .../GetComposableIndexTemplateRequest.cs | 15 ++++ .../GetComposableIndexTemplateResponse.cs | 28 ++++++ .../PutComposableIndexTemplateRequest.cs | 60 +++++++++++++ .../PutComposableIndexTemplateResponse.cs | 10 +++ 10 files changed, 293 insertions(+), 40 deletions(-) create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsRequest.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateRequest.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateResponse.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/ComposableIndexTemplate.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/DataStreamTemplate.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateRequest.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateResponse.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateRequest.cs create mode 100644 src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateResponse.cs diff --git a/src/OpenSearch.Client/Cluster/ComponentTemplate/ComponentTemplate.cs b/src/OpenSearch.Client/Cluster/ComponentTemplate/ComponentTemplate.cs index 9cb9ee41ab..46bc9e5140 100644 --- a/src/OpenSearch.Client/Cluster/ComponentTemplate/ComponentTemplate.cs +++ b/src/OpenSearch.Client/Cluster/ComponentTemplate/ComponentTemplate.cs @@ -5,7 +5,6 @@ * compatible open source license. */ -using System; using System.Collections.Generic; using System.Runtime.Serialization; using OpenSearch.Net.Utf8Json; @@ -32,42 +31,3 @@ public class ComponentTemplate : IComponentTemplate public long? Version { get; set; } public IDictionary Meta { get; set; } } - -[ReadAs(typeof(Template))] -public interface ITemplate -{ - [DataMember(Name = "aliases")] - IAliases Aliases { get; set; } - - [DataMember(Name = "mappings")] - ITypeMapping Mappings { get; set; } - - [DataMember(Name = "settings")] - IIndexSettings Settings { get; set; } -} - -public class Template : ITemplate -{ - public IAliases Aliases { get; set; } - public ITypeMapping Mappings { get; set; } - public IIndexSettings Settings { get; set; } -} - -public class TemplateDescriptor : DescriptorBase, ITemplate -{ - IAliases ITemplate.Aliases { get; set; } - ITypeMapping ITemplate.Mappings { get; set; } - IIndexSettings ITemplate.Settings { get; set; } - - public TemplateDescriptor Aliases(Func> aliasDescriptor) => - Assign(aliasDescriptor, (a, v) => a.Aliases = v?.Invoke(new AliasesDescriptor())?.Value); - - public TemplateDescriptor Map(Func, ITypeMapping> selector) where T : class => - Assign(selector, (a, v) => a.Mappings = v?.Invoke(new TypeMappingDescriptor())); - - public TemplateDescriptor Map(Func, ITypeMapping> selector) => - Assign(selector, (a, v) => a.Mappings = v?.Invoke(new TypeMappingDescriptor())); - - public TemplateDescriptor Settings(Func> settingsSelector) => - Assign(settingsSelector, (a, v) => a.Settings = v?.Invoke(new IndexSettingsDescriptor())?.Value); -} diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsRequest.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsRequest.cs new file mode 100644 index 0000000000..bb52e8ad86 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsRequest.cs @@ -0,0 +1,15 @@ +/* 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 OpenSearch.Client; + +[MapsApi("indices.exists_index_template")] +public partial interface IComposableIndexTemplateExistsRequest { } + +public partial class ComposableIndexTemplateExistsRequest { } + +public partial class ComposableIndexTemplateExistsDescriptor { } diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateRequest.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateRequest.cs new file mode 100644 index 0000000000..668ab5a030 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateRequest.cs @@ -0,0 +1,15 @@ +/* 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 OpenSearch.Client; + +[MapsApi("indices.delete_index_template")] +public partial interface IDeleteComposableIndexTemplateRequest { } + +public partial class DeleteComposableIndexTemplateRequest { } + +public partial class DeleteComposableIndexTemplateDescriptor { } diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateResponse.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateResponse.cs new file mode 100644 index 0000000000..1f8d414513 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateResponse.cs @@ -0,0 +1,10 @@ +/* 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 OpenSearch.Client; + +public class DeleteComposableIndexTemplateResponse : AcknowledgedResponseBase { } diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/ComposableIndexTemplate.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/ComposableIndexTemplate.cs new file mode 100644 index 0000000000..0df8fc2186 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/ComposableIndexTemplate.cs @@ -0,0 +1,90 @@ +/* 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.Runtime.Serialization; +using OpenSearch.Net; +using OpenSearch.Net.Utf8Json; + +namespace OpenSearch.Client; + +[ReadAs(typeof(Template))] +public interface ITemplate +{ + [DataMember(Name = "aliases")] + IAliases Aliases { get; set; } + + [DataMember(Name = "mappings")] + ITypeMapping Mappings { get; set; } + + [DataMember(Name = "settings")] + IIndexSettings Settings { get; set; } +} + +public class Template : ITemplate +{ + public IAliases Aliases { get; set; } + public ITypeMapping Mappings { get; set; } + public IIndexSettings Settings { get; set; } +} + +public class TemplateDescriptor : DescriptorBase, ITemplate +{ + IAliases ITemplate.Aliases { get; set; } + ITypeMapping ITemplate.Mappings { get; set; } + IIndexSettings ITemplate.Settings { get; set; } + + public TemplateDescriptor Aliases(Func> aliasDescriptor) => + Assign(aliasDescriptor, (a, v) => a.Aliases = v?.Invoke(new AliasesDescriptor())?.Value); + + public TemplateDescriptor Map(Func, ITypeMapping> selector) where T : class => + Assign(selector, (a, v) => a.Mappings = v?.Invoke(new TypeMappingDescriptor())); + + public TemplateDescriptor Map(Func, ITypeMapping> selector) => + Assign(selector, (a, v) => a.Mappings = v?.Invoke(new TypeMappingDescriptor())); + + public TemplateDescriptor Settings(Func> settingsSelector) => + Assign(settingsSelector, (a, v) => a.Settings = v?.Invoke(new IndexSettingsDescriptor())?.Value); +} + +[ReadAs(typeof(ComposableIndexTemplate))] +public interface IComposableIndexTemplate +{ + [DataMember(Name = "composed_of")] + IReadOnlyCollection ComposedOf { get; set; } + + [DataMember(Name = "data_stream")] + IDataStreamTemplate DataStream { get; set; } + + [DataMember(Name = "index_patterns")] + IReadOnlyCollection IndexPatterns { get; set; } + + [DataMember(Name = "priority")] + long? Priority { get; set; } + + [DataMember(Name = "template")] + ITemplate Template { get; set; } + + [DataMember(Name = "version")] + long? Version { get; set; } + + [DataMember(Name = "_meta")] + [JsonFormatter(typeof(VerbatimDictionaryInterfaceKeysFormatter))] + IDictionary Meta { get; set; } +} + +public class ComposableIndexTemplate : IComposableIndexTemplate +{ + public IReadOnlyCollection ComposedOf { get; set; } = EmptyReadOnly.Collection; + public IDataStreamTemplate DataStream { get; set; } + public IReadOnlyCollection IndexPatterns { get; set; } = EmptyReadOnly.Collection; + public long? Priority { get; set; } + public ITemplate Template { get; set; } + public long? Version { get; set; } + public IDictionary Meta { get; set; } +} diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/DataStreamTemplate.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/DataStreamTemplate.cs new file mode 100644 index 0000000000..aae25dc69d --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/DataStreamTemplate.cs @@ -0,0 +1,50 @@ +/* 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.Runtime.Serialization; + +namespace OpenSearch.Client; + +[ReadAs(typeof(DataStreamTemplate))] +public interface IDataStreamTemplate +{ + [DataMember(Name = "timestamp_field")] + ITimestampField TimestampField { get; set; } +} + +public class DataStreamTemplate : IDataStreamTemplate +{ + public ITimestampField TimestampField { get; set; } +} + +public class DataStreamTemplateDescriptor : DescriptorBase, IDataStreamTemplate +{ + ITimestampField IDataStreamTemplate.TimestampField { get; set; } + + public DataStreamTemplateDescriptor TimestampField(Func selector) => + Assign(selector, (a, v) => a.TimestampField = v?.Invoke(new TimestampFieldDescriptor())); +} + +[ReadAs(typeof(TimestampField))] +public interface ITimestampField +{ + [DataMember(Name = "name")] + string Name { get; set; } +} + +public class TimestampField : ITimestampField +{ + public string Name { get; set; } +} + +public class TimestampFieldDescriptor : DescriptorBase, ITimestampField +{ + string ITimestampField.Name { get; set; } + + public TimestampFieldDescriptor Name(string name) => Assign(name, (a, v) => a.Name = v); +} diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateRequest.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateRequest.cs new file mode 100644 index 0000000000..efc11a832d --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateRequest.cs @@ -0,0 +1,15 @@ +/* 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 OpenSearch.Client; + +[MapsApi("indices.get_index_template")] +public partial interface IGetComposableIndexTemplateRequest { } + +public partial class GetComposableIndexTemplateRequest { } + +public partial class GetComposableIndexTemplateDescriptor { } diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateResponse.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateResponse.cs new file mode 100644 index 0000000000..289492df31 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateResponse.cs @@ -0,0 +1,28 @@ +/* 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.Collections.Generic; +using System.Runtime.Serialization; + +namespace OpenSearch.Client; + +[DataContract] +public class GetComposableIndexTemplateResponse : ResponseBase +{ + [DataMember(Name = "index_templates")] + public IReadOnlyCollection IndexTemplates { get; internal set; } +} + +[DataContract] +public class NamedComposableIndexTemplate +{ + [DataMember(Name = "name")] + public string Name { get; internal set; } + + [DataMember(Name = "index_template")] + public ComposableIndexTemplate IndexTemplate { get; internal set; } +} diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateRequest.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateRequest.cs new file mode 100644 index 0000000000..8a61aeb27a --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateRequest.cs @@ -0,0 +1,60 @@ +/* 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.Linq; + +namespace OpenSearch.Client; + +[MapsApi("indices.put_index_template")] +public partial interface IPutComposableIndexTemplateRequest : IComposableIndexTemplate { } + +public partial class PutComposableIndexTemplateRequest +{ + public IReadOnlyCollection ComposedOf { get; set; } + public IDataStreamTemplate DataStream { get; set; } + public IReadOnlyCollection IndexPatterns { get; set; } + public long? Priority { get; set; } + public ITemplate Template { get; set; } + public long? Version { get; set; } + public IDictionary Meta { get; set; } +} + +public partial class PutComposableIndexTemplateDescriptor +{ + IReadOnlyCollection IComposableIndexTemplate.ComposedOf { get; set; } + IDataStreamTemplate IComposableIndexTemplate.DataStream { get; set; } + IReadOnlyCollection IComposableIndexTemplate.IndexPatterns { get; set; } + long? IComposableIndexTemplate.Priority { get; set; } + ITemplate IComposableIndexTemplate.Template { get; set; } + long? IComposableIndexTemplate.Version { get; set; } + IDictionary IComposableIndexTemplate.Meta { get; set; } + + public PutComposableIndexTemplateDescriptor ComposedOf(params string[] composedOf) => Assign(composedOf, (a, v) => a.ComposedOf = v); + + public PutComposableIndexTemplateDescriptor ComposedOf(IEnumerable composedOf) => Assign(composedOf?.ToArray(), (a, v) => a.ComposedOf = v); + + public PutComposableIndexTemplateDescriptor DataStream(Func dataStreamSelector) => + Assign(dataStreamSelector, (a, v) => a.DataStream = v?.Invoke(new DataStreamTemplateDescriptor())); + + public PutComposableIndexTemplateDescriptor IndexPatterns(params string[] patterns) => Assign(patterns, (a, v) => a.IndexPatterns = v); + + public PutComposableIndexTemplateDescriptor IndexPatterns(IEnumerable patterns) => Assign(patterns?.ToArray(), (a, v) => a.IndexPatterns = v); + + public PutComposableIndexTemplateDescriptor Priority(long? priority) => Assign(priority, (a, v) => a.Priority = v); + + public PutComposableIndexTemplateDescriptor Template(Func selector) => + Assign(selector, (a, v) => a.Template = v?.Invoke(new TemplateDescriptor())); + + public PutComposableIndexTemplateDescriptor Version(long? version) => Assign(version, (a, v) => a.Version = v); + + public PutComposableIndexTemplateDescriptor Meta(Func, FluentDictionary> selector) => + Assign(selector, (a, v) => a.Meta = v?.Invoke(new FluentDictionary())); + + public PutComposableIndexTemplateDescriptor Meta(Dictionary meta) => Assign(meta, (a, v) => a.Meta = v); +} diff --git a/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateResponse.cs b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateResponse.cs new file mode 100644 index 0000000000..5a2af05ba9 --- /dev/null +++ b/src/OpenSearch.Client/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateResponse.cs @@ -0,0 +1,10 @@ +/* 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 OpenSearch.Client; + +public class PutComposableIndexTemplateResponse : AcknowledgedResponseBase { } From 7dec1d82f19a7969195f05a70ecc1180e7f3ac36 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 18:40:04 +1300 Subject: [PATCH 04/16] Fix tests Signed-off-by: Thomas Farr --- tests/Tests.YamlRunner/TestSuiteBootstrap.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Tests.YamlRunner/TestSuiteBootstrap.fs b/tests/Tests.YamlRunner/TestSuiteBootstrap.fs index 14ab5824ac..cd99079be0 100644 --- a/tests/Tests.YamlRunner/TestSuiteBootstrap.fs +++ b/tests/Tests.YamlRunner/TestSuiteBootstrap.fs @@ -41,7 +41,7 @@ let private deleteAllIndices (client: IOpenSearchLowLevelClient) = let private deleteAllTemplates (client: IOpenSearchLowLevelClient) = [ client.Indices.DeleteTemplateForAll("*") - client.Indices.DeleteTemplateV2ForAll("*") + client.Indices.DeleteComposableTemplateForAll("*") client.Cluster.DeleteComponentTemplate("*") ] From c883bdbc5b991f1460f289dee014601408807632 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 19:01:09 +1300 Subject: [PATCH 05/16] Add ComposableIndexTemplateCrudTests Signed-off-by: Thomas Farr --- .../ComposableIndexTemplateCrudTests.cs | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs new file mode 100644 index 0000000000..fd01ab2c48 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs @@ -0,0 +1,135 @@ +/* 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.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using OpenSearch.Client; +using Tests.Core.Extensions; +using Tests.Core.ManagedOpenSearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates; + +public class ComposableIndexTemplateCrudTests + : CrudTestBase +{ + public ComposableIndexTemplateCrudTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override LazyResponses Exists() => + Calls( + id => new ComposableIndexTemplateExistsRequest(id), + (id, d) => d, + (s, c, f) => c.Indices.ComposableTemplateExists(s, f), + (s, c, f) => c.Indices.ComposableTemplateExistsAsync(s, f), + (s, c, r) => c.Indices.ComposableTemplateExists(r), + (s, c, r) => c.Indices.ComposableTemplateExistsAsync(r) + ); + + protected override LazyResponses Create() => + Calls( + CreateInitializer, + CreateFluent, + (s, c, f) => c.Indices.PutComposableTemplate(s, f), + (s, c, f) => c.Indices.PutComposableTemplateAsync(s, f), + (s, c, r) => c.Indices.PutComposableTemplate(r), + (s, c, r) => c.Indices.PutComposableTemplateAsync(r) + ); + + private PutComposableIndexTemplateRequest CreateInitializer(string name) => new(name) + { + IndexPatterns = new[] { "startingwiththis-*" }, + Template = new Template { Settings = new OpenSearch.Client.IndexSettings { NumberOfShards = 2 } } + }; + + private IPutComposableIndexTemplateRequest CreateFluent(string name, PutComposableIndexTemplateDescriptor d) => d + .IndexPatterns("startingwiththis-*") + .Template(t => t + .Settings(s => s + .NumberOfShards(2) + ) + ); + + protected override LazyResponses Read() => + Calls( + name => new GetComposableIndexTemplateRequest(name), + (name, d) => d.Name(name), + (s, c, f) => c.Indices.GetComposableTemplate(s, f), + (s, c, f) => c.Indices.GetComposableTemplateAsync(s, f), + (s, c, r) => c.Indices.GetComposableTemplate(r), + (s, c, r) => c.Indices.GetComposableTemplateAsync(r) + ); + + protected override void ExpectAfterCreate(GetComposableIndexTemplateResponse response) + { + response.IndexTemplates.Should().NotBeNull().And.HaveCount(1); + var template = response.IndexTemplates.First().IndexTemplate; + template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwith")); + template.Template.Should().NotBeNull(); + template.Template.Settings.Should().NotBeNull().And.NotBeEmpty(); + template.Template.Settings.NumberOfShards.Should().Be(2); + } + + protected override LazyResponses Update() => + Calls( + PutInitializer, + PutFluent, + (s, c, f) => c.Indices.PutComposableTemplate(s, f), + (s, c, f) => c.Indices.PutComposableTemplateAsync(s, f), + (s, c, r) => c.Indices.PutComposableTemplate(r), + (s, c, r) => c.Indices.PutComposableTemplateAsync(r) + ); + + private PutComposableIndexTemplateRequest PutInitializer(string name) => new(name) + { + IndexPatterns = new[] { "startingwiththis-*" }, + Template = new Template { Settings = new OpenSearch.Client.IndexSettings { NumberOfShards = 1 } } + }; + + private IPutComposableIndexTemplateRequest PutFluent(string name, PutComposableIndexTemplateDescriptor d) => d + .IndexPatterns("startingwiththis-*") + .Template(t => t + .Settings(s => s + .NumberOfShards(1) + ) + ); + + protected override void ExpectAfterUpdate(GetComposableIndexTemplateResponse response) + { + response.IndexTemplates.Should().NotBeNull().And.HaveCount(1); + var template = response.IndexTemplates.First().IndexTemplate; + template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwith")); + template.Template.Should().NotBeNull(); + template.Template.Settings.Should().NotBeNull().And.NotBeEmpty(); + template.Template.Settings.NumberOfShards.Should().Be(1); + } + + protected override LazyResponses Delete() => + Calls( + name => new DeleteComposableIndexTemplateRequest(name), + (name, d) => d, + (s, c, f) => c.Indices.DeleteComposableTemplate(s, f), + (s, c, f) => c.Indices.DeleteComposableTemplateAsync(s, f), + (s, c, r) => c.Indices.DeleteComposableTemplate(r), + (s, c, r) => c.Indices.DeleteComposableTemplateAsync(r) + ); + + protected override async Task GetAfterDeleteIsValid() => await AssertOnGetAfterDelete(r => r.ShouldNotBeValid()); + + protected override void ExpectDeleteNotFoundResponse(DeleteComposableIndexTemplateResponse response) + { + response.ServerError.Should().NotBeNull(); + response.ServerError.Status.Should().Be(404); + response.ServerError.Error.Reason.Should().Contain("missing"); + } +} From 556a8c50a3e9e40dc1a5291f19bcae7b1371b267 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 19:04:52 +1300 Subject: [PATCH 06/16] Add ComposableIndexTemplateExists tests Signed-off-by: Thomas Farr --- .../ComposableIndexTemplateExistsApiTests.cs | 38 +++++++++++++++++++ .../ComposableIndexTemplateExistsUrlTests.cs | 28 ++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsApiTests.cs create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsApiTests.cs new file mode 100644 index 0000000000..28549e1a15 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsApiTests.cs @@ -0,0 +1,38 @@ +/* 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 OpenSearch.Client; +using OpenSearch.Net; +using Tests.Core.ManagedOpenSearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.ComposableIndexTemplateExists; + +public class ComposableIndexTemplateExistsApiTests + : ApiTestBase +{ + public ComposableIndexTemplateExistsApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override Func Fluent => d => d; + + protected override HttpMethod HttpMethod => HttpMethod.HEAD; + + protected override ComposableIndexTemplateExistsRequest Initializer => new(CallIsolatedValue); + protected override string UrlPath => $"/_index_template/{CallIsolatedValue}"; + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Indices.ComposableTemplateExists(CallIsolatedValue, f), + (client, f) => client.Indices.ComposableTemplateExistsAsync(CallIsolatedValue, f), + (client, r) => client.Indices.ComposableTemplateExists(r), + (client, r) => client.Indices.ComposableTemplateExistsAsync(r) + ); + + protected override ComposableIndexTemplateExistsDescriptor NewDescriptor() => new(CallIsolatedValue); +} diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs new file mode 100644 index 0000000000..346ca9b461 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs @@ -0,0 +1,28 @@ +/* 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.Threading.Tasks; +using OpenSearch.Client; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; +using Tests.Framework.EndpointTests; +using static Tests.Framework.EndpointTests.UrlTester; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.ComposableIndexTemplateExists; + +public class ComposableIndexTemplateUrlTests +{ + [U] public async Task Urls() + { + const string name = "temp"; + await HEAD($"/_index_template/{name}") + .Fluent(c => c.Indices.ComposableTemplateExists(name)) + .Request(c => c.Indices.ComposableTemplateExists(new ComposableIndexTemplateExistsRequest(name))) + .FluentAsync(c => c.Indices.ComposableTemplateExistsAsync(name)) + .RequestAsync(c => c.Indices.ComposableTemplateExistsAsync(new ComposableIndexTemplateExistsRequest(name))) + ; + } +} From 5168dbc160a2776f491caa5b9d8c19bd8970af88 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Mon, 13 Nov 2023 19:09:41 +1300 Subject: [PATCH 07/16] Add DeleteComposableIndexTemplate tests Signed-off-by: Thomas Farr --- .../ComposableIndexTemplateExistsUrlTests.cs | 2 +- .../DeleteComposableIndexTemplateApiTests.cs | 33 +++++++++++++++++++ .../DeleteComposableIndexTemplateUrlTests.cs | 28 ++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateApiTests.cs create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateUrlTests.cs diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs index 346ca9b461..dcacbfd866 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateExists/ComposableIndexTemplateExistsUrlTests.cs @@ -13,7 +13,7 @@ namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.ComposableIndexTemplateExists; -public class ComposableIndexTemplateUrlTests +public class ComposableIndexTemplateExistsUrlTests { [U] public async Task Urls() { diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateApiTests.cs new file mode 100644 index 0000000000..147644ce85 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateApiTests.cs @@ -0,0 +1,33 @@ +/* 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 OpenSearch.Client; +using OpenSearch.Net; +using Tests.Core.ManagedOpenSearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.DeleteComposableIndexTemplate; + +public class DeleteComposableIndexTemplateApiTests + : ApiTestBase +{ + public DeleteComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override HttpMethod HttpMethod => HttpMethod.DELETE; + + protected override DeleteComposableIndexTemplateRequest Initializer => new(CallIsolatedValue); + protected override string UrlPath => $"/_index_template/{CallIsolatedValue}"; + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Indices.DeleteComposableTemplate(CallIsolatedValue), + (client, f) => client.Indices.DeleteComposableTemplateAsync(CallIsolatedValue), + (client, r) => client.Indices.DeleteComposableTemplate(r), + (client, r) => client.Indices.DeleteComposableTemplateAsync(r) + ); +} diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateUrlTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateUrlTests.cs new file mode 100644 index 0000000000..7f80f7c913 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/DeleteComposableIndexTemplate/DeleteComposableIndexTemplateUrlTests.cs @@ -0,0 +1,28 @@ +/* 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.Threading.Tasks; +using OpenSearch.Client; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; +using Tests.Framework.EndpointTests; +using static Tests.Framework.EndpointTests.UrlTester; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.DeleteComposableIndexTemplate; + +public class DeleteComposableIndexTemplateUrlTests +{ + [U] public async Task Urls() + { + const string name = "temp"; + await DELETE($"/_index_template/{name}") + .Fluent(c => c.Indices.DeleteComposableTemplate(name)) + .Request(c => c.Indices.DeleteComposableTemplate(new DeleteComposableIndexTemplateRequest(name))) + .FluentAsync(c => c.Indices.DeleteComposableTemplateAsync(name)) + .RequestAsync(c => c.Indices.DeleteComposableTemplateAsync(new DeleteComposableIndexTemplateRequest(name))) + ; + } +} From d60b9fbc9eee930a28a80e28cf18b9cd8fb01aa7 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Tue, 14 Nov 2023 10:34:42 +1300 Subject: [PATCH 08/16] Add GetComposableIndexTemplate tests Signed-off-by: Thomas Farr --- .../GetComposableIndexTemplateApiTests.cs | 76 +++++++++++++++++++ .../GetComposableIndexTemplateUrlTests.cs | 35 +++++++++ 2 files changed, 111 insertions(+) create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateUrlTests.cs diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs new file mode 100644 index 0000000000..dacdcd7adf --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.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; +using System.Linq; +using FluentAssertions; +using OpenSearch.Client; +using OpenSearch.Net; +using Tests.Core.Extensions; +using Tests.Core.ManagedOpenSearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.GetComposableIndexTemplate; + +public class GetComposableIndexTemplateApiTests + : ApiIntegrationTestBase +{ + public GetComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override bool ExpectIsValid => true; + protected override object ExpectJson => null; + protected override int ExpectStatusCode => 200; + protected override HttpMethod HttpMethod => HttpMethod.GET; + protected override string UrlPath => $"/_index_template/{CallIsolatedValue}"; + + protected override GetComposableIndexTemplateRequest Initializer => new(CallIsolatedValue); + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Indices.GetComposableTemplate(CallIsolatedValue, f), + (client, f) => client.Indices.GetComposableTemplateAsync(CallIsolatedValue, f), + (client, r) => client.Indices.GetComposableTemplate(r), + (client, r) => client.Indices.GetComposableTemplateAsync(r) + ); + + protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueValues values) + { + foreach (var callUniqueValue in values.Values) + { + var putTemplateResponse = client.Indices.PutComposableTemplate(callUniqueValue, d => d + .IndexPatterns("startingwiththis-*") + .Version(1) + .Template(t => t + .Settings(s => s.NumberOfShards(2)))); + + if (!putTemplateResponse.IsValid) + throw new Exception($"Problem putting index template for integration test: {putTemplateResponse.DebugInformation}"); + } + } + + protected override void ExpectResponse(GetComposableIndexTemplateResponse response) + { + response.ShouldBeValid(); + + response.IndexTemplates.Should().NotBeNull().And.HaveCount(1); + + var namedTemplate = response.IndexTemplates.First(); + namedTemplate.Name.Should().Be(CallIsolatedValue); + var template = namedTemplate.IndexTemplate; + + template.Should().NotBeNull(); + template.IndexPatterns.Should().NotBeNull().And.HaveCount(1); + template.IndexPatterns.First().Should().Be("startingwiththis-*"); + + template.Version.Should().Be(1); + + template.Template.Should().NotBeNull(); + template.Template.Settings.Should().NotBeNull(); + template.Template.Settings.NumberOfShards.Should().Be(2); + } +} diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateUrlTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateUrlTests.cs new file mode 100644 index 0000000000..f77542a305 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateUrlTests.cs @@ -0,0 +1,35 @@ +/* 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.Threading.Tasks; +using OpenSearch.Client; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; +using Tests.Framework.EndpointTests; +using static Tests.Framework.EndpointTests.UrlTester; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.GetComposableIndexTemplate; + +public class GetComposableIndexTemplateUrlTests +{ + [U] public async Task Urls() + { + const string name = "temp"; + await GET($"/_index_template/{name}") + .Fluent(c => c.Indices.GetComposableTemplate(name)) + .Request(c => c.Indices.GetComposableTemplate(new GetComposableIndexTemplateRequest(name))) + .FluentAsync(c => c.Indices.GetComposableTemplateAsync(name)) + .RequestAsync(c => c.Indices.GetComposableTemplateAsync(new GetComposableIndexTemplateRequest(name))) + ; + + await GET("/_index_template") + .Fluent(c => c.Indices.GetComposableTemplate()) + .Request(c => c.Indices.GetComposableTemplate(new GetComposableIndexTemplateRequest())) + .FluentAsync(c => c.Indices.GetComposableTemplateAsync()) + .RequestAsync(c => c.Indices.GetComposableTemplateAsync(new GetComposableIndexTemplateRequest())) + ; + } +} From 30d538f0f231b2cdeb31eb3a83a7a9b9a72a3686 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Tue, 14 Nov 2023 10:51:10 +1300 Subject: [PATCH 09/16] Add PutComposableIndexTemplate tests Signed-off-by: Thomas Farr --- .../PutComposableIndexTemplateApiTests.cs | 143 ++++++++++++++++++ .../PutComposableIndexTemplateUrlTests.cs | 28 ++++ 2 files changed, 171 insertions(+) create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs create mode 100644 tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateUrlTests.cs diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs new file mode 100644 index 0000000000..b0ea73a697 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs @@ -0,0 +1,143 @@ +/* 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 FluentAssertions; +using OpenSearch.Client; +using OpenSearch.Net; +using Tests.Core.Extensions; +using Tests.Core.ManagedOpenSearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.PutComposableIndexTemplate; + +public class PutComposableIndexTemplateApiTests + : ApiIntegrationTestBase +{ + public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override bool ExpectIsValid => true; + + protected override object ExpectJson => new + { + priority = 1, + version = 2, + index_patterns = new[] { "oscx-*" }, + composed_of = new[] { $"component_{CallIsolatedValue}" }, + template = new + { + settings = new Dictionary { { "index.number_of_shards", 1 } }, + mappings = new + { + dynamic_templates = new object[] + { + new + { + @base = new + { + match = "*", + match_mapping_type = "*", + mapping = new + { + index = false + } + } + } + } + } + } + }; + + protected override int ExpectStatusCode => 200; + + protected override Func Fluent => d => d + .Create(false) + .Priority(1) + .Version(2) + .IndexPatterns("oscx-*") + .ComposedOf($"component_{CallIsolatedValue}") + .Template(t => t + .Settings(p => p.NumberOfShards(1)) + .Map(tm => tm + .DynamicTemplates(dts => dts + .DynamicTemplate("base", dt => dt + .Match("*") + .MatchMappingType("*") + .Mapping(mm => mm + .Generic(g => g + .Index(false) + ) + ) + ) + ) + ) + ); + + protected override HttpMethod HttpMethod => HttpMethod.PUT; + + protected override PutComposableIndexTemplateRequest Initializer => new(CallIsolatedValue) + { + Create = false, + Priority = 1, + Version = 2, + IndexPatterns = new[] { "oscx-*" }, + ComposedOf = new[] { $"component_{CallIsolatedValue}" }, + Template = new Template { + Settings = new OpenSearch.Client.IndexSettings + { + NumberOfShards = 1 + }, + Mappings = new TypeMapping + { + DynamicTemplates = new DynamicTemplateContainer + { + { "base", new DynamicTemplate + { + Match = "*", + MatchMappingType = "*", + Mapping = new GenericProperty { Index = false } + } } + } + } + } + }; + + protected override bool SupportsDeserialization => false; + protected override string UrlPath => $"/_index_template/{CallIsolatedValue}?create=false"; + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Indices.PutComposableTemplate(CallIsolatedValue, f), + (client, f) => client.Indices.PutComposableTemplateAsync(CallIsolatedValue, f), + (client, r) => client.Indices.PutComposableTemplate(r), + (client, r) => client.Indices.PutComposableTemplateAsync(r) + ); + + protected override PutComposableIndexTemplateDescriptor NewDescriptor() => new(CallIsolatedValue); + + protected override void ExpectResponse(PutComposableIndexTemplateResponse response) + { + response.ShouldBeValid(); + response.Acknowledged.Should().BeTrue(); + } + + protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueValues values) + { + foreach (var value in values.Values) + { + var putComponentResponse = client.Cluster.PutComponentTemplate($"component_{value}", d => d + .Template(t => t + .Settings(s => s + .NumberOfReplicas(0)))); + + if (!putComponentResponse.IsValid) + throw new Exception($"Problem putting component template for integration test: {putComponentResponse.DebugInformation}"); + } + } +} diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateUrlTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateUrlTests.cs new file mode 100644 index 0000000000..45e62057d4 --- /dev/null +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateUrlTests.cs @@ -0,0 +1,28 @@ +/* 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.Threading.Tasks; +using OpenSearch.Client; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; +using Tests.Framework.EndpointTests; +using static Tests.Framework.EndpointTests.UrlTester; + +namespace Tests.Indices.IndexSettings.ComposableIndexTemplates.PutComposableIndexTemplate; + +public class PutComposableIndexTemplateUrlTests +{ + [U] public async Task Urls() + { + const string name = "temp"; + await PUT($"/_index_template/{name}") + .Fluent(c => c.Indices.PutComposableTemplate(name, p => p)) + .Request(c => c.Indices.PutComposableTemplate(new PutComposableIndexTemplateRequest(name))) + .FluentAsync(c => c.Indices.PutComposableTemplateAsync(name, p => p)) + .RequestAsync(c => c.Indices.PutComposableTemplateAsync(new PutComposableIndexTemplateRequest(name))) + ; + } +} From 210460a6cd6cdda8aa9a05c9cb70df941cd64338 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Tue, 14 Nov 2023 11:17:41 +1300 Subject: [PATCH 10/16] Non-overlapping templates Signed-off-by: Thomas Farr --- .../ComposableIndexTemplateCrudTests.cs | 12 ++++++------ .../GetComposableIndexTemplateApiTests.cs | 8 ++++---- .../PutComposableIndexTemplateApiTests.cs | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs index fd01ab2c48..d39bc4a945 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/ComposableIndexTemplateCrudTests.cs @@ -45,12 +45,12 @@ protected override LazyResponses Create() => private PutComposableIndexTemplateRequest CreateInitializer(string name) => new(name) { - IndexPatterns = new[] { "startingwiththis-*" }, + IndexPatterns = new[] { $"startingwiththis-{name}-*" }, Template = new Template { Settings = new OpenSearch.Client.IndexSettings { NumberOfShards = 2 } } }; private IPutComposableIndexTemplateRequest CreateFluent(string name, PutComposableIndexTemplateDescriptor d) => d - .IndexPatterns("startingwiththis-*") + .IndexPatterns($"startingwiththis-{name}-*") .Template(t => t .Settings(s => s .NumberOfShards(2) @@ -72,7 +72,7 @@ protected override void ExpectAfterCreate(GetComposableIndexTemplateResponse res { response.IndexTemplates.Should().NotBeNull().And.HaveCount(1); var template = response.IndexTemplates.First().IndexTemplate; - template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwith")); + template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwiththis")); template.Template.Should().NotBeNull(); template.Template.Settings.Should().NotBeNull().And.NotBeEmpty(); template.Template.Settings.NumberOfShards.Should().Be(2); @@ -91,12 +91,12 @@ protected override LazyResponses Update() => private PutComposableIndexTemplateRequest PutInitializer(string name) => new(name) { - IndexPatterns = new[] { "startingwiththis-*" }, + IndexPatterns = new[] { $"startingwiththis-{name}-*" }, Template = new Template { Settings = new OpenSearch.Client.IndexSettings { NumberOfShards = 1 } } }; private IPutComposableIndexTemplateRequest PutFluent(string name, PutComposableIndexTemplateDescriptor d) => d - .IndexPatterns("startingwiththis-*") + .IndexPatterns($"startingwiththis-{name}-*") .Template(t => t .Settings(s => s .NumberOfShards(1) @@ -107,7 +107,7 @@ protected override void ExpectAfterUpdate(GetComposableIndexTemplateResponse res { response.IndexTemplates.Should().NotBeNull().And.HaveCount(1); var template = response.IndexTemplates.First().IndexTemplate; - template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwith")); + template.IndexPatterns.Should().NotBeNullOrEmpty().And.Contain(t => t.StartsWith("startingwiththis")); template.Template.Should().NotBeNull(); template.Template.Settings.Should().NotBeNull().And.NotBeEmpty(); template.Template.Settings.NumberOfShards.Should().Be(1); diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs index dacdcd7adf..9693e85d31 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs @@ -40,10 +40,10 @@ protected override LazyResponses ClientUsage() => Calls( protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueValues values) { - foreach (var callUniqueValue in values.Values) + foreach (var value in values.Values) { - var putTemplateResponse = client.Indices.PutComposableTemplate(callUniqueValue, d => d - .IndexPatterns("startingwiththis-*") + var putTemplateResponse = client.Indices.PutComposableTemplate(value, d => d + .IndexPatterns($"{value}-*") .Version(1) .Template(t => t .Settings(s => s.NumberOfShards(2)))); @@ -65,7 +65,7 @@ protected override void ExpectResponse(GetComposableIndexTemplateResponse respon template.Should().NotBeNull(); template.IndexPatterns.Should().NotBeNull().And.HaveCount(1); - template.IndexPatterns.First().Should().Be("startingwiththis-*"); + template.IndexPatterns.First().Should().Be($"{CallIsolatedValue}-*"); template.Version.Should().Be(1); diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs index b0ea73a697..5e44f73766 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs @@ -29,7 +29,7 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage { priority = 1, version = 2, - index_patterns = new[] { "oscx-*" }, + index_patterns = new[] { $"{CallIsolatedValue}-*" }, composed_of = new[] { $"component_{CallIsolatedValue}" }, template = new { @@ -61,7 +61,7 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage .Create(false) .Priority(1) .Version(2) - .IndexPatterns("oscx-*") + .IndexPatterns($"{CallIsolatedValue}-*") .ComposedOf($"component_{CallIsolatedValue}") .Template(t => t .Settings(p => p.NumberOfShards(1)) @@ -87,7 +87,7 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage Create = false, Priority = 1, Version = 2, - IndexPatterns = new[] { "oscx-*" }, + IndexPatterns = new[] { $"{CallIsolatedValue}-*" }, ComposedOf = new[] { $"component_{CallIsolatedValue}" }, Template = new Template { Settings = new OpenSearch.Client.IndexSettings From ea5bac7320e9267d289de040899db71fb5ca6095 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Tue, 14 Nov 2023 12:54:40 +1300 Subject: [PATCH 11/16] Fix tests Signed-off-by: Thomas Farr --- .github/workflows/integration.yml | 15 ++++---- .../CodeStandards/NamingConventions.doc.cs | 1 + .../EndpointTests/ApiIntegrationTestBase.cs | 6 ++-- .../RequestResponseApiTestBase.cs | 7 ++-- .../GetComposableIndexTemplateApiTests.cs | 5 +++ .../PutComposableIndexTemplateApiTests.cs | 9 +++++ .../Search/PointInTime/CreatePitApiTests.cs | 18 +++------- .../PointInTime/DeleteAllPitsApiTests.cs | 17 ++++++---- .../Search/PointInTime/DeletePitApiTests.cs | 25 +++++++------- .../Search/PointInTime/GetAllPitsApiTests.cs | 20 ++++++----- .../Search/PointInTime/PitSearchApiTests.cs | 34 +++++++++---------- 11 files changed, 86 insertions(+), 71 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index c1edf5b94b..7ff79fe825 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -49,11 +49,11 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.?sproj') }} restore-keys: | ${{ runner.os }}-nuget- - + - run: "./build.sh integrate ${{ matrix.version }} readonly,writable random:test_only_one --report" name: Integration Tests working-directory: client - + - name: Upload test report if: failure() uses: actions/upload-artifact@v3 @@ -62,12 +62,13 @@ jobs: path: client/build/output/* integration-opensearch-unreleased: + if: false # TODO: Temporarily disabled due to failures building & running OpenSearch from source, pending investigation & fixes name: Integration OpenSearch Unreleased runs-on: ubuntu-latest strategy: fail-fast: false matrix: - opensearch_ref: + opensearch_ref: - '1.x' - '2.x' - 'main' @@ -77,7 +78,7 @@ jobs: uses: actions/checkout@v3 with: path: client - + - uses: actions/setup-dotnet@v3 with: dotnet-version: | @@ -90,7 +91,7 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.?sproj') }} restore-keys: | ${{ runner.os }}-nuget- - + - name: Restore or Build OpenSearch id: opensearch uses: ./client/.github/actions/build-opensearch @@ -99,14 +100,14 @@ jobs: security_plugin: ${{ matrix.opensearch_ref == '1.x' }} knn_plugin: true plugins_output_directory: ${{ env.OPENSEARCH_PLUGINS_DIRECTORY }} - + - run: "./build.sh integrate $OPENSEARCH_VERSION readonly,writable random:test_only_one --report" name: Integration Tests working-directory: client env: OPENSEARCH_VERSION: ${{ steps.opensearch.outputs.version }} OPENSEARCH_DISTRIBUTION: ${{ steps.opensearch.outputs.distribution }} - + - name: Upload test report if: failure() uses: actions/upload-artifact@v3 diff --git a/tests/Tests/CodeStandards/NamingConventions.doc.cs b/tests/Tests/CodeStandards/NamingConventions.doc.cs index ab357fa340..9dcb6fcb9e 100644 --- a/tests/Tests/CodeStandards/NamingConventions.doc.cs +++ b/tests/Tests/CodeStandards/NamingConventions.doc.cs @@ -142,6 +142,7 @@ public void ParityBetweenRequestsAndResponses() typeof(TypeExistsRequest), typeof(IndexTemplateExistsRequest), typeof(ComponentTemplateExistsRequest), + typeof(ComposableIndexTemplateExistsRequest), typeof(SearchTemplateRequest), typeof(SearchTemplateRequest<>), typeof(ScrollRequest), diff --git a/tests/Tests/Framework/EndpointTests/ApiIntegrationTestBase.cs b/tests/Tests/Framework/EndpointTests/ApiIntegrationTestBase.cs index 9536800057..d935e160a9 100644 --- a/tests/Tests/Framework/EndpointTests/ApiIntegrationTestBase.cs +++ b/tests/Tests/Framework/EndpointTests/ApiIntegrationTestBase.cs @@ -26,12 +26,12 @@ * under the License. */ - using System; +using System; using System.Diagnostics; using System.Runtime.ExceptionServices; using System.Threading.Tasks; - using OpenSearch.OpenSearch.Ephemeral; - using OpenSearch.OpenSearch.Xunit.XunitPlumbing; +using OpenSearch.OpenSearch.Ephemeral; +using OpenSearch.OpenSearch.Xunit.XunitPlumbing; using OpenSearch.Net; using FluentAssertions; using OpenSearch.Client; diff --git a/tests/Tests/Framework/EndpointTests/RequestResponseApiTestBase.cs b/tests/Tests/Framework/EndpointTests/RequestResponseApiTestBase.cs index e2dd2ecdf9..67a28dc816 100644 --- a/tests/Tests/Framework/EndpointTests/RequestResponseApiTestBase.cs +++ b/tests/Tests/Framework/EndpointTests/RequestResponseApiTestBase.cs @@ -97,6 +97,8 @@ protected virtual void IntegrationTeardown(IOpenSearchClient client, CallUniqueV protected virtual void OnBeforeCall(IOpenSearchClient client) { } + protected virtual void OnAfterCall(IOpenSearchClient client, TResponse response) => OnAfterCall(client); + protected virtual void OnAfterCall(IOpenSearchClient client) { } protected abstract LazyResponses ClientUsage(); @@ -138,8 +140,9 @@ void IntegrateOnly(Action act) UniqueValues.CurrentView = v; IntegrateOnly(OnBeforeCall); - dict.Add(v, await m()); - IntegrateOnly(OnAfterCall); + var resp = await m(); + dict.Add(v, resp); + IntegrateOnly(c => OnAfterCall(c, resp)); if (TestOnlyOne) break; } diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs index 9693e85d31..80fb073262 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/GetComposableIndexTemplate/GetComposableIndexTemplateApiTests.cs @@ -53,6 +53,11 @@ protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueVal } } + protected override void IntegrationTeardown(IOpenSearchClient client, CallUniqueValues values) + { + foreach (var value in values.Values) client.Indices.DeleteComposableTemplate(value); + } + protected override void ExpectResponse(GetComposableIndexTemplateResponse response) { response.ShouldBeValid(); diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs index 5e44f73766..0743382666 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs @@ -140,4 +140,13 @@ protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueVal throw new Exception($"Problem putting component template for integration test: {putComponentResponse.DebugInformation}"); } } + + protected override void IntegrationTeardown(IOpenSearchClient client, CallUniqueValues values) + { + foreach (var value in values.Values) + { + client.Indices.DeleteComposableTemplate(value); + client.Cluster.DeleteComponentTemplate($"component_{value}"); + } + } } diff --git a/tests/Tests/Search/PointInTime/CreatePitApiTests.cs b/tests/Tests/Search/PointInTime/CreatePitApiTests.cs index 779c3a9bfb..b44102c158 100644 --- a/tests/Tests/Search/PointInTime/CreatePitApiTests.cs +++ b/tests/Tests/Search/PointInTime/CreatePitApiTests.cs @@ -6,7 +6,6 @@ */ using System; -using System.Collections.Generic; using FluentAssertions; using OpenSearch.Client; using OpenSearch.Net; @@ -16,22 +15,16 @@ using Tests.Domain; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; +using Xunit; namespace Tests.Search.PointInTime; +[Collection("PitApiTests")] [SkipVersion("<2.4.0", "Point-In-Time search support was added in version 2.4.0")] public class CreatePitApiTests - : ApiIntegrationTestBase + : ApiIntegrationTestBase { - private static readonly Dictionary Pits = new(); - - public CreatePitApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - - private string CallIsolatedPit - { - get => Pits.TryGetValue(CallIsolatedValue, out var pit) ? pit : "default-for-unit-tests"; - set => Pits[CallIsolatedValue] = value; - } + public CreatePitApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } protected override bool ExpectIsValid => true; @@ -65,12 +58,11 @@ protected override LazyResponses ClientUsage() => Calls( protected override void ExpectResponse(CreatePitResponse response) { - CallIsolatedPit = response.PitId; response.ShouldBeValid(); response.PitId.Should().NotBeNullOrEmpty(); response.CreationTime.Should().BeCloseTo(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), 10000); response.Shards.Should().NotBeNull(); } - protected override void OnAfterCall(IOpenSearchClient client) => client.DeletePit(d => d.PitId(CallIsolatedPit)); + protected override void OnAfterCall(IOpenSearchClient client, CreatePitResponse response) => client.DeletePit(d => d.PitId(response.PitId)); } diff --git a/tests/Tests/Search/PointInTime/DeleteAllPitsApiTests.cs b/tests/Tests/Search/PointInTime/DeleteAllPitsApiTests.cs index cb8035ab10..a11ef9ff65 100644 --- a/tests/Tests/Search/PointInTime/DeleteAllPitsApiTests.cs +++ b/tests/Tests/Search/PointInTime/DeleteAllPitsApiTests.cs @@ -17,20 +17,22 @@ using Tests.Domain; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; +using Xunit; namespace Tests.Search.PointInTime; +[Collection("PitApiTests")] [SkipVersion("<2.4.0", "Point-In-Time search support was added in version 2.4.0")] public class DeleteAllPitsApiTests : ApiIntegrationTestBase { - private static readonly Dictionary> Pits = new(); - public DeleteAllPitsApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - private List CallIsolatedPits => Pits.TryGetValue(CallIsolatedValue, out var pits) - ? pits - : Pits[CallIsolatedValue] = new List(); + private List PitIds + { + get => ExtendedValue>(nameof(PitIds)); + set => ExtendedValue(nameof(PitIds), value); + } protected override bool ExpectIsValid => true; @@ -60,7 +62,7 @@ protected override void ExpectResponse(DeleteAllPitsResponse response) response.Pits.Should() .NotBeNull() .And.HaveCount(5) - .And.BeEquivalentTo(CallIsolatedPits.Select(p => new DeletedPit + .And.BeEquivalentTo(PitIds.Select(p => new DeletedPit { PitId = p, Successful = true @@ -69,13 +71,14 @@ protected override void ExpectResponse(DeleteAllPitsResponse response) protected override void OnBeforeCall(IOpenSearchClient client) { + PitIds = new List(); for (var i = 0; i < 5; i++) { var pit = Client.CreatePit(OpenSearch.Client.Indices.Index(), c => c.KeepAlive("1h")); if (!pit.IsValid) throw new Exception("Setup: Initial PIT failed."); - CallIsolatedPits.Add(pit.PitId); + PitIds.Add(pit.PitId); } } } diff --git a/tests/Tests/Search/PointInTime/DeletePitApiTests.cs b/tests/Tests/Search/PointInTime/DeletePitApiTests.cs index 9d7b992b55..f789638ea9 100644 --- a/tests/Tests/Search/PointInTime/DeletePitApiTests.cs +++ b/tests/Tests/Search/PointInTime/DeletePitApiTests.cs @@ -6,7 +6,6 @@ */ using System; -using System.Collections.Generic; using System.Linq; using FluentAssertions; using OpenSearch.Client; @@ -17,21 +16,21 @@ using Tests.Domain; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; +using Xunit; namespace Tests.Search.PointInTime; +[Collection("PitApiTests")] [SkipVersion("<2.4.0", "Point-In-Time search support was added in version 2.4.0")] public class DeletePitApiTests - : ApiIntegrationTestBase + : ApiIntegrationTestBase { - private static readonly Dictionary Pits = new(); + public DeletePitApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - public DeletePitApiTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - - private string CallIsolatedPit + private string PitId { - get => Pits.TryGetValue(CallIsolatedValue, out var pit) ? pit : "default-for-unit-tests"; - set => Pits[CallIsolatedValue] = value; + get => TryGetExtendedValue(nameof(PitId), out var value) ? value : "default-for-unit-tests"; + set => ExtendedValue(nameof(PitId), value); } protected override bool ExpectIsValid => true; @@ -40,16 +39,16 @@ private string CallIsolatedPit { pit_id = new[] { - CallIsolatedPit + PitId } }; protected override int ExpectStatusCode => 200; - protected override Func Fluent => d => d.PitId(CallIsolatedPit); + protected override Func Fluent => d => d.PitId(PitId); protected override HttpMethod HttpMethod => HttpMethod.DELETE; - protected override DeletePitRequest Initializer => new(CallIsolatedPit); + protected override DeletePitRequest Initializer => new(PitId); protected override bool SupportsDeserialization => false; protected override string UrlPath => "/_search/point_in_time"; @@ -69,7 +68,7 @@ protected override void ExpectResponse(DeletePitResponse response) var pit = response.Pits.First(); pit.Successful.Should().BeTrue(); - pit.PitId.Should().Be(CallIsolatedPit); + pit.PitId.Should().Be(PitId); } protected override void OnBeforeCall(IOpenSearchClient client) @@ -78,6 +77,6 @@ protected override void OnBeforeCall(IOpenSearchClient client) if (!pit.IsValid) throw new Exception("Setup: Initial PIT failed."); - CallIsolatedPit = pit.PitId; + PitId = pit.PitId; } } diff --git a/tests/Tests/Search/PointInTime/GetAllPitsApiTests.cs b/tests/Tests/Search/PointInTime/GetAllPitsApiTests.cs index 08e7f69c92..66934e7ddf 100644 --- a/tests/Tests/Search/PointInTime/GetAllPitsApiTests.cs +++ b/tests/Tests/Search/PointInTime/GetAllPitsApiTests.cs @@ -17,20 +17,22 @@ using Tests.Domain; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; +using Xunit; namespace Tests.Search.PointInTime; +[Collection("PitApiTests")] [SkipVersion("<2.4.0", "Point-In-Time search support was added in version 2.4.0")] public sealed class GetAllPitsApiTests : ApiIntegrationTestBase { - private static readonly Dictionary> Pits = new(); - public GetAllPitsApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - private List<(string id, long creationTime)> CallIsolatedPits => Pits.TryGetValue(CallIsolatedValue, out var pits) - ? pits - : Pits[CallIsolatedValue] = new List<(string id, long creationTime)>(); + private List<(string id, long creationTime)> Pits + { + get => ExtendedValue>(nameof(Pits)); + set => ExtendedValue(nameof(Pits), value); + } protected override bool ExpectIsValid => true; @@ -60,7 +62,7 @@ protected override void ExpectResponse(GetAllPitsResponse response) response.Pits.Should() .NotBeNull() .And.HaveCount(5) - .And.BeEquivalentTo(CallIsolatedPits.Select(p => new PitDetail + .And.BeEquivalentTo(Pits.Select(p => new PitDetail { PitId = p.id, CreationTime = p.creationTime, @@ -70,16 +72,16 @@ protected override void ExpectResponse(GetAllPitsResponse response) protected override void OnBeforeCall(IOpenSearchClient client) { + Pits = new List<(string, long)>(); for (var i = 0; i < 5; i++) { var pit = client.CreatePit(OpenSearch.Client.Indices.Index(), c => c.KeepAlive("1h")); if (!pit.IsValid) throw new Exception("Setup: Initial PIT failed."); - CallIsolatedPits.Add((pit.PitId, pit.CreationTime)); + Pits.Add((pit.PitId, pit.CreationTime)); } } - protected override void OnAfterCall(IOpenSearchClient client) => - client.DeletePit(d => d.PitId(CallIsolatedPits.Select(p => p.id))); + protected override void OnAfterCall(IOpenSearchClient client) => client.DeletePit(d => d.PitId(Pits.Select(p => p.id))); } diff --git a/tests/Tests/Search/PointInTime/PitSearchApiTests.cs b/tests/Tests/Search/PointInTime/PitSearchApiTests.cs index fb9b93f850..cab3ab8ae4 100644 --- a/tests/Tests/Search/PointInTime/PitSearchApiTests.cs +++ b/tests/Tests/Search/PointInTime/PitSearchApiTests.cs @@ -6,7 +6,6 @@ */ using System; -using System.Collections.Generic; using System.Linq; using FluentAssertions; using OpenSearch.Client; @@ -16,9 +15,11 @@ using Tests.Core.ManagedOpenSearch.Clusters; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; +using Xunit; namespace Tests.Search.PointInTime; +[Collection("PitApiTests")] [SkipVersion("<2.4.0", "Point-In-Time search support was added in version 2.4.0")] public sealed class PitSearchApiTests : ApiIntegrationTestBase< @@ -29,16 +30,11 @@ public sealed class PitSearchApiTests : SearchRequest > { - private static readonly Dictionary Pits = new(); + private static readonly string IndexName = nameof(PitSearchApiTests).ToLowerInvariant(); + private string _pitId = "default-for-unit-tests"; public PitSearchApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } - private string CallIsolatedPit - { - get => Pits.TryGetValue(CallIsolatedValue, out var pit) ? pit : "default-for-unit-tests"; - set => Pits[CallIsolatedValue] = value; - } - protected override object ExpectJson => new { query = new @@ -47,7 +43,7 @@ private string CallIsolatedPit }, pit = new { - id = CallIsolatedPit, + id = _pitId, keep_alive = "1h" }, track_total_hits = true @@ -59,7 +55,7 @@ private string CallIsolatedPit protected override Func, ISearchRequest> Fluent => s => s .Query(q => q.MatchAll()) .PointInTime(p => p - .Id(CallIsolatedPit) + .Id(_pitId) .KeepAlive("1h")) .TrackTotalHits(); @@ -71,7 +67,7 @@ private string CallIsolatedPit Query = new QueryContainer(new MatchAllQuery()), PointInTime = new OpenSearch.Client.PointInTime { - Id = CallIsolatedPit, + Id = _pitId, KeepAlive = "1h" }, TrackTotalHits = true @@ -91,26 +87,30 @@ protected override void ExpectResponse(ISearchResponse response) .And.BeEquivalentTo(Enumerable.Range(0, 10).Select(i => new Doc { Id = i })); } - protected override void OnBeforeCall(IOpenSearchClient client) + protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueValues values) { var bulkResp = client.Bulk(b => b - .Index(CallIsolatedValue) + .Index(IndexName) .IndexMany(Enumerable.Range(0, 10).Select(i => new Doc { Id = i })) .Refresh(Refresh.WaitFor)); bulkResp.ShouldBeValid(); - var pitResp = client.CreatePit(CallIsolatedValue, p => p.KeepAlive("1h")); + var pitResp = client.CreatePit(IndexName, p => p.KeepAlive("1h")); pitResp.ShouldBeValid(); - CallIsolatedPit = pitResp.PitId; + _pitId = pitResp.PitId; bulkResp = client.Bulk(b => b - .Index(CallIsolatedValue) + .Index(IndexName) .IndexMany(Enumerable.Range(10, 10).Select(i => new Doc { Id = i })) .Refresh(Refresh.WaitFor)); bulkResp.ShouldBeValid(); } - protected override void OnAfterCall(IOpenSearchClient client) => client.DeletePit(d => d.PitId(CallIsolatedPit)); + protected override void IntegrationTeardown(IOpenSearchClient client, CallUniqueValues values) + { + client.DeletePit(d => d.PitId(_pitId)); + client.Indices.Delete(IndexName); + } protected override LazyResponses ClientUsage() => Calls( (c, f) => c.Search(f), From 733162a0448b4d1c55879fc04040c6d922e85bf1 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Thu, 16 Nov 2023 11:25:02 +1300 Subject: [PATCH 12/16] Test data_stream template mapping serialization Signed-off-by: Thomas Farr --- .../PutComposableIndexTemplateApiTests.cs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs index 0743382666..c15c663fbe 100644 --- a/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs +++ b/tests/Tests/Indices/IndexSettings/ComposableIndexTemplates/PutComposableIndexTemplate/PutComposableIndexTemplateApiTests.cs @@ -52,6 +52,13 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage } } } + }, + data_stream = new + { + timestamp_field = new + { + name = "@timestamp" + } } }; @@ -72,13 +79,10 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage .MatchMappingType("*") .Mapping(mm => mm .Generic(g => g - .Index(false) - ) - ) - ) - ) - ) - ); + .Index(false))))))) + .DataStream(ds => ds + .TimestampField(tf => tf + .Name("@timestamp"))); protected override HttpMethod HttpMethod => HttpMethod.PUT; @@ -106,6 +110,13 @@ public PutComposableIndexTemplateApiTests(WritableCluster cluster, EndpointUsage } } } } + }, + DataStream = new DataStreamTemplate + { + TimestampField = new TimestampField + { + Name = "@timestamp" + } } }; From bc669bdf5f1c8092b475f8d7679d300bd913c598 Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Thu, 16 Nov 2023 17:00:42 +1300 Subject: [PATCH 13/16] Update guide and add sample Signed-off-by: Thomas Farr --- OpenSearch.sln.DotSettings | 27 -- guides/index-template.md | 247 ++++++++---------- guides/json.md | 2 +- .../IndexTemplate/IndexTemplateSample.cs | 149 +++++++++++ samples/Samples/Program.cs | 24 ++ .../Program.cs => RawJson/RawJsonSample.cs} | 17 +- samples/Samples/Sample.cs | 42 +++ samples/Samples/Samples.csproj | 4 + .../Samples/Utils/OpenSearchClientOptions.cs | 59 +++++ 9 files changed, 400 insertions(+), 171 deletions(-) create mode 100644 samples/Samples/IndexTemplate/IndexTemplateSample.cs create mode 100644 samples/Samples/Program.cs rename samples/Samples/{RawJsonSample/Program.cs => RawJson/RawJsonSample.cs} (86%) create mode 100644 samples/Samples/Sample.cs create mode 100644 samples/Samples/Utils/OpenSearchClientOptions.cs diff --git a/OpenSearch.sln.DotSettings b/OpenSearch.sln.DotSettings index 0326966f7b..d831b30a7f 100644 --- a/OpenSearch.sln.DotSettings +++ b/OpenSearch.sln.DotSettings @@ -14,33 +14,6 @@ &lt;inspection_tool class="UnnecessaryReturnJS" enabled="false" level="WARNING" enabled_by_default="false" /&gt; &lt;inspection_tool class="WrongPropertyKeyValueDelimiter" enabled="false" level="WEAK WARNING" enabled_by_default="false" /&gt; &lt;/profile&gt;</IDEA_SETTINGS><VBReformatCode>True</VBReformatCode><HtmlReformatCode>True</HtmlReformatCode><CSUpdateFileHeader>True</CSUpdateFileHeader><CSReorderTypeMembers>True</CSReorderTypeMembers><CSReformatCode>True</CSReformatCode></Profile> - /* SPDX-License-Identifier: Apache-2.0 -* -* The OpenSearch Contributors require contributions made to -* this file be licensed under the Apache-2.0 license or a -* compatible open source license. -* -* Modifications Copyright OpenSearch Contributors. See -* GitHub history for details. -* -* Licensed to Elasticsearch B.V. under one or more contributor -* license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright -* ownership. Elasticsearch B.V. licenses this file to you under -* the Apache License, Version 2.0 (the "License"); you may -* not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ - True 56A87048-9065-459B-826D-3DF68B409845/d:Views diff --git a/guides/index-template.md b/guides/index-template.md index 96fe338803..2448ed8696 100644 --- a/guides/index-template.md +++ b/guides/index-template.md @@ -1,10 +1,8 @@ # Index Template Index templates allow you to define default settings, mappings, and aliases for one or more indices during their creation. This guide will teach you how to create index templates and apply them to indices using the OpenSearch .NET client. +See [samples/Samples/IndexTemplate/IndexTemplateSample.cs](../samples/Samples/IndexTemplate/IndexTemplateSample.cs) for a complete working sample. ## Setup -**At the time of writing the API methods related to composable templates do not yet exist in the high-level client, as such this guide makes use of their low-level counterparts.** - - Assuming you have OpenSearch running locally on port 9200, you can create a client instance with the following code: ```csharp @@ -19,95 +17,86 @@ var config = new ConnectionSettings(node) var client = new OpenSearchClient(config);; ``` +The below examples are based off of the following class definition to represent the contents of the index: -## Index Template API Actions +```csharp +public class Book +{ + public string? Title { get; set; } + public string? Author { get; set; } + public DateTime? PublishedOn { get; set; } + public int? Pages { get; set; } +} +``` +## Index Template API Actions ### Create an Index Template You can create an index template to define default settings and mappings for indices of certain patterns. The following example creates an index template named `books` with default settings and mappings for indices of the `books-*` pattern: ```csharp -client.LowLevel.Indices.PutTemplateV2ForAll("books", PostData.Serializable(new -{ - index_patterns = new[] { "books-*" }, - priority = 0, - template = new - { - settings = new - { - index = new - { - number_of_shards = 3, - number_of_replicas = 0 - } - }, - mappings = new - { - properties = new - { - title = new { type = "text" }, - author = new { type = "text" }, - published_on = new { type = "date" }, - pages = new { type = "integer" } - } - } - } -})); +var putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)) + .Map(m => m + .Properties(p => p + .Text(f => f.Name(b => b.Title)) + .Text(f => f.Name(b => b.Author)) + .Date(f => f.Name(b => b.PublishedOn)) + .Number(f => f.Name(b => b.Pages).Type(NumberType.Integer)) + )))); +Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); ``` Now, when you create an index that matches the `books-*` pattern, OpenSearch will automatically apply the template's settings and mappings to the index. Let's create an index named `books-nonfiction` and verify that its settings and mappings match those of the template: ```csharp -client.Indices.Create("books-nonfiction"); -var getResponse = client.Indices.Get("books-nonfiction"); -Console.WriteLine(getResponse.Indices["books-nonfiction"].Mappings.Properties["pages"].Type); // integer +var createIndex = await client.Indices.CreateAsync("books-nonfiction"); +Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + +var getIndex = await client.Indices.GetAsync("books-nonfiction"); +Debug.Assert( + getIndex.Indices["books-nonfiction"].Mappings.Properties["pages"].Type == "integer", + "`pages` property should have `integer` type"); ``` ### Multiple Index Templates ```csharp -var createResponseOne = client.LowLevel.Indices.PutTemplateV2ForAll("books", PostData.Serializable(new -{ - index_patterns = new[] { "books-*" }, - priority = 0, - template = new - { - settings = new - { - index = new - { - number_of_shards = 3, - number_of_replicas = 0 - } - } - } -})); - -client.LowLevel.Indices.PutTemplateV2ForAll("books-fiction", PostData.Serializable(new -{ - index_patterns = new[] { "books-fiction-*" }, - priority = 1, // higher priority than the `books` template - template = new - { - settings = new - { - index = new - { - number_of_shards = 1, - number_of_replicas = 1 - } - } - } -})); +putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)))); +Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + +putTemplate = await client.Indices.PutComposableTemplateAsync("books-fiction", d => d + .IndexPatterns("books-fiction-*") + .Priority(1) // higher priority than the `books` template + .Template(t => t + .Settings(s => s + .NumberOfShards(1) + .NumberOfReplicas(1)))); +Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); ``` When we create an index named `books-fiction-romance`, OpenSearch will apply the `books-fiction-*` template's settings to the index: ```csharp -client.Indices.Create("books-fiction-romance"); -var getResponse = client.Indices.Get("books-fiction-romance"); -Console.WriteLine(getResponse.Indices["books-fiction-romance"].Settings.NumberOfShards); // 1 +createIndex = await client.Indices.CreateAsync("books-fiction-romance"); +Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + +getIndex = await client.Indices.GetAsync("books-fiction-romance"); +Debug.Assert( + getIndex.Indices["books-fiction-romance"].Settings.NumberOfShards == 1, + "`books-fiction-romance` index should have 1 shard"); ``` @@ -115,82 +104,69 @@ Console.WriteLine(getResponse.Indices["books-fiction-romance"].Settings.NumberOf Composable index templates are a new type of index template that allow you to define multiple component templates and compose them into a final template. The following example creates a component template named `books_mappings` with default mappings for indices of the `books-*` and `books-fiction-*` patterns: ```csharp -// Create a component template -client.Cluster.PutComponentTemplate("books_mappings", ct => ct - .Template(t => t - .Map(m => m - .Properties(p => p - .Text(tp => tp - .Name("title")) - .Text(tp => tp - .Name("author")) - .Date(d => d - .Name("published_on")) - .Number(n => n - .Name("pages") - .Type(NumberType.Integer)))))); - -// Create an index template for "books" -var createBooksTemplateResponse = client.LowLevel.Indices.PutTemplateV2ForAll("books", PostData.Serializable(new -{ - index_patterns = new[] { "books-*" }, - composed_of = new[] { "books_mappings" }, - priority = 0, - template = new - { - settings = new - { - index = new - { - number_of_shards = 3, - number_of_replicas = 0 - } - } - } -})); - -// Create an index template for "books-fiction" -var createBooksFictionTemplateResponse = client.LowLevel.Indices.PutTemplateV2ForAll("books-fiction", PostData.Serializable(new -{ - index_patterns = new[] { "books-fiction-*" }, - composed_of = new[] { "books_mappings" }, - priority = 1, - template = new - { - settings = new - { - index = new - { - number_of_shards = 1, - number_of_replicas = 1 - } - } - } -})); +var putComponentTemplate = await client.Cluster.PutComponentTemplateAsync("books_mappings", d => d + .Template(t => t + .Map(m => m + .Properties(p => p + .Text(f => f.Name(b => b.Title)) + .Text(f => f.Name(b => b.Author)) + .Date(f => f.Name(b => b.PublishedOn)) + .Number(f => f.Name(b => b.Pages).Type(NumberType.Integer)) + )))); +Debug.Assert(putComponentTemplate.IsValid, putComponentTemplate.DebugInformation); + +putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .ComposedOf("books_mappings") + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)))); +Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + +putTemplate = await client.Indices.PutComposableTemplateAsync("books-fiction", d => d + .IndexPatterns("books-fiction-*") + .Priority(1) // higher priority than the `books` template + .ComposedOf("books_mappings") + .Template(t => t + .Settings(s => s + .NumberOfShards(1) + .NumberOfReplicas(1)))); +Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); ``` When we create an index named `books-fiction-horror`, OpenSearch will apply the `books-fiction-*` template's settings, and `books_mappings` template mappings to the index: ```csharp -client.Indices.Create("books-fiction-horror"); -var getResponse = client.Indices.Get("books-fiction-horror"); -Console.WriteLine(getResponse.Indices["books-fiction-horror"].Settings.NumberOfShards); // 1 Console.WriteLine(getResponse.Indices["books-fiction-horror"].Mappings.Properties["pages"].Type); // integer +createIndex = await client.Indices.CreateAsync("books-fiction-horror"); +Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + +getIndex = await client.Indices.GetAsync("books-fiction-horror"); +Debug.Assert( + getIndex.Indices["books-fiction-horror"].Settings.NumberOfShards == 1, + "`books-fiction-horror` index should have 1 shard"); +Debug.Assert( + getIndex.Indices["books-fiction-horror"].Mappings.Properties["pages"].Type == "integer", + "`pages` property should have `integer` type"); ``` ### Get an Index Template -You can get an index template with the `GetTemplateV2ForAll` API action. The following example gets the `books` index template: +You can get an index template with the `GetComposableTemplate` API action. The following example gets the `books` index template: ```csharp -var getResponse = client.LowLevel.Indices.GetTemplateV2ForAll("books").Body; -Console.WriteLine($"Get response: {getResponse}"); // Get response: {"books":{"order":0,"index_patterns":["books-*"],"settings":{"index":{"number_of_shards":"3","number_of_replicas":"0"}},"mappings":{},"aliases":{}}} +var getTemplate = await client.Indices.GetComposableTemplateAsync("books"); +Debug.Assert( + getTemplate.IndexTemplates.First().IndexTemplate.IndexPatterns.First() == "books-*", + "First index pattern should be `books-*`"); ``` ### Delete an Index Template -You can delete an index template with the `DeleteTemplateV2ForAll` API action. The following example deletes the `books` index template: +You can delete an index template with the `DeleteComposableTemplate` API action. The following example deletes the `books` index template: ```csharp -var deleteResponse = client.LowLevel.Indices.DeleteTemplateV2ForAll("books"); -Console.WriteLine($"Delete response: {deleteResponse}"); // Delete response: {"acknowledged":true} +var deleteTemplate = await client.Indices.DeleteComposableTemplateAsync("books"); +Debug.Assert(deleteTemplate.IsValid, deleteTemplate.DebugInformation); ``` @@ -198,7 +174,12 @@ Console.WriteLine($"Delete response: {deleteResponse}"); // Delete response: {"a Let's delete all resources created in this guide: ```csharp -client.Indices.Delete("books-"); -client.LowLevel.Indices.DeleteTemplateV2ForAll("books-fiction"); -client.Cluster.DeleteComponentTemplate("books_mappings"); +var deleteIndex = await client.Indices.DeleteAsync("books-*"); +Debug.Assert(deleteIndex.IsValid, deleteIndex.DebugInformation); + +deleteTemplate = await client.Indices.DeleteComposableTemplateAsync("books-fiction"); +Debug.Assert(deleteTemplate.IsValid, deleteTemplate.DebugInformation); + +var deleteComponentTemplate = await client.Cluster.DeleteComponentTemplateAsync("books_mappings"); +Debug.Assert(deleteComponentTemplate.IsValid, deleteComponentTemplate.DebugInformation); ``` diff --git a/guides/json.md b/guides/json.md index 8984c53362..b946b59000 100644 --- a/guides/json.md +++ b/guides/json.md @@ -11,7 +11,7 @@ - [PostData.MultiJson](#postdatamultijson) # 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/RawJsonSample/Program.cs](../samples/Samples/RawJsonSample/Program.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 `client.LowLevel.DoRequest` to do so. See [samples/Samples/RawJson/RawJsonSample.cs](../samples/Samples/RawJson/RawJsonSample.cs) for a complete working sample. ## HTTP Methods diff --git a/samples/Samples/IndexTemplate/IndexTemplateSample.cs b/samples/Samples/IndexTemplate/IndexTemplateSample.cs new file mode 100644 index 0000000000..79aa9a84b4 --- /dev/null +++ b/samples/Samples/IndexTemplate/IndexTemplateSample.cs @@ -0,0 +1,149 @@ +/* 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; + +namespace Samples.IndexTemplate; + +public class IndexTemplateSample : Sample +{ + public IndexTemplateSample() + : base("index-template", "A sample demonstrating how to use the client to create and manage index templates") { } + + protected override async Task Run(IOpenSearchClient client) + { + // Create index template + + var putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)) + .Map(m => m + .Properties(p => p + .Text(f => f.Name(b => b.Title)) + .Text(f => f.Name(b => b.Author)) + .Date(f => f.Name(b => b.PublishedOn)) + .Number(f => f.Name(b => b.Pages).Type(NumberType.Integer)) + )))); + Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + + // Confirm mapping + + var createIndex = await client.Indices.CreateAsync("books-nonfiction"); + Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + var getIndex = await client.Indices.GetAsync("books-nonfiction"); + Debug.Assert( + getIndex.Indices["books-nonfiction"].Mappings.Properties["pages"].Type == "integer", + "`pages` property should have `integer` type"); + + // Multiple index templates + + putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)))); + Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + + putTemplate = await client.Indices.PutComposableTemplateAsync("books-fiction", d => d + .IndexPatterns("books-fiction-*") + .Priority(1) // higher priority than the `books` template + .Template(t => t + .Settings(s => s + .NumberOfShards(1) + .NumberOfReplicas(1)))); + Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + + // Validate settings + + createIndex = await client.Indices.CreateAsync("books-fiction-romance"); + Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + getIndex = await client.Indices.GetAsync("books-fiction-romance"); + Debug.Assert( + getIndex.Indices["books-fiction-romance"].Settings.NumberOfShards == 1, + "`books-fiction-romance` index should have 1 shard"); + + // Component templates + + var putComponentTemplate = await client.Cluster.PutComponentTemplateAsync("books_mappings", d => d + .Template(t => t + .Map(m => m + .Properties(p => p + .Text(f => f.Name(b => b.Title)) + .Text(f => f.Name(b => b.Author)) + .Date(f => f.Name(b => b.PublishedOn)) + .Number(f => f.Name(b => b.Pages).Type(NumberType.Integer)) + )))); + Debug.Assert(putComponentTemplate.IsValid, putComponentTemplate.DebugInformation); + + putTemplate = await client.Indices.PutComposableTemplateAsync("books", d => d + .IndexPatterns("books-*") + .Priority(0) + .ComposedOf("books_mappings") + .Template(t => t + .Settings(s => s + .NumberOfShards(3) + .NumberOfReplicas(0)))); + Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + + putTemplate = await client.Indices.PutComposableTemplateAsync("books-fiction", d => d + .IndexPatterns("books-fiction-*") + .Priority(1) // higher priority than the `books` template + .ComposedOf("books_mappings") + .Template(t => t + .Settings(s => s + .NumberOfShards(1) + .NumberOfReplicas(1)))); + Debug.Assert(putTemplate.IsValid, putTemplate.DebugInformation); + + // Validate settings & mappings + createIndex = await client.Indices.CreateAsync("books-fiction-horror"); + Debug.Assert(createIndex.IsValid, createIndex.DebugInformation); + getIndex = await client.Indices.GetAsync("books-fiction-horror"); + Debug.Assert( + getIndex.Indices["books-fiction-horror"].Settings.NumberOfShards == 1, + "`books-fiction-horror` index should have 1 shard"); + Debug.Assert( + getIndex.Indices["books-fiction-horror"].Mappings.Properties["pages"].Type == "integer", + "`pages` property should have `integer` type"); + + // Get index template + + var getTemplate = await client.Indices.GetComposableTemplateAsync("books"); + Debug.Assert( + getTemplate.IndexTemplates.First().IndexTemplate.IndexPatterns.First() == "books-*", + "First index pattern should be `books-*`"); + + // Delete index template + + var deleteTemplate = await client.Indices.DeleteComposableTemplateAsync("books"); + Debug.Assert(deleteTemplate.IsValid, deleteTemplate.DebugInformation); + + // Cleanup + + var deleteIndex = await client.Indices.DeleteAsync("books-*"); + Debug.Assert(deleteIndex.IsValid, deleteIndex.DebugInformation); + deleteTemplate = await client.Indices.DeleteComposableTemplateAsync("books-fiction"); + Debug.Assert(deleteTemplate.IsValid, deleteTemplate.DebugInformation); + var deleteComponentTemplate = await client.Cluster.DeleteComponentTemplateAsync("books_mappings"); + Debug.Assert(deleteComponentTemplate.IsValid, deleteComponentTemplate.DebugInformation); + } + + private class Book + { + public string? Title { get; set; } + public string? Author { get; set; } + public DateTime? PublishedOn { get; set; } + public int? Pages { get; set; } + } +} diff --git a/samples/Samples/Program.cs b/samples/Samples/Program.cs new file mode 100644 index 0000000000..e4174840de --- /dev/null +++ b/samples/Samples/Program.cs @@ -0,0 +1,24 @@ +/* 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.CommandLine; +using Samples.Utils; + +namespace Samples; + +public static class Program +{ + public static async Task Main(string[] args) + { + var rootCommand = new RootCommand("A collection of samples demonstrating how to use the OpenSearch .NET client"); + var clientDescriptor = rootCommand.AddOpenSearchClientOptions(); + + foreach (var sample in Sample.GetAllSamples()) rootCommand.AddCommand(sample.AsCommand(clientDescriptor)); + + await rootCommand.InvokeAsync(args); + } +} diff --git a/samples/Samples/RawJsonSample/Program.cs b/samples/Samples/RawJson/RawJsonSample.cs similarity index 86% rename from samples/Samples/RawJsonSample/Program.cs rename to samples/Samples/RawJson/RawJsonSample.cs index 2ad5796a72..62a75719ef 100644 --- a/samples/Samples/RawJsonSample/Program.cs +++ b/samples/Samples/RawJson/RawJsonSample.cs @@ -10,19 +10,16 @@ using OpenSearch.Net; using HttpMethod = OpenSearch.Net.HttpMethod; -public class Program -{ - public static async Task Main(string[] args) - { - var node = new Uri("http://localhost:9200"); - var config = new ConnectionSettings(node) - .ServerCertificateValidationCallback(CertificateValidations.AllowAll) - .BasicAuthentication("admin", "admin") - .DisableDirectStreaming(); +namespace Samples.RawJson; - var client = new OpenSearchClient(config); +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 diff --git a/samples/Samples/Sample.cs b/samples/Samples/Sample.cs new file mode 100644 index 0000000000..6126255c99 --- /dev/null +++ b/samples/Samples/Sample.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. +*/ + +using System.CommandLine; +using System.CommandLine.Binding; +using OpenSearch.Client; + +namespace Samples; + +public abstract class Sample +{ + public static IEnumerable GetAllSamples() => + typeof(Sample) + .Assembly + .GetTypes() + .Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(Sample))) + .Select(t => (Sample) Activator.CreateInstance(t)!); + + private readonly string _name; + private readonly string _description; + + protected Sample(string name, string description) + { + _name = name; + _description = description; + } + + public Command AsCommand(IValueDescriptor clientDescriptor) + { + var command = new Command(_name, _description); + + command.SetHandler(Run, clientDescriptor); + + return command; + } + + protected abstract Task Run(IOpenSearchClient client); +} diff --git a/samples/Samples/Samples.csproj b/samples/Samples/Samples.csproj index 684c46b599..6ac00aa311 100644 --- a/samples/Samples/Samples.csproj +++ b/samples/Samples/Samples.csproj @@ -12,4 +12,8 @@ + + + + \ No newline at end of file diff --git a/samples/Samples/Utils/OpenSearchClientOptions.cs b/samples/Samples/Utils/OpenSearchClientOptions.cs new file mode 100644 index 0000000000..ae42bdb387 --- /dev/null +++ b/samples/Samples/Utils/OpenSearchClientOptions.cs @@ -0,0 +1,59 @@ +/* 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.CommandLine; +using System.CommandLine.Binding; +using OpenSearch.Client; +using OpenSearch.Net; + +namespace Samples.Utils; + +public static class OpenSearchClientOptions +{ + public static IValueDescriptor AddOpenSearchClientOptions(this Command command, bool global = true) + { + Option host = new("--host", () => new Uri("https://localhost:9200"), "The OpenSearch host to connect to"); + Option username = new("--username", () => "admin", "The username to use for authentication"); + Option password = new("--password", () => "admin", "The password to use for authentication"); + + Action