Skip to content

Commit

Permalink
Merge branch 'main' into FIX-1953
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasbruvik committed Aug 4, 2023
2 parents a3803aa + d4a90fc commit 2a629d7
Show file tree
Hide file tree
Showing 42 changed files with 903 additions and 813 deletions.
1 change: 1 addition & 0 deletions Src/Witsml/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Globalization;

namespace Witsml.Extensions
Expand Down
17 changes: 17 additions & 0 deletions Src/Witsml/Extensions/UriExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Witsml.Extensions;

public static class UriExtensions
{
/// <summary>
/// Determines whether two specified Uri objects have the same value ignore case.
/// </summary>
/// The first Uri to compare.
/// The second Uri to compare.
/// <returns>True if the value of the <paramref name="firstUri" /> parameter is equal to the value of the <paramref name="secondUri" />, otherwise return false.</returns>
public static bool EqualsIgnoreCase(this Uri firstUri, Uri secondUri)
{
return string.Equals(firstUri?.AbsoluteUri, secondUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase);
}
}
24 changes: 22 additions & 2 deletions Src/Witsml/QueryLogger.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
using System;

using Serilog;
using Serilog.Core;

using Witsml.Data;
using Witsml.ServiceReference;

namespace Witsml;

public interface IQueryLogger
{
void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null);
/// <summary>
/// This method will be invoked after every call to Witsml server. It will contain information about the call, response and error (if any)
/// </summary>
/// <param name="function">Name of the Witsml function call</param>
/// <param name="serverUrl">Witsml server Url</param>
/// <param name="query">Witsml query</param>
/// <param name="optionsIn">OptionsIn if applicable (could be null)</param>
/// <param name="querySent">Xml request to the Witsml server (QueryIn/XMLin)</param>
/// <param name="isSuccessful">if true - request was successful (resultCode > 0)</param>
/// <param name="xmlReceived">Xml response from server (could be null)</param>
/// <param name="resultCode">Result code from the witsml server (negative number means error code)</param>
/// <param name="suppMsgOut">Result message from the witsml server</param>
/// <typeparam name="T">IWitsmlQueryType</typeparam>
void LogQuery<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn, string querySent, bool isSuccessful,
string xmlReceived, short resultCode, string suppMsgOut) where T : IWitsmlQueryType;
}

public class DefaultQueryLogger : IQueryLogger
Expand All @@ -19,7 +38,8 @@ public DefaultQueryLogger()
.CreateLogger();
}

public void LogQuery(string querySent, bool isSuccessful, string xmlReceived = null)
public void LogQuery<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn, string querySent, bool isSuccessful,
string xmlReceived, short resultCode, string suppMsgOut) where T : IWitsmlQueryType
{
if (xmlReceived != null)
{
Expand Down
25 changes: 18 additions & 7 deletions Src/Witsml/WitsmlClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ private async Task<T> GetFromStoreInnerAsync<T>(T query, OptionsIn optionsIn) wh
};

WMLS_GetFromStoreResponse response = await _client.WMLS_GetFromStoreAsync(request);
LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful(), response.XMLout);

LogQueriesSentAndReceived(nameof(_client.WMLS_GetFromStoreAsync), this._serverUrl, query, optionsIn, request.QueryIn,
response.IsSuccessful(), response.XMLout, response.Result, response.SuppMsgOut);

if (response.IsSuccessful())
return XmlHelper.Deserialize(response.XMLout, query);
Expand Down Expand Up @@ -155,7 +157,9 @@ private async Task<T> GetFromStoreInnerAsync<T>(T query, OptionsIn optionsIn) wh
};

WMLS_GetFromStoreResponse response = await _client.WMLS_GetFromStoreAsync(request);
LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful(), response.XMLout);

LogQueriesSentAndReceived(nameof(_client.WMLS_GetFromStoreAsync), this._serverUrl, query, optionsIn,
request.QueryIn, response.IsSuccessful(), response.XMLout, response.Result, response.SuppMsgOut);

if (response.IsSuccessful())
return (XmlHelper.Deserialize(response.XMLout, query), response.Result);
Expand Down Expand Up @@ -211,7 +215,9 @@ public async Task<QueryResult> AddToStoreAsync<T>(T query) where T : IWitsmlQuer
};

WMLS_AddToStoreResponse response = await _client.WMLS_AddToStoreAsync(request);
LogQueriesSentAndReceived(request.XMLin, response.IsSuccessful());

LogQueriesSentAndReceived(nameof(_client.WMLS_AddToStoreAsync), this._serverUrl, query, optionsIn,
request.XMLin, response.IsSuccessful(), null, response.Result, response.SuppMsgOut);

if (response.IsSuccessful())
return new QueryResult(true);
Expand Down Expand Up @@ -241,7 +247,9 @@ public async Task<QueryResult> UpdateInStoreAsync<T>(T query) where T : IWitsmlQ
};

WMLS_UpdateInStoreResponse response = await _client.WMLS_UpdateInStoreAsync(request);
LogQueriesSentAndReceived(request.XMLin, response.IsSuccessful());

LogQueriesSentAndReceived(nameof(_client.WMLS_UpdateInStoreAsync), this._serverUrl, query, null,
request.XMLin, response.IsSuccessful(), null, response.Result, response.SuppMsgOut);

if (response.IsSuccessful())
return new QueryResult(true);
Expand Down Expand Up @@ -271,7 +279,9 @@ public async Task<QueryResult> DeleteFromStoreAsync<T>(T query) where T : IWitsm
};

WMLS_DeleteFromStoreResponse response = await _client.WMLS_DeleteFromStoreAsync(request);
LogQueriesSentAndReceived(request.QueryIn, response.IsSuccessful());

LogQueriesSentAndReceived(nameof(_client.WMLS_DeleteFromStoreAsync), this._serverUrl, query, null,
request.QueryIn, response.IsSuccessful(), null, response.Result, response.SuppMsgOut);

if (response.IsSuccessful())
return new QueryResult(true);
Expand Down Expand Up @@ -304,9 +314,10 @@ public async Task<QueryResult> TestConnectionAsync()
return new QueryResult(true);
}

private void LogQueriesSentAndReceived(string querySent, bool isSuccessful, string xmlReceived = null)
private void LogQueriesSentAndReceived<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn,
string querySent, bool isSuccessful, string xmlReceived, short resultCode, string suppMsgOut = null) where T : IWitsmlQueryType
{
_queryLogger?.LogQuery(querySent, isSuccessful, xmlReceived);
_queryLogger?.LogQuery(function, serverUrl, query, optionsIn, querySent, isSuccessful, xmlReceived, resultCode, suppMsgOut);
}

public Uri GetServerHostname() => _serverUrl;
Expand Down
9 changes: 6 additions & 3 deletions Src/WitsmlExplorer.Api/Configuration/ServerCredentials.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;

using Witsml.Extensions;

namespace WitsmlExplorer.Api.Configuration
{
public class ServerCredentials : ICredentials, IEquatable<ServerCredentials>
Expand Down Expand Up @@ -26,9 +29,9 @@ public bool IsCredsNullOrEmpty()
}
public bool Equals(ServerCredentials other)
{
return (Host.ToString() == other.Host.ToString()) &&
(UserId == other.UserId) &&
(Password == other.Password);
return (Host.EqualsIgnoreCase(other.Host)) &&
(UserId == other.UserId) &&
(Password == other.Password);
}

public override bool Equals(object obj)
Expand Down
50 changes: 50 additions & 0 deletions Src/WitsmlExplorer.Api/Jobs/CreateTrajectoryJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using WitsmlExplorer.Api.Models;

namespace WitsmlExplorer.Api.Jobs;

/// <summary>
/// Job for create trajectory with jobInfo.
/// </summary>
public record CreateTrajectoryJob : Job
{
/// <summary>
/// Trajectory API model.
/// </summary>
public Trajectory Trajectory { get; init; }

/// <summary>
/// Getting description of created trajectory.
/// </summary>
/// <returns>String of job info which provide Trajectory Uid and Name, WellUid, WellboreUid.</returns>
public override string Description()
{
return $"Create Trajectory - Uid: {Trajectory.Uid}; Name: {Trajectory.Name}; WellUid: {Trajectory.WellUid}; WellboreUid: {Trajectory.WellboreUid};";
}

/// <summary>
/// Getting name of trajectory.
/// </summary>
/// <returns>String of trajectory name.</returns>
public override string GetObjectName()
{
return Trajectory.Name;
}

/// <summary>
/// Getting name of wellbore.
/// </summary>
/// <returns>String of wellbore name.</returns>
public override string GetWellboreName()
{
return Trajectory.WellboreName;
}

/// <summary>
/// Getting name of well.
/// </summary>
/// <returns>String of well name.</returns>
public override string GetWellName()
{
return Trajectory.WellName;
}
}
1 change: 1 addition & 0 deletions Src/WitsmlExplorer.Api/Models/JobType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public enum JobType
CreateRisk,
CreateMudLog,
CreateRig,
CreateTrajectory,
CreateWbGeometry,
BatchModifyWell,
ImportLogData,
Expand Down
18 changes: 9 additions & 9 deletions Src/WitsmlExplorer.Api/Models/Trajectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ namespace WitsmlExplorer.Api.Models
{
public class Trajectory : ObjectOnWellbore
{
public decimal? MdMin { get; internal init; }
public decimal? MdMax { get; internal init; }
public string AziRef { get; internal init; }
public string DTimTrajStart { get; internal init; }
public string DTimTrajEnd { get; internal init; }
public List<TrajectoryStation> TrajectoryStations { get; internal init; }
public string ServiceCompany { get; internal init; }
public string DateTimeCreation { get; internal init; }
public string DateTimeLastChange { get; internal init; }
public decimal? MdMin { get; init; }
public decimal? MdMax { get; init; }
public string AziRef { get; init; }
public string DTimTrajStart { get; init; }
public string DTimTrajEnd { get; init; }
public List<TrajectoryStation> TrajectoryStations { get; init; }
public string ServiceCompany { get; init; }
public string DateTimeCreation { get; init; }
public string DateTimeLastChange { get; init; }
}
}
28 changes: 28 additions & 0 deletions Src/WitsmlExplorer.Api/Query/TrajectoryQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,34 @@ public static WitsmlTrajectories DeleteTrajectoryStations(string wellUid, string
}.AsSingletonList()
};
}

/// <summary>
/// Create trajectories witsml model.
/// </summary>
/// <param name="trajectory">API model of trajectory data.</param>
/// <returns>New instance of WitsmlTrajectories model with added trajectory data.</returns>
public static WitsmlTrajectories CreateTrajectory(Trajectory trajectory)
{
return new()
{
Trajectories = new WitsmlTrajectory
{
UidWell = trajectory.WellUid,
NameWell = trajectory.WellName,
NameWellbore = trajectory.WellboreName,
Uid = trajectory.Uid,
Name = trajectory.Name,
UidWellbore = trajectory.WellboreUid,
MdMin = trajectory.MdMin != null ? new WitsmlMeasuredDepthCoord() { Value = trajectory.MdMin.Value.ToString(CultureInfo.InvariantCulture) } : null,
MdMax = trajectory.MdMax != null ? new WitsmlMeasuredDepthCoord() { Value = trajectory.MdMax.Value.ToString(CultureInfo.InvariantCulture) } : null,
AziRef = trajectory.AziRef.NullIfEmpty(),
ServiceCompany = trajectory.ServiceCompany.NullIfEmpty(),
DTimTrajStart = StringHelpers.ToUniversalDateTimeString(trajectory.DTimTrajStart),
DTimTrajEnd = StringHelpers.ToUniversalDateTimeString(trajectory.DTimTrajEnd),
}.AsSingletonList()
};
}

public static WitsmlTrajectories UpdateTrajectoryStation(TrajectoryStation trajectoryStation, ObjectReference trajectoryReference)
{
WitsmlTrajectoryStation ts = new()
Expand Down
7 changes: 4 additions & 3 deletions Src/WitsmlExplorer.Api/Services/CredentialsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

using Witsml;
using Witsml.Data;
using Witsml.Extensions;

using WitsmlExplorer.Api.Configuration;
using WitsmlExplorer.Api.Extensions;
Expand Down Expand Up @@ -87,8 +88,8 @@ private async Task<bool> UserHasRoleForHost(string[] roles, Uri host)
bool result = true;
IEnumerable<Server> allServers = await _allServers;

bool systemCredsExists = _witsmlServerCredentials.WitsmlCreds.Any(n => n.Host == host);
IEnumerable<Server> hostServer = allServers.Where(n => n.Url.ToString() == host.ToString());
bool systemCredsExists = _witsmlServerCredentials.WitsmlCreds.Any(n => n.Host.EqualsIgnoreCase(host));
IEnumerable<Server> hostServer = allServers.Where(n => n.Url.EqualsIgnoreCase(host));
bool validRole = hostServer.Any(n =>
n.Roles != null && n.Roles.Intersect(roles).Any()
);
Expand Down Expand Up @@ -139,7 +140,7 @@ private async Task<ServerCredentials> GetSystemCredentialsByToken(string token,
_logger.LogDebug("User roles in JWT: {roles}", string.Join(",", userRoles));
if (await UserHasRoleForHost(userRoles, server))
{
result = _witsmlServerCredentials.WitsmlCreds.Single(n => n.Host == server);
result = _witsmlServerCredentials.WitsmlCreds.Single(n => n.Host.EqualsIgnoreCase(server));
if (!result.IsCredsNullOrEmpty())
{
CacheCredentials(GetClaimFromToken(token, SUBJECT), result, 1.0);
Expand Down
4 changes: 2 additions & 2 deletions Src/WitsmlExplorer.Api/Workers/Copy/CopyLogDataWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public CopyLogDataWorker(IWitsmlClientProvider witsmlClientProvider, ILogger<Cop
Uri targetHostname = GetTargetWitsmlClientOrThrow().GetServerHostname();
Uri sourceHostname = GetSourceWitsmlClientOrThrow().GetServerHostname();
IEnumerable<Server> servers = _witsmlServerRepository == null ? new List<Server>() : await _witsmlServerRepository.GetDocumentsAsync();
int targetDepthLogDecimals = servers.FirstOrDefault((server) => server.Url == targetHostname)?.DepthLogDecimals ?? 0;
int sourceDepthLogDecimals = servers.FirstOrDefault((server) => server.Url == sourceHostname)?.DepthLogDecimals ?? 0;
int targetDepthLogDecimals = servers.FirstOrDefault((server) => server.Url.EqualsIgnoreCase(targetHostname))?.DepthLogDecimals ?? 0;
int sourceDepthLogDecimals = servers.FirstOrDefault((server) => server.Url.EqualsIgnoreCase(sourceHostname))?.DepthLogDecimals ?? 0;

(WitsmlLog sourceLog, WitsmlLog targetLog) = await GetLogs(job);
List<string> mnemonicsToCopy = job.Source.ComponentUids.Any()
Expand Down
63 changes: 63 additions & 0 deletions Src/WitsmlExplorer.Api/Workers/Create/CreateTrajectoryWorker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Threading.Tasks;

using Microsoft.Extensions.Logging;

using Witsml;
using Witsml.Data;

using WitsmlExplorer.Api.Jobs;
using WitsmlExplorer.Api.Models;
using WitsmlExplorer.Api.Query;
using WitsmlExplorer.Api.Services;

namespace WitsmlExplorer.Api.Workers.Create;

/// <summary>
/// Worker for creating new trajectory by specific well and wellbore.
/// </summary>
public class CreateTrajectoryWorker : BaseWorker<CreateTrajectoryJob>, IWorker
{
public CreateTrajectoryWorker(ILogger<CreateTrajectoryJob> logger, IWitsmlClientProvider witsmlClientProvider) : base(witsmlClientProvider, logger) { }
public JobType JobType => JobType.CreateTrajectory;

/// <summary>
/// Create new trajectory on wellbore for witsml client.
/// </summary>
/// <param name="job">Job info of created trajectory.</param>
/// <returns>Task of workerResult with refresh objects.</returns>
public override async Task<(WorkerResult, RefreshAction)> Execute(CreateTrajectoryJob job)
{
Verify(job.Trajectory);

WitsmlTrajectories trajectoryToCreate = TrajectoryQueries.CreateTrajectory(job.Trajectory);

QueryResult addToStoreResult = await GetTargetWitsmlClientOrThrow().AddToStoreAsync(trajectoryToCreate);

if (!addToStoreResult.IsSuccessful)
{
string errorMessage = "Failed to create trajectory.";
Logger.LogError("{ErrorMessage}. {jobDescription}", errorMessage, job.Description());
return (new WorkerResult(GetTargetWitsmlClientOrThrow().GetServerHostname(), false, errorMessage, addToStoreResult.Reason), null);
}

Logger.LogInformation("Trajectory created. {jobDescription}", job.Description());
RefreshObjects refreshAction = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), job.Trajectory.WellUid, job.Trajectory.WellboreUid, EntityType.Trajectory);
WorkerResult workerResult = new(GetTargetWitsmlClientOrThrow().GetServerHostname(), true, $"Trajectory {job.Trajectory.Name} add for {job.Trajectory.WellboreName}");

return (workerResult, refreshAction);
}

private static void Verify(Trajectory trajectory)
{
if (string.IsNullOrEmpty(trajectory.Uid))
{
throw new InvalidOperationException($"{nameof(trajectory.Uid)} cannot be empty");
}

if (string.IsNullOrEmpty(trajectory.Name))
{
throw new InvalidOperationException($"{nameof(trajectory.Name)} cannot be empty");
}
}
}
Loading

0 comments on commit 2a629d7

Please sign in to comment.