Esempio n. 1
0
        public override async Task <(WorkerResult, RefreshAction)> Execute(ImportLogDataJob job)
        {
            var chunkSize   = 1000;
            var wellUid     = job.TargetLog.WellUid;
            var wellboreUid = job.TargetLog.WellboreUid;
            var logUid      = job.TargetLog.LogUid;
            var witsmlLog   = await GetLogHeader(wellUid, wellboreUid, logUid);

            if (witsmlLog == null)
            {
                var reason = $"Did not find witsml log for wellUid: {wellUid}, wellboreUid: {wellboreUid}, logUid: {logUid}";
                return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Unable to find log", reason), null);
            }

            var logCurveInfos = witsmlLog.LogCurveInfo.Where(logCurveInfo => job.Mnemonics.Contains(logCurveInfo.Mnemonic)).ToList();

            //Todo: find a way to determine the maximum amount of rows that can be sent to the WITSML server then pass that amount to the CreateImportQueries method
            var queries = CreateImportQueries(job, chunkSize).ToArray();

            //Todo: update import progress for the user using websockets
            for (var i = 0; i < queries.Length; i++)
            {
                var result = await witsmlClient.UpdateInStoreAsync(queries[i]);

                if (result.IsSuccessful)
                {
                    Log.Information("{JobType} - Query {QueryCount}/{CurrentQuery} successful", GetType().Name, queries.Length, i + 1);
                }
                else
                {
                    Log.Error("Failed to import curve data for log object. WellUid: {WellUid}, WellboreUid: {WellboreUid}, Uid: {LogUid}, Mnemonics: {MnemonicsString}. Failed import at query:{QueryNumber} with the chunkSize of {ChunkSize} and total number of queries:{QueriesLength}",
                              wellUid,
                              wellboreUid,
                              logUid,
                              string.Join(", ", job.Mnemonics),
                              i,
                              chunkSize,
                              queries.Length);

                    return(new WorkerResult(witsmlClient.GetServerHostname(), result.IsSuccessful, $"Failed to import curve data from row: {i * chunkSize}", result.Reason, witsmlLog.GetDescription()), null);
                }
            }

            Log.Information("{JobType} - Job successful", GetType().Name);

            var refreshAction  = new RefreshLogObject(witsmlClient.GetServerHostname(), wellUid, wellboreUid, logUid, RefreshType.Update);
            var mnemonicsOnLog = string.Join(", ", logCurveInfos.Select(logCurveInfo => logCurveInfo.Mnemonic));
            var workerResult   = new WorkerResult(witsmlClient.GetServerHostname(), true, $"Imported curve info values for mnemonics: {mnemonicsOnLog}, for log: {logUid}");

            return(workerResult, refreshAction);
        }
        public override async Task <(WorkerResult, RefreshAction)> Execute(CopyLogDataJob job)
        {
            var(sourceLog, targetLog) = await GetLogs(job);

            var mnemonicsToCopy = job.SourceLogCurvesReference.Mnemonics.Any()
                ? job.SourceLogCurvesReference.Mnemonics.Distinct().ToList()
                : sourceLog.LogCurveInfo.Select(lci => lci.Mnemonic).ToList();

            var targetLogMnemonics        = targetLog.LogCurveInfo.Select(lci => lci.Mnemonic);
            var existingMnemonicsInTarget = mnemonicsToCopy.Where(mnemonic => targetLogMnemonics.Contains(mnemonic, StringComparer.OrdinalIgnoreCase)).ToList();
            var newMnemonicsInTarget      = mnemonicsToCopy.Where(mnemonic => !targetLogMnemonics.Contains(mnemonic, StringComparer.OrdinalIgnoreCase)).ToList();

            try
            {
                VerifyMatchingIndexTypes(sourceLog, targetLog);
                VerifyValidInterval(sourceLog);
                VerifyMatchingIndexCurves(sourceLog, targetLog);
                VerifyIndexCurveIsIncludedInMnemonics(sourceLog, newMnemonicsInTarget, existingMnemonicsInTarget);
                await VerifyTargetHasRequiredLogCurveInfos(sourceLog, job.SourceLogCurvesReference.Mnemonics, targetLog);
            }
            catch (Exception e)
            {
                Log.Error(e, "Failed to copy log data");
                return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Failed to copy log data", e.Message), null);
            }

            var copyResultForExistingMnemonics = await CopyLogData(sourceLog, targetLog, job, existingMnemonicsInTarget);

            if (!copyResultForExistingMnemonics.Success)
            {
                var message = $"Failed to copy curves for existing mnemonics to log. Copied a total of {copyResultForExistingMnemonics.NumberOfRowsCopied} rows";
                return(LogAndReturnErrorResult(message));
            }

            var copyResultForNewMnemonics = await CopyLogData(sourceLog, targetLog, job, newMnemonicsInTarget);

            if (!copyResultForNewMnemonics.Success)
            {
                var message = $"Failed to copy curves for new mnemonics to log. Copied a total of {copyResultForNewMnemonics.NumberOfRowsCopied} rows";
                return(LogAndReturnErrorResult(message));
            }

            var totalRowsCopied = copyResultForExistingMnemonics.NumberOfRowsCopied + copyResultForNewMnemonics.NumberOfRowsCopied;

            Log.Information("{JobType} - Job successful. {Count} rows copied", GetType().Name, totalRowsCopied);
            var workerResult  = new WorkerResult(witsmlClient.GetServerHostname(), true, $"{totalRowsCopied} rows copied");
            var refreshAction = new RefreshLogObject(witsmlClient.GetServerHostname(), job.TargetLogReference.WellUid, job.TargetLogReference.WellboreUid, job.TargetLogReference.LogUid, RefreshType.Update);

            return(workerResult, refreshAction);
        }
        public override async Task <(WorkerResult, RefreshAction)> Execute(DeleteMnemonicsJob job)
        {
            var wellUid         = job.LogObject.WellUid;
            var wellboreUid     = job.LogObject.WellboreUid;
            var logUid          = job.LogObject.LogUid;
            var mnemonics       = new ReadOnlyCollection <string>(job.Mnemonics.ToList());
            var mnemonicsString = string.Join(", ", mnemonics);

            var query  = LogQueries.DeleteMnemonics(wellUid, wellboreUid, logUid, mnemonics);
            var result = await witsmlClient.DeleteFromStoreAsync(query);

            if (result.IsSuccessful)
            {
                Log.Information("{JobType} - Job successful", GetType().Name);
                var refreshAction = new RefreshLogObject(witsmlClient.GetServerHostname(), wellUid, wellboreUid, logUid, RefreshType.Update);
                var workerResult  = new WorkerResult(witsmlClient.GetServerHostname(), true, $"Deleted mnemonics: {mnemonicsString} for log: {logUid}");
                return(workerResult, refreshAction);
            }

            Log.Error("Failed to delete mnemonics for log object. WellUid: {WellUid}, WellboreUid: {WellboreUid}, Uid: {LogUid}, Mnemonics: {MnemonicsString}",
                      wellUid,
                      wellboreUid,
                      logUid,
                      mnemonics);

            query = LogQueries.GetWitsmlLogById(wellUid, wellboreUid, logUid);
            var queryResult = await witsmlClient.GetFromStoreAsync(query, new OptionsIn(ReturnElements.IdOnly));

            var log = queryResult.Logs.First();
            EntityDescription description = null;

            if (log != null)
            {
                description = new EntityDescription
                {
                    WellName     = log.NameWell,
                    WellboreName = log.NameWellbore,
                    ObjectName   = log.Name
                };
            }

            return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Failed to delete mnemonics", result.Reason, description), null);
        }
        public override async Task <(WorkerResult, RefreshAction)> Execute(DeleteCurveValuesJob job)
        {
            var wellUid     = job.LogReference.WellUid;
            var wellboreUid = job.LogReference.WellboreUid;
            var logUid      = job.LogReference.LogUid;
            var witsmlLog   = await GetLogHeader(wellUid, wellboreUid, logUid);

            if (witsmlLog == null)
            {
                var reason = $"Did not find witsml log for wellUid: {wellUid}, wellboreUid: {wellboreUid}, logUid: {logUid}";
                return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Unable to find log", reason), null);
            }

            var logCurveInfos = witsmlLog.LogCurveInfo.Where(logCurveInfo => job.Mnemonics.Contains(logCurveInfo.Mnemonic)).ToList();
            var deleteQueries = CreateDeleteQueries(job, witsmlLog, logCurveInfos);

            foreach (var query in deleteQueries)
            {
                var result = await witsmlClient.DeleteFromStoreAsync(query);

                if (result.IsSuccessful)
                {
                    Log.Information("{JobType} - Job successful", GetType().Name);
                }
                else
                {
                    Log.Error("Failed to delete mnemonics for log object. WellUid: {WellUid}, WellboreUid: {WellboreUid}, Uid: {LogUid}, Mnemonics: {MnemonicsString}",
                              wellUid,
                              wellboreUid,
                              logUid,
                              string.Join(", ", job.Mnemonics));

                    return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Failed to delete mnemonics", result.Reason, witsmlLog.GetDescription()), null);
                }
            }

            var refreshAction  = new RefreshLogObject(witsmlClient.GetServerHostname(), wellUid, wellboreUid, logUid, RefreshType.Update);
            var mnemonicsOnLog = string.Join(", ", logCurveInfos.Select(logCurveInfo => logCurveInfo.Mnemonic));
            var workerResult   = new WorkerResult(witsmlClient.GetServerHostname(), true, $"Deleted curve info values for mnemonics: {mnemonicsOnLog}, for log: {logUid}");

            return(workerResult, refreshAction);
        }
        public async Task <(WorkerResult, RefreshAction)> Execute(TrimLogDataJob job)
        {
            var witsmlLogQuery = LogQueries.QueryById(job.LogObject.WellUid, job.LogObject.WellboreUid, job.LogObject.LogUid);
            var witsmlLogs     = await witsmlClient.GetFromStoreAsync(witsmlLogQuery, OptionsIn.HeaderOnly);

            var witsmlLog = witsmlLogs.Logs.First();

            var currentStartIndex = Index.Start(witsmlLog);
            var newStartIndex     = Index.Start(witsmlLog, job.StartIndex);
            var currentEndIndex   = Index.End(witsmlLog);
            var newEndIndex       = Index.End(witsmlLog, job.EndIndex);

            bool trimmedStartOfLog = false;

            if (currentStartIndex < newStartIndex && newStartIndex < currentEndIndex)
            {
                var trimLogObjectStartQuery = CreateRequest(
                    job.LogObject.WellUid,
                    job.LogObject.WellboreUid,
                    job.LogObject.LogUid,
                    witsmlLog.IndexType,
                    deleteTo: newStartIndex);

                var result = await witsmlClient.DeleteFromStoreAsync(trimLogObjectStartQuery);

                if (result.IsSuccessful)
                {
                    trimmedStartOfLog = true;
                }
                else
                {
                    Log.Error($"Job failed. An error occurred when trimming logobject start: {job.PrintProperties()}");
                    return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Failed to update start of log", result.Reason, GetDescription(witsmlLog)), null);
                }
            }

            bool trimmedEndOfLog = false;

            if (currentEndIndex > newEndIndex && newEndIndex > currentStartIndex)
            {
                var trimLogObjectEndQuery = CreateRequest(
                    job.LogObject.WellUid,
                    job.LogObject.WellboreUid,
                    job.LogObject.LogUid,
                    witsmlLog.IndexType,
                    deleteFrom: newEndIndex);

                var result = await witsmlClient.DeleteFromStoreAsync(trimLogObjectEndQuery);

                if (result.IsSuccessful)
                {
                    trimmedEndOfLog = true;
                }
                else
                {
                    Log.Error($"Job failed. An error occurred when trimming logobject end: {job.PrintProperties()}");
                    return(new WorkerResult(witsmlClient.GetServerHostname(), false, "Failed to update end of log", result.Reason, GetDescription(witsmlLog)), null);
                }
            }

            var refreshAction = new RefreshLogObject(witsmlClient.GetServerHostname(), job.LogObject.WellUid, job.LogObject.WellboreUid, job.LogObject.LogUid, RefreshType.Update);

            if (trimmedStartOfLog && trimmedEndOfLog)
            {
                return(new WorkerResult(witsmlClient.GetServerHostname(), true, $"Updated start/end of log [{job.LogObject.LogUid}]"), refreshAction);
            }
            if (trimmedStartOfLog)
            {
                return(new WorkerResult(witsmlClient.GetServerHostname(), true, $"Updated start of log [{job.LogObject.LogUid}]"), refreshAction);
            }
            if (trimmedEndOfLog)
            {
                return(new WorkerResult(witsmlClient.GetServerHostname(), true, $"Updated end of log [{job.LogObject.LogUid}]"), refreshAction);
            }

            return(new WorkerResult(witsmlClient.GetServerHostname(), false, $"Failed to update start/end of log [{job.LogObject.LogUid}]", "Invalid index range"), null);
        }