Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX-1953 Create Log Header Consistency Check #1976

Merged
merged 10 commits into from
Aug 7, 2023
4 changes: 2 additions & 2 deletions Src/Witsml/Data/Curves/Index.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static Index Start(WitsmlLog log, string customIndexValue = "")
return log.IndexType switch
{
WitsmlLog.WITSML_INDEX_TYPE_MD => new DepthIndex(double.Parse(customIndexValue.IsNumeric() ? customIndexValue : log.StartIndex.Value, CultureInfo.InvariantCulture),
log.StartIndex.Uom),
log.StartIndex?.Uom ?? "m"),
WitsmlLog.WITSML_INDEX_TYPE_DATE_TIME => new DateTimeIndex(DateTime.Parse(customIndexValue.NullIfEmpty() ?? log.StartDateTimeIndex, CultureInfo.InvariantCulture)),
_ => throw new Exception($"Invalid index type: '{log.IndexType}'")
};
Expand All @@ -56,7 +56,7 @@ public static Index End(WitsmlLog log, string customIndexValue = "")
return log.IndexType switch
{
WitsmlLog.WITSML_INDEX_TYPE_MD => new DepthIndex(double.Parse(customIndexValue.IsNumeric() ? customIndexValue : log.EndIndex.Value, CultureInfo.InvariantCulture),
log.EndIndex.Uom),
log.EndIndex?.Uom ?? "m"),
WitsmlLog.WITSML_INDEX_TYPE_DATE_TIME => new DateTimeIndex(DateTime.Parse(customIndexValue.NullIfEmpty() ?? log.EndDateTimeIndex, CultureInfo.InvariantCulture)),
_ => throw new Exception($"Invalid index type: '{log.IndexType}'")
};
Expand Down
2 changes: 1 addition & 1 deletion Src/Witsml/Extensions/UriExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ public static bool EqualsIgnoreCase(this Uri firstUri, Uri secondUri)
{
return string.Equals(firstUri?.AbsoluteUri, secondUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase);
}
}
}
4 changes: 2 additions & 2 deletions Src/Witsml/QueryLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface IQueryLogger
/// <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,
void LogQuery<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn, string querySent, bool isSuccessful,
string xmlReceived, short resultCode, string suppMsgOut) where T : IWitsmlQueryType;
}

Expand All @@ -38,7 +38,7 @@ public DefaultQueryLogger()
.CreateLogger();
}

public void LogQuery<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn, string querySent, bool isSuccessful,
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
16 changes: 8 additions & 8 deletions Src/Witsml/WitsmlClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ private async Task<T> GetFromStoreInnerAsync<T>(T query, OptionsIn optionsIn) wh
};

WMLS_GetFromStoreResponse response = await _client.WMLS_GetFromStoreAsync(request);
LogQueriesSentAndReceived(nameof(_client.WMLS_GetFromStoreAsync), this._serverUrl, query, optionsIn, request.QueryIn,

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

if (response.IsSuccessful())
Expand Down Expand Up @@ -157,8 +157,8 @@ private async Task<T> GetFromStoreInnerAsync<T>(T query, OptionsIn optionsIn) wh
};

WMLS_GetFromStoreResponse response = await _client.WMLS_GetFromStoreAsync(request);
LogQueriesSentAndReceived(nameof(_client.WMLS_GetFromStoreAsync), this._serverUrl, query, optionsIn,

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

if (response.IsSuccessful())
Expand Down Expand Up @@ -216,7 +216,7 @@ public async Task<QueryResult> AddToStoreAsync<T>(T query) where T : IWitsmlQuer

WMLS_AddToStoreResponse response = await _client.WMLS_AddToStoreAsync(request);

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

if (response.IsSuccessful())
Expand Down Expand Up @@ -248,7 +248,7 @@ public async Task<QueryResult> UpdateInStoreAsync<T>(T query) where T : IWitsmlQ

WMLS_UpdateInStoreResponse response = await _client.WMLS_UpdateInStoreAsync(request);

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

if (response.IsSuccessful())
Expand Down Expand Up @@ -280,7 +280,7 @@ public async Task<QueryResult> DeleteFromStoreAsync<T>(T query) where T : IWitsm

WMLS_DeleteFromStoreResponse response = await _client.WMLS_DeleteFromStoreAsync(request);

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

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

private void LogQueriesSentAndReceived<T>(string function, Uri serverUrl, T query, OptionsIn optionsIn,
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(function, serverUrl, query, optionsIn, querySent, isSuccessful, xmlReceived, resultCode, suppMsgOut);
Expand Down
29 changes: 29 additions & 0 deletions Src/WitsmlExplorer.Api/HttpHandlers/JobHandler.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

using WitsmlExplorer.Api.Configuration;
using WitsmlExplorer.Api.Extensions;
using WitsmlExplorer.Api.Jobs;
using WitsmlExplorer.Api.Middleware;
using WitsmlExplorer.Api.Models;
Expand Down Expand Up @@ -50,6 +53,32 @@ public static IResult GetUserJobInfos(IJobCache jobCache, HttpRequest httpReques
return TypedResults.Ok(jobCache.GetJobInfosByUser(userName));
}

[Produces(typeof(IEnumerable<JobInfo>))]
public static IResult GetUserJobInfo(string jobId, IJobCache jobCache, HttpRequest httpRequest, IConfiguration configuration, ICredentialsService credentialsService)
{
EssentialHeaders eh = new(httpRequest);
bool useOAuth2 = StringHelpers.ToBoolean(configuration[ConfigConstants.OAuth2Enabled]);
string userName = useOAuth2 ? credentialsService.GetClaimFromToken(eh.GetBearerToken(), "upn") : eh.TargetUsername;
if (!useOAuth2)
{
credentialsService.VerifyUserIsLoggedIn(eh, ServerType.Target);
}
JobInfo job = jobCache.GetJobInfoById(jobId);
if (job.Username != userName && (!useOAuth2 || !IsAdminOrDeveloper(eh.GetBearerToken())))
{
return TypedResults.Forbid();
}
return TypedResults.Ok(job);
}

private static bool IsAdminOrDeveloper(string token)
{
JwtSecurityTokenHandler handler = new();
JwtSecurityToken jwt = handler.ReadJwtToken(token);
IEnumerable<string> userRoles = jwt.Claims.Where(n => n.Type == "roles").Select(n => n.Value);
return userRoles.Contains(AuthorizationPolicyRoles.ADMIN) || userRoles.Contains(AuthorizationPolicyRoles.DEVELOPER);
}

[Produces(typeof(IEnumerable<JobInfo>))]
public static IResult GetAllJobInfos(IJobCache jobCache, IConfiguration configuration)
{
Expand Down
29 changes: 29 additions & 0 deletions Src/WitsmlExplorer.Api/Jobs/CheckLogHeaderJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using WitsmlExplorer.Api.Models;

namespace WitsmlExplorer.Api.Jobs
{
public record CheckLogHeaderJob : Job
{
public LogObject LogReference { get; init; }

public override string Description()
{
return $"Check Log Headers - Log: {LogReference.Name}";
}

public override string GetObjectName()
{
return LogReference.Name;
}

public override string GetWellboreName()
{
return LogReference.WellboreName;
}

public override string GetWellName()
{
return LogReference.WellName;
}
}
}
4 changes: 4 additions & 0 deletions Src/WitsmlExplorer.Api/Jobs/JobInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Text.Json.Serialization;

using WitsmlExplorer.Api.Models.Reports;

namespace WitsmlExplorer.Api.Jobs
{
public record JobInfo
Expand Down Expand Up @@ -42,6 +44,8 @@ public JobInfo()

public string FailedReason { get; set; }

public BaseReport Report { get; set; }

private JobStatus _status;

[JsonConverter(typeof(JsonStringEnumConverter))]
Expand Down
3 changes: 2 additions & 1 deletion Src/WitsmlExplorer.Api/Models/JobType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public enum JobType
BatchModifyWell,
ImportLogData,
ReplaceComponents,
ReplaceObjects
ReplaceObjects,
CheckLogHeader
}
}
11 changes: 11 additions & 0 deletions Src/WitsmlExplorer.Api/Models/Reports/BaseReport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;

namespace WitsmlExplorer.Api.Models.Reports
{
public class BaseReport
{
public string Title { get; set; }
public string Summary { get; init; }
public IEnumerable<object> ReportItems { get; init; }
}
}
16 changes: 16 additions & 0 deletions Src/WitsmlExplorer.Api/Models/Reports/CheckLogHeaderReport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace WitsmlExplorer.Api.Models.Reports
{
public class CheckLogHeaderReport : BaseReport
{
public LogObject LogReference { get; init; }
}

public class CheckLogHeaderReportItem
{
public string Mnemonic { get; init; }
public string HeaderStartIndex { get; init; }
public string DataStartIndex { get; init; }
public string HeaderEndIndex { get; init; }
public string DataEndIndex { get; init; }
}
}
34 changes: 30 additions & 4 deletions Src/WitsmlExplorer.Api/Query/LogQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ public static WitsmlLogs GetLogContent(
switch (indexType)
{
case WitsmlLog.WITSML_INDEX_TYPE_MD:
queryLog.StartIndex = new WitsmlIndex((DepthIndex)startIndex);
queryLog.EndIndex = new WitsmlIndex((DepthIndex)endIndex);
queryLog.StartIndex = startIndex != null ? new WitsmlIndex((DepthIndex)startIndex) : new WitsmlIndex();
queryLog.EndIndex = endIndex != null ? new WitsmlIndex((DepthIndex)endIndex) : new WitsmlIndex();
break;
case WitsmlLog.WITSML_INDEX_TYPE_DATE_TIME:
queryLog.StartDateTimeIndex = startIndex.GetValueAsString();
queryLog.EndDateTimeIndex = endIndex.GetValueAsString();
queryLog.StartDateTimeIndex = startIndex?.GetValueAsString() ?? "";
queryLog.EndDateTimeIndex = endIndex?.GetValueAsString() ?? "";
break;
default:
break;
Expand Down Expand Up @@ -148,5 +148,31 @@ public static WitsmlLogs DeleteMnemonics(string wellUid, string wellboreUid, str
}.AsSingletonList()
};
}

public static WitsmlLogs GetLogHeaderIndexes(string wellUid, string wellboreUid, string logUid)
{
return new WitsmlLogs
{
Logs = new WitsmlLog
{
UidWell = wellUid,
UidWellbore = wellboreUid,
Uid = logUid,
StartIndex = new WitsmlIndex(),
EndIndex = new WitsmlIndex(),
StartDateTimeIndex = "",
EndDateTimeIndex = "",
IndexCurve = new WitsmlIndexCurve(),
LogCurveInfo = new WitsmlLogCurveInfo
{
Mnemonic = "",
MinIndex = new WitsmlIndex(),
MaxIndex = new WitsmlIndex(),
MinDateTimeIndex = "",
MaxDateTimeIndex = ""
}.AsSingletonList(),
}.AsSingletonList()
};
}
}
}
4 changes: 2 additions & 2 deletions Src/WitsmlExplorer.Api/Query/TrajectoryQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static WitsmlTrajectories DeleteTrajectoryStations(string wellUid, string
}.AsSingletonList()
};
}

/// <summary>
/// Create trajectories witsml model.
/// </summary>
Expand All @@ -117,7 +117,7 @@ public static WitsmlTrajectories CreateTrajectory(Trajectory trajectory)
}.AsSingletonList()
};
}

public static WitsmlTrajectories UpdateTrajectoryStation(TrajectoryStation trajectoryStation, ObjectReference trajectoryReference)
{
WitsmlTrajectoryStation ts = new()
Expand Down
1 change: 1 addition & 0 deletions Src/WitsmlExplorer.Api/Routes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public static void ConfigureApi(this WebApplication app, IConfiguration configur

app.MapPost("/jobs/{jobType}", JobHandler.CreateJob, useOAuth2);
app.MapGet("/jobs/userjobinfos", JobHandler.GetUserJobInfos, useOAuth2);
app.MapGet("/jobs/userjobinfo/{jobId}", JobHandler.GetUserJobInfo, useOAuth2);
app.MapGet("/jobs/alljobinfos", JobHandler.GetAllJobInfos, useOAuth2, AuthorizationPolicyRoles.ADMINORDEVELOPER);

app.MapGet("/credentials/authorize", AuthorizeHandler.Authorize, useOAuth2);
Expand Down
7 changes: 6 additions & 1 deletion Src/WitsmlExplorer.Api/Services/JobCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface IJobCache
{
void CacheJob(JobInfo jobInfo);
IEnumerable<JobInfo> GetJobInfosByUser(string username);
JobInfo GetJobInfoById(string jobId);
IEnumerable<JobInfo> GetAllJobInfos();
}

Expand Down Expand Up @@ -51,6 +52,11 @@ public IEnumerable<JobInfo> GetJobInfosByUser(string username)
return _jobs.Values.Where(job => job.Username == username);
}

public JobInfo GetJobInfoById(string jobId)
{
return _jobs[jobId];
}

public IEnumerable<JobInfo> GetAllJobInfos()
{
return _jobs.Values;
Expand Down Expand Up @@ -79,6 +85,5 @@ private void Cleanup()
}
_logger.LogInformation("JobCache cleanup finished, deleted: {deleted}, failed: {failed}, remaining: {remaining}", deleted, failed, _jobs.Count);
}

}
}
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Workers/BaseWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected IWitsmlClient GetSourceWitsmlClientOrThrow()
job.JobInfo.Status = JobStatus.Failed;
job.JobInfo.FailedReason = ex.Message;
Logger.LogError("An unexpected exception has occured: {ex}", ex);
return (new WorkerResult(new Uri(job.JobInfo.TargetServer), false, $"{job.JobInfo.JobType} failed", ex.Message), null);
return (new WorkerResult(new Uri(job.JobInfo.TargetServer), false, $"{job.JobInfo.JobType} failed", ex.Message, jobId: job.JobInfo.Id), null);
}
}

Expand Down
Loading