//		public Task Schedule(DateTime scheduledTime)
//		{
//			ResetWriterResult();
//			WriterResult.ScheduledTime = scheduledTime;
//			return WriterResult.Schedule();
//		}

        public void CancelSchedule(CancellationToken cancellationToken)
        {
            var runStatusResult = WriterResult.SetRunStatus(ERunStatus.Cancelled, null, null);

            if (!runStatusResult)
            {
                throw new DatajobRunException($"Failed to set status");
            }

            WriterResult.ScheduledTime = null;
        }
Exemplo n.º 2
0
 private void UpdateProgress(int percent, string message = null, Exception exception = null)
 {
     WriterResult.RowsCreated = percent;
     WriterResult.SetRunStatus(TransformWriterResult.ERunStatus.Running, message, exception);
 }
        public async Task <bool> Run(CancellationToken cancellationToken)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                WriterResult.StartTime      = DateTime.Now;
                WriterResult.LastUpdateTime = DateTime.Now;

                var runStatus = WriterResult.SetRunStatus(ERunStatus.Started, null, null);
                if (!runStatus)
                {
                    throw new DatajobRunException($"Failed to set status");
                }

                if (_transformWriterOptions.TargetAction == TransformWriterOptions.ETargetAction.Truncate)
                {
                    runStatus = WriterResult.SetRunStatus(ERunStatus.Started, "Truncating tables...", null);

                    var targetTables = new HashSet <DexihTable>();

                    foreach (var step in Datajob.DexihDatalinkSteps.Where(c => c.IsValid))
                    {
                        var datalink = _hub.DexihDatalinks.SingleOrDefault(c => c.IsValid && c.Key == step.DatalinkKey);

                        if (datalink == null)
                        {
                            throw new DatajobRunException($"The datalink in the step {step.Name} with the datalink key {step.DatalinkKey} cound not be found.");
                        }

                        foreach (var target in datalink.DexihDatalinkTargets)
                        {
                            if (target.TableKey > 0)
                            {
                                var table = _hub.GetTableFromKey(target.TableKey);
                                if (table != null)
                                {
                                    targetTables.Add(table);
                                }
                            }
                        }
                    }

                    // this loops through attempting to truncate tables one by one.
                    // is repeats when there are failures to accomodate for some table having foriegn keys

                    var atLeastOneSuccess = true;
                    var atLeastOneFail    = true;

                    while (atLeastOneSuccess && atLeastOneFail)
                    {
                        atLeastOneSuccess = false;
                        atLeastOneFail    = false;

                        var newTagetTables = new HashSet <DexihTable>();

                        foreach (var dbTable in targetTables)
                        {
                            var dbConnection = _hub.DexihConnections.SingleOrDefault(c => c.Key == dbTable.ConnectionKey);

                            if (dbConnection == null)
                            {
                                throw new DatajobRunException($"The connection for the table {dbTable.Name} with the connection key {dbTable.ConnectionKey} could not be found.");
                            }
                            var connection = dbConnection.GetConnection(_transformSettings);
                            var table      = dbTable.GetTable(_hub, connection, _transformSettings);
                            try
                            {
                                await connection.TruncateTable(table, cancellationToken);

                                atLeastOneSuccess = true;
                            }
                            catch
                            {
                                atLeastOneFail = true;
                                newTagetTables.Add(dbTable);
                            }
                        }

                        targetTables = newTagetTables;
                    }

                    if (targetTables.Count > 0)
                    {
                        var message = $"The job failed as the following tables could not be truncated: {string.Join(", ", targetTables.Select(c => c.Name))}";
                        WriterResult.SetRunStatus(ERunStatus.Abended, message, null);
                        return(false);
                    }
                }

                var inputParameters = new InputParameters();
                foreach (var parameter in Datajob.Parameters)
                {
                    inputParameters.Add(new InputParameter()
                    {
                        Name = parameter.Name, Value = parameter.Value, Rank = parameter.Rank
                    });
                }

                //start all jobs async
                foreach (var step in Datajob.DexihDatalinkSteps.Where(c => c.IsValid))
                {
                    var datalink = _hub.DexihDatalinks.SingleOrDefault(c => c.IsValid && c.Key == step.DatalinkKey);

                    if (datalink == null)
                    {
                        throw new DatajobRunException($"The step {step.Name} contains a datalink with the key {step.DatalinkKey} which can not be found.");
                    }

                    foreach (var parameter in step.Parameters)
                    {
                        parameter.Value = inputParameters.SetParameters(parameter.Value, parameter.Rank);
                    }

                    var transformSettings = new TransformSettings
                    {
                        HubVariables    = _transformSettings.HubVariables,
                        RemoteSettings  = _transformSettings.RemoteSettings,
                        InputParameters = step.Parameters.ToArray <InputParameterBase>(),
                        ClientFactory   = _transformSettings.ClientFactory
                    };

                    var inputColumns = step.DexihDatalinkStepColumns.Select(c => c.ToInputColumn()).ToArray();

                    var datalinkRun = new DatalinkRun(transformSettings, _logger, WriterResult.AuditKey, datalink, _hub, inputColumns, _transformWriterOptions, _alertQueue, _alertEmails)
                    {
                        DatalinkStepKey = step.Key
                    };

                    DatalinkSteps.Add(datalinkRun);

                    //start datalinks that have no dependencies.
                    if (step.DexihDatalinkDependencies == null || step.DexihDatalinkDependencies.Count == 0)
                    {
                        StartDatalink(datalinkRun);
                    }
                }

                WriterResult.SetRunStatus(ERunStatus.Running, null, null);

                await WaitUntilFinished();

                return(true);
            }
            catch (OperationCanceledException)
            {
                Cancel();
                await WaitUntilFinished();

                WriterResult.SetRunStatus(ERunStatus.Cancelled, "Datajob was cancelled", null);
                throw new DatajobRunException($"The datajob {Datajob.Name} was cancelled.");
            }
            catch (Exception ex)
            {
                Cancel();
                await WaitUntilFinished();

                var message = $"The job {Datajob.Name} failed.  {ex.Message}";
                WriterResult?.SetRunStatus(ERunStatus.Abended, message, ex);
                throw new DatajobRunException(message, ex);
            }
            finally
            {
                await WriterResult.CompleteDatabaseWrites();

                OnFinish?.Invoke(this);
            }
        }