/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Net.Security;
using System.Reflection;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using OpenSearch.Net.Extensions;
namespace OpenSearch.Net
{
///
/// Allows you to control how behaves and where/how it connects to OpenSearch
///
public class ConnectionConfiguration : ConnectionConfiguration
{
///
/// Detects whether we are running on .NET Core with CurlHandler.
/// If this is true, we will set a very restrictive
/// As the old curl based handler is known to bleed TCP connections:
/// https://github.com/dotnet/runtime/issues/22366
///
private static bool UsingCurlHandler => ConnectionInfo.UsingCurlHandler;
///
/// The default ping timeout. Defaults to 2 seconds
///
public static readonly TimeSpan DefaultPingTimeout = TimeSpan.FromSeconds(2);
///
/// The default ping timeout when the connection is over HTTPS. Defaults to
/// 5 seconds
///
public static readonly TimeSpan DefaultPingTimeoutOnSSL = TimeSpan.FromSeconds(5);
///
/// The default timeout before the client aborts a request to OpenSearch.
/// Defaults to 1 minute
///
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(1);
///
/// The default timeout before a TCP connection is forcefully recycled so that DNS updates come through
/// Defaults to 5 minutes.
///
public static readonly TimeSpan DefaultDnsRefreshTimeout = TimeSpan.FromMinutes(5);
///
/// The default connection limit for both OpenSearch.Net and OpenSearch.Client. Defaults to 80
/// Except for implementations based on curl, which defaults to
///
public static readonly int DefaultConnectionLimit = UsingCurlHandler ? Environment.ProcessorCount : 80;
///
/// The default user agent for OpenSearch.Net
///
public static readonly string DefaultUserAgent = $"opensearch-net/{typeof(IConnectionConfigurationValues).Assembly.GetCustomAttribute().InformationalVersion} ({RuntimeInformation.OSDescription}; {RuntimeInformation.FrameworkDescription}; OpenSearch.Net)";
///
/// Creates a new instance of
///
/// The root of the OpenSearch node we want to connect to. Defaults to http://localhost:9200
/// A connection implementation that can make API requests. Defaults to
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
public ConnectionConfiguration(Uri uri = null, IConnection connection = null)
: this(new SingleNodeConnectionPool(uri ?? new Uri("http://localhost:9200")), connection) { }
///
/// Sets up the client to communicate to OpenSearch Cloud using ,
/// documentation for more information on how to obtain your Cloud Id
///
public ConnectionConfiguration(string cloudId, BasicAuthenticationCredentials credentials) : this(new CloudConnectionPool(cloudId, credentials)) { }
///
/// Sets up the client to communicate to OpenSearch Cloud using ,
/// documentation for more information on how to obtain your Cloud Id
///
public ConnectionConfiguration(string cloudId, ApiKeyAuthenticationCredentials credentials) : this(new CloudConnectionPool(cloudId, credentials)) { }
///
/// Creates a new instance of
///
/// A connection pool implementation that tells the client what nodes are available
public ConnectionConfiguration(IConnectionPool connectionPool)
// ReSharper disable once IntroduceOptionalParameters.Global
: this(connectionPool, null, null) { }
///
/// Creates a new instance of
///
/// A connection pool implementation that tells the client what nodes are available
/// An connection implementation that can make API requests
public ConnectionConfiguration(IConnectionPool connectionPool, IConnection connection)
// ReSharper disable once IntroduceOptionalParameters.Global
: this(connectionPool, connection, null) { }
///
/// Creates a new instance of
///
/// A connection pool implementation that tells the client what nodes are available
/// A serializer implementation used to serialize requests and deserialize responses
public ConnectionConfiguration(IConnectionPool connectionPool, IOpenSearchSerializer serializer)
: this(connectionPool, null, serializer) { }
///
/// Creates a new instance of
///
/// A connection pool implementation that tells the client what nodes are available
/// An connection implementation that can make API requests
/// A serializer implementation used to serialize requests and deserialize responses
public ConnectionConfiguration(IConnectionPool connectionPool, IConnection connection, IOpenSearchSerializer serializer)
: base(connectionPool, connection, serializer) { }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class ConnectionConfiguration : IConnectionConfigurationValues
where T : ConnectionConfiguration
{
private readonly IConnection _connection;
private readonly IConnectionPool _connectionPool;
private readonly NameValueCollection _headers = new NameValueCollection();
private readonly NameValueCollection _queryString = new NameValueCollection();
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly OpenSearchUrlFormatter _urlFormatter;
private BasicAuthenticationCredentials _basicAuthCredentials;
private ApiKeyAuthenticationCredentials _apiKeyAuthCredentials;
private X509CertificateCollection _clientCertificates;
private Action _completedRequestHandler = DefaultCompletedRequestHandler;
private int _connectionLimit;
private TimeSpan? _deadTimeout;
private bool _disableAutomaticProxyDetection;
private bool _disableDirectStreaming;
private bool _disableMetaHeader;
private bool _disablePings;
private bool _enableHttpCompression;
private bool _enableHttpPipelining = true;
private TimeSpan? _keepAliveInterval;
private TimeSpan? _keepAliveTime;
private TimeSpan? _maxDeadTimeout;
private int? _maxRetries;
private TimeSpan? _maxRetryTimeout;
private Func _nodePredicate = DefaultNodePredicate;
private Action _onRequestDataCreated = DefaultRequestDataCreated;
private TimeSpan? _pingTimeout;
private bool _prettyJson;
private string _proxyAddress;
private SecureString _proxyPassword;
private string _proxyUsername;
private TimeSpan _requestTimeout;
private TimeSpan _dnsRefreshTimeout;
private Func