/* 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.Specialized;
using System.Security;
using System.Security.Cryptography.X509Certificates;
namespace OpenSearch.Net
{
public interface IRequestConfiguration
{
///
/// Force a different Accept header on the request
///
string Accept { get; set; }
///
/// Treat the following statuses (on top of the 200 range) NOT as error.
///
IReadOnlyCollection AllowedStatusCodes { get; set; }
///
/// Basic access authorization credentials to specify with this request.
/// Overrides any credentials that are set at the global IConnectionSettings level.
///
///
/// Cannot be used in conjunction with
///
BasicAuthenticationCredentials BasicAuthenticationCredentials { get; set; }
///
/// An API-key authorization credentials to specify with this request.
/// Overrides any credentials that are set at the global IConnectionSettings level.
///
///
/// Cannot be used in conjunction with
///
ApiKeyAuthenticationCredentials ApiKeyAuthenticationCredentials { get; set; }
///
/// Use the following client certificates to authenticate this single request
///
X509CertificateCollection ClientCertificates { get; set; }
///
/// Force a different Content-Type header on the request
///
string ContentType { get; set; }
///
/// Whether to buffer the request and response bytes for the call
///
bool? DisableDirectStreaming { get; set; }
///
/// Under no circumstance do a ping before the actual call. If a node was previously dead a small ping with
/// low connect timeout will be tried first in normal circumstances
///
bool? DisablePing { get; set; }
///
/// Forces no sniffing to occur on the request no matter what configuration is in place
/// globally
///
bool? DisableSniff { get; set; }
///
/// Whether or not this request should be pipelined. http://en.wikipedia.org/wiki/HTTP_pipelining defaults to true
///
bool? EnableHttpPipelining { get; set; }
///
/// This will force the operation on the specified node, this will bypass any configured connection pool and will no retry.
///
Uri ForceNode { get; set; }
///
/// This will override whatever is set on the connection configuration or whatever default the connectionpool has.
///
int? MaxRetries { get; set; }
///
/// Associate an Id with this user-initiated task, such that it can be located in the cluster task list.
///
string OpaqueId { get; set; }
///
/// The ping timeout for this specific request
///
TimeSpan? PingTimeout { get; set; }
///
/// The timeout for this specific request, takes precedence over the global timeout settings
///
TimeSpan? RequestTimeout { get; set; }
///
/// Submit the request on behalf in the context of a different shield user
///
///
string RunAs { get; set; }
///
/// Instead of following a c/go like error checking on response.IsValid do throw an exception (except when is false)
/// on the client when a call resulted in an exception on either the client or the OpenSearch server.
/// Reasons for such exceptions could be search parser errors, index missing exceptions, etc...
///
bool? ThrowExceptions { get; set; }
///
/// Whether the request should be sent with chunked Transfer-Encoding.
///
bool? TransferEncodingChunked { get; set; }
///
/// Try to send these headers for this single request
///
NameValueCollection Headers { get; set; }
///
bool? EnableTcpStats { get; set; }
///
bool? EnableThreadPoolStats { get; set; }
///
/// Holds additional meta data about the request.
///
RequestMetaData RequestMetaData { get; set; }
}
public class RequestConfiguration : IRequestConfiguration
{
///
public string Accept { get; set; }
///
public IReadOnlyCollection AllowedStatusCodes { get; set; }
///
public BasicAuthenticationCredentials BasicAuthenticationCredentials { get; set; }
///
public ApiKeyAuthenticationCredentials ApiKeyAuthenticationCredentials { get; set; }
///
public X509CertificateCollection ClientCertificates { get; set; }
///
public string ContentType { get; set; }
///
public bool? DisableDirectStreaming { get; set; }
///
public bool? DisablePing { get; set; }
///
public bool? DisableSniff { get; set; }
///
public bool? EnableHttpPipelining { get; set; } = true;
///
public Uri ForceNode { get; set; }
///
public int? MaxRetries { get; set; }
///
public string OpaqueId { get; set; }
///
public TimeSpan? PingTimeout { get; set; }
///
public TimeSpan? RequestTimeout { get; set; }
///
public string RunAs { get; set; }
///
public bool? ThrowExceptions { get; set; }
///
public bool? TransferEncodingChunked { get; set; }
///
public NameValueCollection Headers { get; set; }
///
public bool? EnableTcpStats { get; set; }
///
public bool? EnableThreadPoolStats { get; set; }
///
public RequestMetaData RequestMetaData { get; set; }
}
public class RequestConfigurationDescriptor : IRequestConfiguration
{
public RequestConfigurationDescriptor(IRequestConfiguration config)
{
Self.RequestTimeout = config?.RequestTimeout;
Self.PingTimeout = config?.PingTimeout;
Self.ContentType = config?.ContentType;
Self.Accept = config?.Accept;
Self.MaxRetries = config?.MaxRetries;
Self.ForceNode = config?.ForceNode;
Self.DisableSniff = config?.DisableSniff;
Self.DisablePing = config?.DisablePing;
Self.DisableDirectStreaming = config?.DisableDirectStreaming;
Self.AllowedStatusCodes = config?.AllowedStatusCodes;
Self.BasicAuthenticationCredentials = config?.BasicAuthenticationCredentials;
Self.ApiKeyAuthenticationCredentials = config?.ApiKeyAuthenticationCredentials;
Self.EnableHttpPipelining = config?.EnableHttpPipelining ?? true;
Self.RunAs = config?.RunAs;
Self.ClientCertificates = config?.ClientCertificates;
Self.ThrowExceptions = config?.ThrowExceptions;
Self.OpaqueId = config?.OpaqueId;
Self.TransferEncodingChunked = config?.TransferEncodingChunked;
Self.Headers = config?.Headers;
Self.EnableTcpStats = config?.EnableTcpStats;
Self.EnableThreadPoolStats = config?.EnableThreadPoolStats;
}
string IRequestConfiguration.Accept { get; set; }
IReadOnlyCollection IRequestConfiguration.AllowedStatusCodes { get; set; }
BasicAuthenticationCredentials IRequestConfiguration.BasicAuthenticationCredentials { get; set; }
ApiKeyAuthenticationCredentials IRequestConfiguration.ApiKeyAuthenticationCredentials { get; set; }
X509CertificateCollection IRequestConfiguration.ClientCertificates { get; set; }
string IRequestConfiguration.ContentType { get; set; }
bool? IRequestConfiguration.DisableDirectStreaming { get; set; }
bool? IRequestConfiguration.DisablePing { get; set; }
bool? IRequestConfiguration.DisableSniff { get; set; }
bool? IRequestConfiguration.EnableHttpPipelining { get; set; } = true;
Uri IRequestConfiguration.ForceNode { get; set; }
int? IRequestConfiguration.MaxRetries { get; set; }
string IRequestConfiguration.OpaqueId { get; set; }
TimeSpan? IRequestConfiguration.PingTimeout { get; set; }
TimeSpan? IRequestConfiguration.RequestTimeout { get; set; }
string IRequestConfiguration.RunAs { get; set; }
private IRequestConfiguration Self => this;
bool? IRequestConfiguration.ThrowExceptions { get; set; }
bool? IRequestConfiguration.TransferEncodingChunked { get; set; }
NameValueCollection IRequestConfiguration.Headers { get; set; }
bool? IRequestConfiguration.EnableTcpStats { get; set; }
bool? IRequestConfiguration.EnableThreadPoolStats { get; set; }
RequestMetaData IRequestConfiguration.RequestMetaData { get; set; }
///
/// Submit the request on behalf in the context of a different shield user
///
///
public RequestConfigurationDescriptor RunAs(string username)
{
Self.RunAs = username;
return this;
}
public RequestConfigurationDescriptor RequestTimeout(TimeSpan requestTimeout)
{
Self.RequestTimeout = requestTimeout;
return this;
}
///
/// Associate an Id with this user-initiated task, such that it can be located in the cluster task list.
///
public RequestConfigurationDescriptor OpaqueId(string opaqueId)
{
Self.OpaqueId = opaqueId;
return this;
}
public RequestConfigurationDescriptor PingTimeout(TimeSpan pingTimeout)
{
Self.PingTimeout = pingTimeout;
return this;
}
public RequestConfigurationDescriptor ContentType(string contentTypeHeader)
{
Self.ContentType = contentTypeHeader;
return this;
}
public RequestConfigurationDescriptor Accept(string acceptHeader)
{
Self.Accept = acceptHeader;
return this;
}
public RequestConfigurationDescriptor AllowedStatusCodes(IEnumerable codes)
{
Self.AllowedStatusCodes = codes?.ToReadOnlyCollection();
return this;
}
public RequestConfigurationDescriptor AllowedStatusCodes(params int[] codes)
{
Self.AllowedStatusCodes = codes?.ToReadOnlyCollection();
return this;
}
public RequestConfigurationDescriptor DisableSniffing(bool? disable = true)
{
Self.DisableSniff = disable;
return this;
}
public RequestConfigurationDescriptor DisablePing(bool? disable = true)
{
Self.DisablePing = disable;
return this;
}
public RequestConfigurationDescriptor ThrowExceptions(bool throwExceptions = true)
{
Self.ThrowExceptions = throwExceptions;
return this;
}
public RequestConfigurationDescriptor DisableDirectStreaming(bool? disable = true)
{
Self.DisableDirectStreaming = disable;
return this;
}
public RequestConfigurationDescriptor ForceNode(Uri uri)
{
Self.ForceNode = uri;
return this;
}
public RequestConfigurationDescriptor MaxRetries(int retry)
{
Self.MaxRetries = retry;
return this;
}
public RequestConfigurationDescriptor BasicAuthentication(string userName, string password)
{
if (Self.BasicAuthenticationCredentials == null)
Self.BasicAuthenticationCredentials = new BasicAuthenticationCredentials();
Self.BasicAuthenticationCredentials.Username = userName;
Self.BasicAuthenticationCredentials.Password = password.CreateSecureString();
return this;
}
public RequestConfigurationDescriptor BasicAuthentication(string userName, SecureString password)
{
if (Self.BasicAuthenticationCredentials == null)
Self.BasicAuthenticationCredentials = new BasicAuthenticationCredentials();
Self.BasicAuthenticationCredentials.Username = userName;
Self.BasicAuthenticationCredentials.Password = password;
return this;
}
public RequestConfigurationDescriptor ApiKeyAuthentication(string id, string apiKey)
{
Self.ApiKeyAuthenticationCredentials = new ApiKeyAuthenticationCredentials(id, apiKey);
return this;
}
public RequestConfigurationDescriptor ApiKeyAuthentication(string id, SecureString apiKey)
{
Self.ApiKeyAuthenticationCredentials = new ApiKeyAuthenticationCredentials(id, apiKey);
return this;
}
public RequestConfigurationDescriptor ApiKeyAuthentication(string base64EncodedApiKey)
{
Self.ApiKeyAuthenticationCredentials = new ApiKeyAuthenticationCredentials(base64EncodedApiKey);
return this;
}
public RequestConfigurationDescriptor ApiKeyAuthentication(SecureString base64EncodedApiKey)
{
Self.ApiKeyAuthenticationCredentials = new ApiKeyAuthenticationCredentials(base64EncodedApiKey);
return this;
}
public RequestConfigurationDescriptor EnableHttpPipelining(bool enable = true)
{
Self.EnableHttpPipelining = enable;
return this;
}
/// Use the following client certificates to authenticate this request to OpenSearch
public RequestConfigurationDescriptor ClientCertificates(X509CertificateCollection certificates)
{
Self.ClientCertificates = certificates;
return this;
}
/// Use the following client certificate to authenticate this request to OpenSearch
public RequestConfigurationDescriptor ClientCertificate(X509Certificate certificate) =>
ClientCertificates(new X509Certificate2Collection { certificate });
/// Use the following client certificate to authenticate this request to OpenSearch
public RequestConfigurationDescriptor ClientCertificate(string certificatePath) =>
ClientCertificates(new X509Certificate2Collection { new X509Certificate(certificatePath) });
///
public RequestConfigurationDescriptor TransferEncodingChunked(bool? transferEncodingChunked = true)
{
Self.TransferEncodingChunked = transferEncodingChunked;
return this;
}
///
public RequestConfigurationDescriptor GlobalHeaders(NameValueCollection headers)
{
Self.Headers = headers;
return this;
}
///
public RequestConfigurationDescriptor EnableTcpStats(bool? enableTcpStats = true)
{
Self.EnableTcpStats = enableTcpStats;
return this;
}
///
public RequestConfigurationDescriptor EnableThreadPoolStats(bool? enableThreadPoolStats = true)
{
Self.EnableThreadPoolStats = enableThreadPoolStats;
return this;
}
///
internal RequestConfigurationDescriptor RequestMetaData(RequestMetaData metaData)
{
Self.RequestMetaData = metaData;
return this;
}
}
}