From c3581cd51b83453c20a4ac49010da8023e013612 Mon Sep 17 00:00:00 2001 From: Geir-Tore Lindsve Date: Tue, 27 Jun 2023 16:00:45 +0200 Subject: [PATCH 1/3] Added support for including a client certificate for certificate validation --- Src/Witsml/QueryLogger.cs | 33 ++++ Src/Witsml/QueryResult.cs | 13 ++ Src/Witsml/WitsmlClient.cs | 142 +++--------------- Src/Witsml/WitsmlClientBase.cs | 75 +++++++++ Src/Witsml/WitsmlClientOptions.cs | 42 ++++++ .../Witsml.Tests/ClientCertificateExample.cs | 24 +++ 6 files changed, 212 insertions(+), 117 deletions(-) create mode 100644 Src/Witsml/QueryLogger.cs create mode 100644 Src/Witsml/QueryResult.cs create mode 100644 Src/Witsml/WitsmlClientBase.cs create mode 100644 Src/Witsml/WitsmlClientOptions.cs create mode 100644 Tests/Witsml.Tests/ClientCertificateExample.cs diff --git a/Src/Witsml/QueryLogger.cs b/Src/Witsml/QueryLogger.cs new file mode 100644 index 000000000..3dbae387c --- /dev/null +++ b/Src/Witsml/QueryLogger.cs @@ -0,0 +1,33 @@ +using Serilog; +using Serilog.Core; + +namespace Witsml; + +public interface IQueryLogger +{ + void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null); +} + +public class DefaultQueryLogger : IQueryLogger +{ + private readonly Logger _queryLogger; + + public DefaultQueryLogger() + { + _queryLogger = new LoggerConfiguration() + .WriteTo.File("queries.log", rollOnFileSizeLimit: true, retainedFileCountLimit: 1, fileSizeLimitBytes: 50000000) + .CreateLogger(); + } + + public void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null) + { + if (xmlReceived != null) + { + _queryLogger.Information("Query: \n{Query}\nReceived: \n{Response}\nIsSuccessful: {IsSuccessful}", querySent, xmlReceived, isSuccessful); + } + else + { + _queryLogger.Information("Query: \n{Query}\nIsSuccessful: {IsSuccessful}", querySent, isSuccessful); + } + } +} diff --git a/Src/Witsml/QueryResult.cs b/Src/Witsml/QueryResult.cs new file mode 100644 index 000000000..9ec853b9f --- /dev/null +++ b/Src/Witsml/QueryResult.cs @@ -0,0 +1,13 @@ +namespace Witsml; + +public class QueryResult +{ + public bool IsSuccessful { get; } + public string Reason { get; } + + public QueryResult(bool isSuccessful, string reason = null) + { + IsSuccessful = isSuccessful; + Reason = reason; + } +} diff --git a/Src/Witsml/WitsmlClient.cs b/Src/Witsml/WitsmlClient.cs index 34eb513ef..fb6d4f915 100644 --- a/Src/Witsml/WitsmlClient.cs +++ b/Src/Witsml/WitsmlClient.cs @@ -1,12 +1,10 @@ using System; using System.Linq; -using System.ServiceModel; using System.ServiceModel.Security; using System.Threading.Tasks; using System.Xml; using Serilog; -using Serilog.Core; using Witsml.Data; using Witsml.Extensions; @@ -28,50 +26,43 @@ public interface IWitsmlClient Uri GetServerHostname(); } - public class WitsmlClient : IWitsmlClient + public class WitsmlClient : WitsmlClientBase, IWitsmlClient { private readonly string _clientCapabilities; private readonly StoreSoapPortClient _client; private readonly Uri _serverUrl; private IQueryLogger _queryLogger; - public WitsmlClient(string hostname, string username, string password, WitsmlClientCapabilities clientCapabilities, TimeSpan? requestTimeout = null, bool logQueries = false) - { - if (string.IsNullOrEmpty(hostname)) - { - throw new ArgumentNullException(nameof(hostname), "Hostname is required"); - } - - if (string.IsNullOrEmpty(username)) + [Obsolete("Use the WitsmlClientOptions based constructor instead")] + public WitsmlClient(string hostname, string username, string password, WitsmlClientCapabilities clientCapabilities, TimeSpan? requestTimeout = null, + bool logQueries = false) + : this(new WitsmlClientOptions { - throw new ArgumentNullException(nameof(username), "Username is required"); - } - - if (string.IsNullOrEmpty(password)) - { - throw new ArgumentNullException(nameof(password), "Password is required"); - } - - _clientCapabilities = clientCapabilities.ToXml(); + Hostname = hostname, + Credentials = new WitsmlCredentials(username, password), + ClientCapabilities = clientCapabilities, + RequestTimeOut = requestTimeout ?? TimeSpan.FromMinutes(1), + LogQueries = logQueries + }) { } + + public WitsmlClient(WitsmlClientOptions options) + { + ArgumentNullException.ThrowIfNull(options.Hostname); + ArgumentNullException.ThrowIfNull(options.Credentials.Username); + ArgumentNullException.ThrowIfNull(options.Credentials.Password); - BasicHttpsBinding serviceBinding = CreateBinding(requestTimeout ?? TimeSpan.FromMinutes(1)); - EndpointAddress endpointAddress = new(hostname); + _clientCapabilities = options.ClientCapabilities.ToXml(); + _serverUrl = new Uri(options.Hostname); - _client = new StoreSoapPortClient(serviceBinding, endpointAddress); - _client.ClientCredentials.UserName.UserName = username; - _client.ClientCredentials.UserName.Password = password; - _serverUrl = new Uri(hostname); + _client = CreateSoapClient(options); - _client.Endpoint.EndpointBehaviors.Add(new EndpointBehavior()); - SetupQueryLogging(logQueries); + SetupQueryLogging(options.LogQueries); } private void SetupQueryLogging(bool logQueries) { if (!logQueries) - { return; - } SetQueryLogger(new DefaultQueryLogger()); } @@ -81,24 +72,6 @@ public void SetQueryLogger(IQueryLogger queryLogger) _queryLogger = queryLogger; } - private static BasicHttpsBinding CreateBinding(TimeSpan requestTimeout) - { - BasicHttpsBinding binding = new() - { - Security = - { - Mode = BasicHttpsSecurityMode.Transport, - Transport = - { - ClientCredentialType = HttpClientCredentialType.Basic - } - }, - MaxReceivedMessageSize = int.MaxValue, - SendTimeout = requestTimeout - }; - return binding; - } - /// /// Returns one or more WITSML data-objects from the server /// @@ -154,9 +127,7 @@ private async Task GetFromStoreInnerAsync(T query, OptionsIn optionsIn) wh LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful(), response.XMLout); if (response.IsSuccessful()) - { return XmlHelper.Deserialize(response.XMLout, query); - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); throw new Exception($"Error while querying store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"); @@ -186,9 +157,7 @@ private async Task GetFromStoreInnerAsync(T query, OptionsIn optionsIn) wh LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful(), response.XMLout); if (response.IsSuccessful()) - { return (XmlHelper.Deserialize(response.XMLout, query), response.Result); - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); throw new Exception($"Error while querying store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"); @@ -221,9 +190,7 @@ public async Task GetFromStoreAsync(string query, OptionsIn optionsIn) WMLS_GetFromStoreResponse response = await _client.WMLS_GetFromStoreAsync(request); if (response.IsSuccessful()) - { return response.XMLout; - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); throw new Exception($"Error while querying store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"); @@ -246,9 +213,7 @@ public async Task AddToStoreAsync(T query) where T : IWitsmlQuer LogQueriesSentAndReceived(request.XMLin, response.IsSuccessful()); if (response.IsSuccessful()) - { return new QueryResult(true); - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); string message = $"Error while adding to store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"; @@ -278,9 +243,7 @@ public async Task UpdateInStoreAsync(T query) where T : IWitsmlQ LogQueriesSentAndReceived(request.XMLin, response.IsSuccessful()); if (response.IsSuccessful()) - { return new QueryResult(true); - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); string message = $"Error while updating store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"; @@ -310,9 +273,7 @@ public async Task DeleteFromStoreAsync(T query) where T : IWitsm LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful()); if (response.IsSuccessful()) - { return new QueryResult(true); - } WMLS_GetBaseMsgResponse errorResponse = await _client.WMLS_GetBaseMsgAsync(response.Result); string message = $"Error while deleting from store: {response.Result} - {errorResponse.Result}. {response.SuppMsgOut}"; @@ -335,71 +296,18 @@ public async Task TestConnectionAsync() } // Spec requires a comma-seperated list of supported versions without spaces - string[] versions = response.Result.Split(','); - - if (!versions.Any(v => v == "1.4.1.1")) - { + var versions = response.Result.Split(','); + if (versions.All(v => v != "1.4.1.1")) throw new Exception("Error while testing connection: Server does not indicate support for WITSML 1.4.1.1"); - } return new QueryResult(true); } private void LogQueriesSentAndReceived(string querySent, bool isSuccessful, string xmlReceived = null) { - if (_queryLogger == null) - { - return; - } - - _queryLogger.LogQuery(querySent, isSuccessful, xmlReceived); + _queryLogger?.LogQuery(querySent, isSuccessful, xmlReceived); } - public Uri GetServerHostname() - { - return _serverUrl; - } - - } - - public class QueryResult - { - public bool IsSuccessful { get; } - public string Reason { get; } - - public QueryResult(bool isSuccessful, string reason = null) - { - IsSuccessful = isSuccessful; - Reason = reason; - } - } - - public interface IQueryLogger - { - void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null); - } - - public class DefaultQueryLogger : IQueryLogger - { - private readonly Logger _queryLogger; - - public DefaultQueryLogger() - { - _queryLogger = new LoggerConfiguration() - .WriteTo.File("queries.log", rollOnFileSizeLimit: true, retainedFileCountLimit: 1, fileSizeLimitBytes: 50000000) - .CreateLogger(); - } - - public void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null) - { - if (xmlReceived != null) - { - _queryLogger.Information("Query: \n{Query}\nReceived: \n{Response}\nIsSuccessful: {IsSuccessful}", querySent, xmlReceived, isSuccessful); - } - else - { - _queryLogger.Information("Query: \n{Query}\nIsSuccessful: {IsSuccessful}", querySent, isSuccessful); - } - } + public Uri GetServerHostname() => _serverUrl; } } diff --git a/Src/Witsml/WitsmlClientBase.cs b/Src/Witsml/WitsmlClientBase.cs new file mode 100644 index 000000000..173b885a2 --- /dev/null +++ b/Src/Witsml/WitsmlClientBase.cs @@ -0,0 +1,75 @@ +using System; +using System.Net; +using System.ServiceModel; +using System.ServiceModel.Channels; + +using Serilog; + +using Witsml.ServiceReference; + +namespace Witsml; + +public abstract class WitsmlClientBase +{ + internal static StoreSoapPortClient CreateSoapClient(WitsmlClientOptions options) + { + EndpointAddress endpointAddress = new(options.Hostname); + + Binding serviceBinding = options.ClientCertificate == null + ? CreateBasicBinding(options.RequestTimeOut) + : CreateCertificateAndBasicBinding(); + + var client = new StoreSoapPortClient(serviceBinding, endpointAddress); + client.ClientCredentials.UserName.UserName = options.Credentials.Username; + client.ClientCredentials.UserName.Password = options.Credentials.Password; + + if (options.ClientCertificate != null) + { + client.ClientCredentials.ClientCertificate.Certificate = options.ClientCertificate; + Log.Information($"Configured client to use client certificate. CN={options.ClientCertificate.SubjectName.Name}"); + if (!options.ClientCertificate.HasPrivateKey) + Log.Warning("Configured client certificate does not contain a private key"); + } + + client.Endpoint.EndpointBehaviors.Add(new EndpointBehavior()); + + return client; + } + + private static BasicHttpsBinding CreateBasicBinding(TimeSpan requestTimeout) + { + return new BasicHttpsBinding + { + Security = + { + Mode = BasicHttpsSecurityMode.Transport, + Transport = + { + ClientCredentialType = HttpClientCredentialType.Basic + } + }, + MaxReceivedMessageSize = int.MaxValue, + SendTimeout = requestTimeout + }; + } + + private static CustomBinding CreateCertificateAndBasicBinding() + { + return new CustomBinding + { + Elements = + { + new TextMessageEncodingBindingElement + { + MessageVersion = MessageVersion.Soap11 + }, + new HttpsTransportBindingElement + { + RequireClientCertificate = true, + AuthenticationScheme = AuthenticationSchemes.Basic, + MaxReceivedMessageSize = int.MaxValue + } + } + }; + } +} diff --git a/Src/Witsml/WitsmlClientOptions.cs b/Src/Witsml/WitsmlClientOptions.cs new file mode 100644 index 000000000..fefa53df2 --- /dev/null +++ b/Src/Witsml/WitsmlClientOptions.cs @@ -0,0 +1,42 @@ +using System; +using System.Security.Cryptography.X509Certificates; + +using Witsml.Data; + +namespace Witsml; + +public class WitsmlClientOptions +{ + /// + /// Hostname of the WITSML server to connect to + /// + public string Hostname { get; init; } + + /// + /// Client credentials to be used for basic authentication with the WITSML server + /// + public WitsmlCredentials Credentials { get; init; } + + /// + /// Client certificate to present while connecting to the WITSML server. The certificate should contain the private key. + /// + public X509Certificate2 ClientCertificate { get; init; } + + /// + /// The client capabilities to present to the WITSML server + /// + /// + public WitsmlClientCapabilities ClientCapabilities { get; init; } = new(); + + /// + /// The timeout interval to be used when communicating with the WITSML server. Default is 00:01:00 minutes + /// + public TimeSpan RequestTimeOut { get; init; } = TimeSpan.FromMinutes(1); + + /// + /// Enable logging all queries to a file (queries.log) in the current directory + /// + public bool LogQueries { get; init; } +} + +public record WitsmlCredentials(string Username, string Password); diff --git a/Tests/Witsml.Tests/ClientCertificateExample.cs b/Tests/Witsml.Tests/ClientCertificateExample.cs new file mode 100644 index 000000000..c755f7e1a --- /dev/null +++ b/Tests/Witsml.Tests/ClientCertificateExample.cs @@ -0,0 +1,24 @@ +using System; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; + +namespace Witsml.Tests; + +public class ClientCertificateExample +{ + /// + /// This is just a sample of how to create a X509Certificate client certificate that can be provided to the WitsmlClient + /// + public void CreateCertificate() + { + var clientCertificateString = "---BEGIN CERTIFICATE--- ---END CERTIFICATE---"; + var privateKey = ""; // note that ---BEGIN PRIVATE KEY--- / ---END PRIVATE KEY--- is not included + + var clientCertificate = X509Certificate2.CreateFromPem(clientCertificateString); + + var key = RSA.Create(); + key.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _); + + clientCertificate = clientCertificate.CopyWithPrivateKey(key); + } +} From 0bf7289c2e20270879dbb9ba1400c8faff9e9145 Mon Sep 17 00:00:00 2001 From: Geir-Tore Lindsve Date: Tue, 27 Jun 2023 16:16:17 +0200 Subject: [PATCH 2/3] Fixed build errors by switching to new WitsmlClient constructor --- .../Services/CredentialsService.cs | 7 +++++- .../Services/WitsmlClientProvider.cs | 24 ++++++++++++++++--- .../WitsmlClient/WitsmlClientProvider.cs | 7 +++++- .../Witsml/AddToStore/LogObjectTests.cs | 7 ++++-- .../Witsml/AddToStore/TrajectoryTests.cs | 7 ++++-- .../Witsml/GetFromStore/BhaRunTests.cs | 7 ++++-- .../Witsml/GetFromStore/FluidsReportTests.cs | 7 ++++-- .../GetFromStore/FormationMarkersTests.cs | 7 ++++-- .../Witsml/GetFromStore/LogObjectTests.cs | 7 ++++-- .../Witsml/GetFromStore/MessageTests.cs | 6 ++++- .../Witsml/GetFromStore/MudLogTests.cs | 7 ++++-- .../Witsml/GetFromStore/RigTests.cs | 7 ++++-- .../Witsml/GetFromStore/TrajectoryTests.cs | 7 ++++-- .../Witsml/GetFromStore/TubularTests.cs | 8 ++++--- 14 files changed, 88 insertions(+), 27 deletions(-) diff --git a/Src/WitsmlExplorer.Api/Services/CredentialsService.cs b/Src/WitsmlExplorer.Api/Services/CredentialsService.cs index 3b0f22297..9b60391ff 100644 --- a/Src/WitsmlExplorer.Api/Services/CredentialsService.cs +++ b/Src/WitsmlExplorer.Api/Services/CredentialsService.cs @@ -69,7 +69,12 @@ public async Task VerifyAndCacheCredentials(IEssentialHeaders eh, bool kee cacheId = httpContext.CreateWitsmlExplorerCookie(); } - WitsmlClient witsmlClient = new(creds.Host.ToString(), creds.UserId, creds.Password, _clientCapabilities); + var witsmlClient = new WitsmlClient(new WitsmlClientOptions + { + Hostname = creds.Host.ToString(), + Credentials = new WitsmlCredentials(creds.UserId, creds.Password), + ClientCapabilities = _clientCapabilities + }); await witsmlClient.TestConnectionAsync(); double ttl = keep ? 24.0 : 1.0; // hours diff --git a/Src/WitsmlExplorer.Api/Services/WitsmlClientProvider.cs b/Src/WitsmlExplorer.Api/Services/WitsmlClientProvider.cs index 97988480d..35284698d 100644 --- a/Src/WitsmlExplorer.Api/Services/WitsmlClientProvider.cs +++ b/Src/WitsmlExplorer.Api/Services/WitsmlClientProvider.cs @@ -49,7 +49,13 @@ public WitsmlClientProvider(ILogger logger, IConfiguration internal WitsmlClientProvider(IConfiguration configuration) { (string serverUrl, string username, string password) = GetCredentialsFromConfiguration(configuration); - _witsmlClient = new WitsmlClient(serverUrl, username, password, new WitsmlClientCapabilities(), null, true); + _witsmlClient = new WitsmlClient( + new WitsmlClientOptions + { + Hostname = serverUrl, + Credentials = new WitsmlCredentials(username, password), + LogQueries = true + }); } private static (string, string, string) GetCredentialsFromConfiguration(IConfiguration configuration) @@ -67,7 +73,13 @@ public IWitsmlClient GetClient() { _targetCreds = _credentialsService.GetCredentials(_httpHeaders, _httpHeaders.TargetServer, _httpHeaders.TargetUsername); _witsmlClient = (_targetCreds != null && !_targetCreds.IsCredsNullOrEmpty()) - ? new WitsmlClient(_targetCreds.Host.ToString(), _targetCreds.UserId, _targetCreds.Password, _clientCapabilities, null, _logQueries) + ? new WitsmlClient(new WitsmlClientOptions + { + Hostname = _targetCreds.Host.ToString(), + Credentials = new WitsmlCredentials(_targetCreds.UserId, _targetCreds.Password), + ClientCapabilities = _clientCapabilities, + LogQueries = _logQueries + }) : null; } return _witsmlClient; @@ -79,7 +91,13 @@ public IWitsmlClient GetSourceClient() { _sourceCreds = _credentialsService.GetCredentials(_httpHeaders, _httpHeaders.SourceServer, _httpHeaders.SourceUsername); _witsmlSourceClient = (_sourceCreds != null && !_sourceCreds.IsCredsNullOrEmpty()) - ? new WitsmlClient(_sourceCreds.Host.ToString(), _sourceCreds.UserId, _sourceCreds.Password, _clientCapabilities, null, _logQueries) + ? new WitsmlClient(new WitsmlClientOptions + { + Hostname = _sourceCreds.Host.ToString(), + Credentials = new WitsmlCredentials(_sourceCreds.UserId, _sourceCreds.Password), + ClientCapabilities = _clientCapabilities, + LogQueries = _logQueries + }) : null; } return _witsmlSourceClient; diff --git a/Src/WitsmlExplorer.Console/WitsmlClient/WitsmlClientProvider.cs b/Src/WitsmlExplorer.Console/WitsmlClient/WitsmlClientProvider.cs index a50c9a253..459cb942b 100644 --- a/Src/WitsmlExplorer.Console/WitsmlClient/WitsmlClientProvider.cs +++ b/Src/WitsmlExplorer.Console/WitsmlClient/WitsmlClientProvider.cs @@ -33,7 +33,12 @@ public WitsmlClientProvider() try { (string serverUrl, string username, string password) = GetCredentialsFromConfiguration(); - _witsmlClient = new Witsml.WitsmlClient(serverUrl, username, password, _clientCapabilities); + _witsmlClient = new Witsml.WitsmlClient(new WitsmlClientOptions + { + Hostname = serverUrl, + Credentials = new WitsmlCredentials(username, password), + ClientCapabilities = _clientCapabilities + }); } catch (Exception e) { diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/LogObjectTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/LogObjectTests.cs index 34c8802b2..112121d46 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/LogObjectTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/LogObjectTests.cs @@ -20,13 +20,16 @@ public class LogObjectTests { private readonly ITestOutputHelper _output; private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public LogObjectTests(ITestOutputHelper output) { _output = output; WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/TrajectoryTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/TrajectoryTests.cs index 632ff9701..eec3b5962 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/TrajectoryTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/AddToStore/TrajectoryTests.cs @@ -22,13 +22,16 @@ public class TrajectoryTests { private readonly ITestOutputHelper _output; private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public TrajectoryTests(ITestOutputHelper output) { _output = output; WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/BhaRunTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/BhaRunTests.cs index 0bc1d492d..45539d942 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/BhaRunTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/BhaRunTests.cs @@ -14,12 +14,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class BhaRunTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public BhaRunTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FluidsReportTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FluidsReportTests.cs index 1afd773d1..a47db7f1b 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FluidsReportTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FluidsReportTests.cs @@ -12,12 +12,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class FluidsReportTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public FluidsReportTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FormationMarkersTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FormationMarkersTests.cs index c6c70166b..27d2c3dd6 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FormationMarkersTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/FormationMarkersTests.cs @@ -12,7 +12,6 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public class FormationMarkersTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); private const string UidWell = "94f01089-84d3-4cec-9448-303c508ddb9e"; private const string UidWellbore = "c4ef4f85-5692-4f62-91b2-f26dce721501"; @@ -20,7 +19,11 @@ public class FormationMarkersTests public FormationMarkersTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/LogObjectTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/LogObjectTests.cs index ab84fd825..a95599804 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/LogObjectTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/LogObjectTests.cs @@ -16,7 +16,6 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public class LogObjectTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); private const string IsoPattern = "yyyy-MM-ddTHH:mm:ss.fffZ"; private const string UidWell = "bbd34996-a1f6-4767-8b02-5e3b46a990e8"; @@ -30,7 +29,11 @@ public class LogObjectTests public LogObjectTests() { var config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MessageTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MessageTests.cs index f1ff8cdf6..c542be053 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MessageTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MessageTests.cs @@ -18,7 +18,11 @@ public class MessageTests public MessageTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, new WitsmlClientCapabilities()); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MudLogTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MudLogTests.cs index 391c0e178..3227d4a47 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MudLogTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/MudLogTests.cs @@ -15,12 +15,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class MudLogTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public MudLogTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/RigTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/RigTests.cs index e29e948a3..7765db6d1 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/RigTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/RigTests.cs @@ -15,12 +15,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class RigTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public RigTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TrajectoryTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TrajectoryTests.cs index d16a29cc5..b310de0f6 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TrajectoryTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TrajectoryTests.cs @@ -14,12 +14,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class TrajectoryTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public TrajectoryTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] diff --git a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TubularTests.cs b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TubularTests.cs index f92b9b996..a7d9f25ee 100644 --- a/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TubularTests.cs +++ b/Tests/WitsmlExplorer.IntegrationTests/Witsml/GetFromStore/TubularTests.cs @@ -1,7 +1,6 @@ using System.Threading.Tasks; using Witsml; -using Witsml.Data; using Witsml.Data.Tubular; using Witsml.ServiceReference; using Witsml.Xml; @@ -15,12 +14,15 @@ namespace WitsmlExplorer.IntegrationTests.Witsml.GetFromStore public partial class TubularTests { private readonly WitsmlClient _client; - private readonly WitsmlClientCapabilities _clientCapabilities = new(); public TubularTests() { WitsmlConfiguration config = ConfigurationReader.GetWitsmlConfiguration(); - _client = new WitsmlClient(config.Hostname, config.Username, config.Password, _clientCapabilities); + _client = new WitsmlClient(new WitsmlClientOptions + { + Hostname = config.Hostname, + Credentials = new WitsmlCredentials(config.Username, config.Password) + }); } [Fact(Skip = "Should only be run manually")] From f9bb5b7ac61945cf7384a3bcb0ee6d05905b735a Mon Sep 17 00:00:00 2001 From: Geir-Tore Lindsve Date: Wed, 28 Jun 2023 12:20:26 +0200 Subject: [PATCH 3/3] Bump the minor version of the nuget package since the WitsmlClient ctor has been updated and a significant feature has been added --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 495e0e319..d0758ee59 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,6 +31,6 @@ jobs: - name: Test run: dotnet test ./Tests/Witsml.Tests/Witsml.Tests.csproj --configuration Release - name: Package - run: dotnet pack --configuration Release Src/Witsml -p:Version=2.7.${GITHUB_RUN_NUMBER} + run: dotnet pack --configuration Release Src/Witsml -p:Version=2.8.${GITHUB_RUN_NUMBER} - name: Publish - run: dotnet nuget push --api-key ${{secrets.NUGET_PUBLISH_KEY}} --source https://api.nuget.org/v3/index.json Src/Witsml/bin/Release/WitsmlClient.2.7.${GITHUB_RUN_NUMBER}.nupkg + run: dotnet nuget push --api-key ${{secrets.NUGET_PUBLISH_KEY}} --source https://api.nuget.org/v3/index.json Src/Witsml/bin/Release/WitsmlClient.2.8.${GITHUB_RUN_NUMBER}.nupkg