// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Azure.Core; using Azure.Core.Pipeline; using Azure.Core.Serialization; using Microsoft.Extensions.Configuration; using Typespec = Microsoft.TypeSpec.Generator.Customizations; #pragma warning disable SA1402 // File may only contain a single type namespace Azure.Search.Documents { /// /// Provides the client configuration options for connecting to Azure /// Cognitive Search. /// [Typespec.CodeGenType("DocumentsClientOptions")] public partial class SearchClientOptions : ClientOptions { /// /// The versions of Azure Cognitive Search supported by this client /// library. For more, see /// /// API versions in Azure Cognitive Search. /// public enum ServiceVersion { #pragma warning disable CA1707 // Identifiers should not contain underscores /// /// The 2020-06-30 version of the Azure Cognitive Search service. /// V2020_06_30 = 1, /// /// The 2023-11-01 version of the Azure Cognitive Search service. /// V2023_11_01 = 2, /// /// The 2024-07-01 version of the Azure Cognitive Search service. /// V2024_07_01 = 3, /// /// The 2025-09-01 version of the Azure Cognitive Search service. /// V2025_09_01 = 4, /// /// The 2026-04-01 version of the Azure AI Search service. /// V2026_04_01 = 5, /// /// The 2026-05-01-preview version of the Azure AI Search service. /// V2026_05_01_Preview = 6, #pragma warning restore CA1707 } /// /// The Latest service version supported by this client library. /// internal const ServiceVersion LatestVersion = ServiceVersion.V2026_05_01_Preview; /// /// The service version to use when creating continuation tokens that /// can be passed between different client libraries. Changing this /// value requires updating . /// internal const ServiceVersion ContinuationTokenVersion = ServiceVersion.V2020_06_30; [Typespec.CodeGenMember("Version")] internal string RawVersion { get; } /// /// Gets the of the service API used when /// making requests. For more, see /// /// API versions in Azure Cognitive Search. /// public ServiceVersion Version { get; } /// /// Gets or sets an that can be used to /// customize the serialization of strongly typed models. The /// serializer needs to support JSON and /// will be used if no value is provided. /// public ObjectSerializer Serializer { get; set; } /// /// Gets or sets the Audience to use for authentication with Azure Active Directory (AAD). The audience is not considered when using a shared key. /// /// If null, will be assumed. public SearchAudience? Audience { get; set; } /// /// Initializes a new instance of the /// class. /// /// /// An optional to specify the version of /// the REST API to use. For more, see /// /// API versions in Azure Cognitive Search. /// /// If not provided, the will default to the /// latest supported by this client library. It is recommended that /// application authors allow the version to float to the latest and /// library authors pin to a specific version. /// /// /// Thrown when the is not supported by this /// client library. /// public SearchClientOptions(ServiceVersion version = LatestVersion) { Version = version.Validate(); AddLoggingHeaders(); AddLoggingQueryParameters(); } /// /// Initializes a new instance of from configuration. /// /// The configuration section. [Experimental("SCME0002")] internal SearchClientOptions(IConfigurationSection section) : base(section, null) { Version = LatestVersion; if (section is null || !section.Exists()) { return; } if (section["Version"] is string version && TryGetServiceVersion(version, out ServiceVersion serviceVersion)) { Version = serviceVersion; } AddLoggingHeaders(); AddLoggingQueryParameters(); } /// /// Create an to send requests to the Search /// Service. /// /// /// The to authenticate requests. /// /// An to send requests. internal HttpPipeline Build(AzureKeyCredential credential) { Debug.Assert(credential != null); return HttpPipelineBuilder.Build( options: this, perCallPolicies: new[] { new AzureKeyCredentialPolicy(credential, Constants.ApiKeyHeaderName) }, perRetryPolicies: Array.Empty(), responseClassifier: null); } /// /// Create an to send requests to the Search service. /// /// /// The to authenticate requests. /// /// An to send requests. internal HttpPipeline Build(TokenCredential credential) { Debug.Assert(credential != null); var authorizationScope = $"{(string.IsNullOrEmpty(Audience?.ToString()) ? SearchAudience.AzurePublicCloud : Audience)}/.default"; return HttpPipelineBuilder.Build( options: this, perCallPolicies: new[] { new BearerTokenAuthenticationPolicy(credential, authorizationScope) }, perRetryPolicies: Array.Empty(), responseClassifier: null); } /// /// Add the allow list headers to the /// that are considered safe for logging/exceptions by default. /// private void AddLoggingHeaders() { Diagnostics.LoggedHeaderNames.Add("Access-Control-Allow-Credentials"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Allow-Headers"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Allow-Methods"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Allow-Origin"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Expose-Headers"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Max-Age"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Request-Headers"); Diagnostics.LoggedHeaderNames.Add("Access-Control-Request-Method"); Diagnostics.LoggedHeaderNames.Add("client-request-id"); Diagnostics.LoggedHeaderNames.Add("elapsed-time"); Diagnostics.LoggedHeaderNames.Add("Location"); Diagnostics.LoggedHeaderNames.Add("OData-MaxVersion"); Diagnostics.LoggedHeaderNames.Add("OData-Version"); Diagnostics.LoggedHeaderNames.Add("Origin"); Diagnostics.LoggedHeaderNames.Add("Prefer"); Diagnostics.LoggedHeaderNames.Add("request-id"); Diagnostics.LoggedHeaderNames.Add("return-client-request-id"); Diagnostics.LoggedHeaderNames.Add("throttle-reason"); } /// /// Add the allow list query parameters to the /// that are considered safe for /// logging/exceptions by default. /// private void AddLoggingQueryParameters() { Diagnostics.LoggedQueryParameters.Add("allowIndexDowntime"); } /// /// Attempts to parse a version string into a value. /// /// The version string to parse (e.g. "2024-07-01"). /// When this method returns true, the parsed . /// true if the version string corresponds to a valid API version; otherwise, false. internal static bool TryGetServiceVersion(string version, out ServiceVersion serviceVersion) { serviceVersion = default; switch (version) { case "2020-06-30": serviceVersion = ServiceVersion.V2020_06_30; return true; case "2023-11-01": serviceVersion = ServiceVersion.V2023_11_01; return true; case "2024-07-01": serviceVersion = ServiceVersion.V2024_07_01; return true; case "2025-09-01": serviceVersion = ServiceVersion.V2025_09_01; return true; case "2026-04-01": serviceVersion = ServiceVersion.V2026_04_01; return true; case "2026-05-01-preview": serviceVersion = ServiceVersion.V2026_05_01_Preview; return true; default: return false; } } } /// /// Search extension methods. /// internal static partial class InternalSearchExtensions { /// /// Validate a . /// /// /// The to validate. /// /// /// The validated version. /// /// /// Thrown when the is not supported by this /// client library. /// public static SearchClientOptions.ServiceVersion Validate(this SearchClientOptions.ServiceVersion version) => version switch { SearchClientOptions.ServiceVersion.V2020_06_30 => version, SearchClientOptions.ServiceVersion.V2023_11_01 => version, SearchClientOptions.ServiceVersion.V2024_07_01 => version, SearchClientOptions.ServiceVersion.V2025_09_01 => version, SearchClientOptions.ServiceVersion.V2026_04_01 => version, SearchClientOptions.ServiceVersion.V2026_05_01_Preview => version, _ => throw CreateInvalidVersionException(version) }; /// /// Get a version string, like "2020-06-30", corresponding to a given /// value. /// /// /// The value to /// convert into a version string. /// /// /// The version string. /// /// /// Thrown when the is not supported by this /// client library. /// public static string ToVersionString(this SearchClientOptions.ServiceVersion version) => version switch { SearchClientOptions.ServiceVersion.V2020_06_30 => "2020-06-30", SearchClientOptions.ServiceVersion.V2023_11_01 => "2023-11-01", SearchClientOptions.ServiceVersion.V2024_07_01 => "2024-07-01", SearchClientOptions.ServiceVersion.V2025_09_01 => "2025-09-01", SearchClientOptions.ServiceVersion.V2026_04_01 => "2026-04-01", SearchClientOptions.ServiceVersion.V2026_05_01_Preview => "2026-05-01-preview", _ => throw CreateInvalidVersionException(version) }; /// /// Convert a version string into a . /// public static SearchClientOptions.ServiceVersion ToServiceVersion(this string version) => version switch { "2020-06-30" => SearchClientOptions.ServiceVersion.V2020_06_30, "2023-11-01" => SearchClientOptions.ServiceVersion.V2023_11_01, "2024-07-01" => SearchClientOptions.ServiceVersion.V2024_07_01, "2025-09-01" => SearchClientOptions.ServiceVersion.V2025_09_01, "2026-04-01" => SearchClientOptions.ServiceVersion.V2026_04_01, "2026-05-01-preview" => SearchClientOptions.ServiceVersion.V2026_05_01_Preview, _ => throw new ArgumentOutOfRangeException( nameof(version), version, $"The version string specified is not supported by this library.") }; /// /// Create an to throw when /// an invalid value /// is provided. /// /// The invalid version value. /// An exception to throw. private static ArgumentOutOfRangeException CreateInvalidVersionException(SearchClientOptions.ServiceVersion version) => new ArgumentOutOfRangeException( nameof(version), version, $"The {nameof(SearchClientOptions)}.{nameof(SearchClientOptions.ServiceVersion)} specified is not supported by this library."); } }