diff --git a/src/Elastic.Transport/Components/Pipeline/RequestPipeline.cs b/src/Elastic.Transport/Components/Pipeline/RequestPipeline.cs index cfb287c..a5b9864 100644 --- a/src/Elastic.Transport/Components/Pipeline/RequestPipeline.cs +++ b/src/Elastic.Transport/Components/Pipeline/RequestPipeline.cs @@ -58,7 +58,7 @@ private RequestConfiguration PingAndSniffRequestConfiguration PingTimeout = PingTimeout, RequestTimeout = PingTimeout, Authentication = _requestData.AuthenticationHeader, - EnableHttpPipelining = _requestData.HttpPipeliningEnabled, + HttpPipeliningEnabled = _requestData.HttpPipeliningEnabled, ForceNode = _requestData.ForceNode }; diff --git a/src/Elastic.Transport/Configuration/RequestConfiguration.cs b/src/Elastic.Transport/Configuration/RequestConfiguration.cs index 8a2c697..8506fef 100644 --- a/src/Elastic.Transport/Configuration/RequestConfiguration.cs +++ b/src/Elastic.Transport/Configuration/RequestConfiguration.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Security.Cryptography.X509Certificates; + using Elastic.Transport.Extensions; namespace Elastic.Transport; @@ -108,7 +109,6 @@ public interface IRequestConfiguration /// TimeSpan? RequestTimeout { get; } - /// Specifies the headers from the response that should be parsed. HeadersList? ResponseHeadersToParse { get; } @@ -163,6 +163,48 @@ public record RequestConfiguration : IRequestConfiguration /// The default ping timeout when the connection is over HTTPS. Defaults to 5 seconds public static readonly TimeSpan DefaultPingTimeoutOnSsl = TimeSpan.FromSeconds(5); + /// + public RequestConfiguration() + { + } + + /// + public RequestConfiguration(IRequestConfiguration config) + { +#if NET8_0_OR_GREATER + ArgumentNullException.ThrowIfNull(config); +#else + if (config is null) + throw new ArgumentNullException(nameof(config)); +#endif + + Accept = config.Accept; + AllowedStatusCodes = config.AllowedStatusCodes; + Authentication = config.Authentication; + ClientCertificates = (config.ClientCertificates is null) ? null : new X509CertificateCollection(config.ClientCertificates); + ContentType = config.ContentType; + DisableDirectStreaming = config.DisableDirectStreaming; + DisableAuditTrail = config.DisableAuditTrail; + DisablePings = config.DisablePings; + DisableSniff = config.DisableSniff; + HttpPipeliningEnabled = config.HttpPipeliningEnabled; + EnableHttpCompression = config.EnableHttpCompression; + ForceNode = config.ForceNode; + MaxRetries = config.MaxRetries; + MaxRetryTimeout = config.MaxRetryTimeout; + OpaqueId = config.OpaqueId; + PingTimeout = config.PingTimeout; + RequestTimeout = config.RequestTimeout; + RunAs = config.RunAs; + ThrowExceptions = config.ThrowExceptions; + TransferEncodingChunked = config.TransferEncodingChunked; + Headers = (config.Headers is null) ? null : new NameValueCollection(config.Headers); + EnableTcpStats = config.EnableTcpStats; + EnableThreadPoolStats = config.EnableThreadPoolStats; + ResponseHeadersToParse = (config.ResponseHeadersToParse is null) ? null : new HeadersList(config.ResponseHeadersToParse); + ParseAllHeaders = config.ParseAllHeaders; + RequestMetaData = config.RequestMetaData; + } /// public string? Accept { get; init; } @@ -188,18 +230,12 @@ public record RequestConfiguration : IRequestConfiguration /// public bool? DisablePings { get; init; } - /// - public bool? DisablePing { get; init; } - /// public bool? DisableSniff { get; init; } /// public bool? HttpPipeliningEnabled { get; init; } - /// - public bool? EnableHttpPipelining { get; init; } = true; - /// public bool? EnableHttpCompression { get; init; } @@ -247,7 +283,6 @@ public record RequestConfiguration : IRequestConfiguration /// public RequestMetaData? RequestMetaData { get; init; } - } /// @@ -256,6 +291,40 @@ public class RequestConfigurationDescriptor : IRequestConfiguration /// public RequestConfigurationDescriptor() { } + /// + public RequestConfigurationDescriptor(IRequestConfiguration? config) + { + if (config is null) + return; + + _accept = config.Accept; + _allowedStatusCodes= config.AllowedStatusCodes; + _authentication = config.Authentication; + _clientCertificates = (config.ClientCertificates is null) ? null : new X509CertificateCollection(config.ClientCertificates);; + _contentType = config.ContentType; + _disableDirectStreaming = config.DisableDirectStreaming; + _disableAuditTrail = config.DisableAuditTrail; + _disablePings = config.DisablePings; + _disableSniff = config.DisableSniff; + _httpPipeliningEnabled = config.HttpPipeliningEnabled; + _enableHttpCompression = config.EnableHttpCompression; + _forceNode = config.ForceNode; + _maxRetries = config.MaxRetries; + _maxRetryTimeout = config.MaxRetryTimeout; + _opaqueId = config.OpaqueId; + _pingTimeout = config.PingTimeout; + _requestTimeout = config.RequestTimeout; + _runAs = config.RunAs; + _throwExceptions = config.ThrowExceptions; + _transferEncodingChunked = config.TransferEncodingChunked; + _headers = (config.Headers is null) ? null : new NameValueCollection(config.Headers); + _enableTcpStats = config.EnableTcpStats; + _enableThreadPoolStats = config.EnableThreadPoolStats; + _responseHeadersToParse = (config.ResponseHeadersToParse is null) ? null : new HeadersList(config.ResponseHeadersToParse); + _parseAllHeaders = config.ParseAllHeaders; + _requestMetaData = config.RequestMetaData; + } + private string? _accept; private IReadOnlyCollection? _allowedStatusCodes; private AuthorizationHeader? _authentication; @@ -266,8 +335,10 @@ public RequestConfigurationDescriptor() { } private bool? _disablePings; private bool? _disableSniff; private bool? _httpPipeliningEnabled; + private bool? _enableHttpCompression; private Uri? _forceNode; private int? _maxRetries; + private TimeSpan? _maxRetryTimeout; private string? _opaqueId; private bool? _parseAllHeaders; private TimeSpan? _pingTimeout; @@ -281,12 +352,6 @@ public RequestConfigurationDescriptor() { } private bool? _enableThreadPoolStats; private RequestMetaData? _requestMetaData; -#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value - private bool? _enableHttpCompression; - private TimeSpan? _maxRetryTimeout; -#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value - - /// public RequestConfigurationDescriptor RunAs(string username) { @@ -392,6 +457,13 @@ public RequestConfigurationDescriptor MaxRetries(int retry) return this; } + /// + public RequestConfigurationDescriptor MaxRetries(TimeSpan? timeout) + { + _maxRetryTimeout = timeout; + return this; + } + /// public RequestConfigurationDescriptor Authentication(AuthorizationHeader authentication) { @@ -406,6 +478,13 @@ public RequestConfigurationDescriptor EnableHttpPipelining(bool enable = true) return this; } + /// + public RequestConfigurationDescriptor EnableHttpCompression(bool enable = true) + { + _enableHttpCompression = enable; + return this; + } + /// public RequestConfigurationDescriptor ClientCertificates(X509CertificateCollection certificates) { diff --git a/tests/Elastic.Transport.Tests/Configuration/RequestConfigurationTests.cs b/tests/Elastic.Transport.Tests/Configuration/RequestConfigurationTests.cs new file mode 100644 index 0000000..4380c75 --- /dev/null +++ b/tests/Elastic.Transport.Tests/Configuration/RequestConfigurationTests.cs @@ -0,0 +1,54 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using FluentAssertions; +using Xunit; +#if !NETFRAMEWORK +using Soenneker.Utils.AutoBogus; +#endif + +namespace Elastic.Transport.Tests.Configuration; + +public class RequestConfigurationTests +{ + [Fact] + public void CopiesAllDefaults() + { + var config = new RequestConfiguration(); + var newConfig = new RequestConfiguration(config); + + config.Should().BeEquivalentTo(newConfig); + } + + [Fact] + public void SameDefaults() + { + IRequestConfiguration config = new RequestConfiguration(); + IRequestConfiguration newConfig = new RequestConfigurationDescriptor(); + + config.Should().BeEquivalentTo(newConfig); + } + +#if !NETFRAMEWORK + [Fact] + public void CopiesAllProperties() + { + var autoFaker = new AutoFaker(); + autoFaker.RuleFor(x => x.ClientCertificates, f => new X509CertificateCollection()); + + var config = autoFaker.Generate(); + config.Accept.Should().NotBeEmpty(); + config.ClientCertificates.Should().NotBeNull(); + + IRequestConfiguration newConfig = new RequestConfiguration(config); + config.Should().BeEquivalentTo(newConfig); + + IRequestConfiguration newDescriptor = new RequestConfigurationDescriptor(config); + config.Should().BeEquivalentTo(newDescriptor); + } +#endif +}