/// <summary>
        /// Saves the result of the upload
        /// </summary>
        /// <param name="command">The command</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>The upload result</returns>
        public async Task <IUploadResult> Upload(TCommand command, CancellationToken cancellationToken)
        {
            Argument.NotNull(command, nameof(command));

            var uploadResult = await _uploader
                               .Upload(command, cancellationToken)
                               .ConfigureAwait(Await.Default);

            var now = _dateTimeProvider.UtcNow;

            var file = _dataContext.DataSources
                       .Where(x => string.Equals(command.Path, x.Path, StringComparison.OrdinalIgnoreCase) == true)
                       .FirstOrDefault();

            if (file == null)
            {
                file = new DataSource
                {
                    Path     = command.Path,
                    Attempts = 0,
                };

                _dataContext.DataSources.Add(file);
            }

            if (file.Attempts.HasValue == false)
            {
                file.Attempts = 0;
            }

            if (uploadResult.Success == true)
            {
                var query = new HashFileQuery
                {
                    File = command.File,
                };

                var queryResult = await _hashFileQueryHandler
                                  .Handle(query, cancellationToken)
                                  .ConfigureAwait(Await.Default);

                file.UploadNeeded      = false;
                file.LastUploadDate    = now;
                file.Size              = command.Size;
                file.Hash              = queryResult.Hash;
                file.CreationTimeUtc   = command.CreationTimeUtc;
                file.LastWriteTimeUtc  = command.LastWriteTimeUtc;
                file.LastHashCheckDate = now;
                file.Attempts          = 1;
            }
            else
            {
                file.UploadNeeded = true;
                file.Attempts++;
            }

            await _dataContext
            .SaveChanges(cancellationToken)
            .ConfigureAwait(Await.Default);

            return(uploadResult);
        }
Пример #2
0
        /// <summary>
        /// Handle the command
        /// </summary>
        /// <param name="command">The command</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>The command result</returns>
        public async Task <QueueIntegrationImportCommandResult> Handle(
            QueueIntegrationImportCommand command,
            CancellationToken cancellationToken)
        {
            Argument.NotNull(command, nameof(command));

            var commandResult = new QueueIntegrationImportCommandResult();

            if (_dataContext.IntegrationImports.TryGetValue(command.IntegrationId, out var integrationImport) == false)
            {
                integrationImport = new IntegrationImport
                {
                    IntegrationId = command.IntegrationId,
                };

                _dataContext.IntegrationImports.Add(command.IntegrationId, integrationImport);
            }

            var fileInfo = _fileInfoFactory.FromFileName(command.File);

            if (fileInfo.Exists)
            {
                var versionId = _guidProvider.NewGuid();

                string extension = fileInfo.Extension;

                var now = _dateTimeProvider.UtcNow;

                string queueFolder = _configuration.Value.QueueFolder;

                string orignalFileName = fileInfo.Name;

                var fileDate = new DateTimeOffset(fileInfo.LastWriteTimeUtc, TimeSpan.Zero);

                string fileName = string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}_{1:yyyyMMddHHmmssfff}_{2}{3}",
                    command.IntegrationId,
                    now,
                    versionId,
                    extension);

                var filePath = _path.Combine(queueFolder, fileName);

                long size = fileInfo.Length;

                if (command.MoveFile == true)
                {
                    fileInfo.MoveTo(filePath);

                    var queueItem = new IntegrationImportQueueItem
                    {
                        IntegrationId = command.IntegrationId,
                        File          = filePath,
                        FileName      = orignalFileName,
                        FileSize      = size,
                        FileDate      = fileDate,
                        Hash          = null,
                        FileVersionId = versionId,
                    };

                    _dataContext.IntegrationImportQueue.Add(queueItem);
                }
                else
                {
                    using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var query = new HashFileQuery
                        {
                            File = stream
                        };

                        var queryResult = await _queryHandler
                                          .Handle(query, cancellationToken)
                                          .ConfigureAwait(Await.Default);

                        _ = stream.Seek(0, SeekOrigin.Begin);

                        if (string.Equals(integrationImport.Hash, queryResult.Hash, StringComparison.Ordinal) == false)
                        {
                            integrationImport.Hash = queryResult.Hash;
                            integrationImport.Size = size;

                            var writeCommand = new WriteFileFromStreamCommand
                            {
                                Path     = queueFolder,
                                FileName = fileName,
                                File     = stream,
                                Size     = size
                            };

                            var writeCommandResult = await _commandHandler
                                                     .Handle(writeCommand, cancellationToken)
                                                     .ConfigureAwait(Await.Default);

                            switch (writeCommandResult.Result)
                            {
                            case WriteFileFromStreamCommandResultKind.Success:
                                break;

                            default:
                                throw UnexpectedEnumValueException.Create(writeCommandResult.Result);
                            }

                            string hash = queryResult.Hash;

                            var queueItem = new IntegrationImportQueueItem
                            {
                                IntegrationId = command.IntegrationId,
                                File          = filePath,
                                FileName      = orignalFileName,
                                FileSize      = size,
                                FileDate      = fileDate,
                                Hash          = hash,
                                FileVersionId = versionId,
                            };

                            _dataContext.IntegrationImportQueue.Add(queueItem);
                        }
                    }
                }
            }

            return(commandResult);
        }
Пример #3
0
        /// <summary>
        /// Handles the checking if the file needs to be uploaded
        /// </summary>
        /// <param name="query">The query</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>The response</returns>
        public async Task <FileNeedsUploadQueryResult> Handle(
            FileNeedsUploadQuery query,
            CancellationToken cancellationToken)
        {
            Argument.NotNull(query, nameof(query));

            var queryResult = new FileNeedsUploadQueryResult();

            var file = _dataContext.DataSources
                       .Where(x => string.Equals(query.Path, x.Path, StringComparison.OrdinalIgnoreCase) == true)
                       .FirstOrDefault();

            var now = _dateTimeProvider.UtcNow;

            bool upload = false;

            var maxFileAge = _configuration.Value.MaxFileAge;

            var maxFileHashAge = _configuration.Value.MaxFileHashAge;

            if (file == null)
            {
                upload = true;
            }

            else if (file.UploadNeeded == true)
            {
                upload = true;
            }

            else if (file.Size.HasValue == false ||
                     file.Size != query.Size)
            {
                upload = true;
            }

            else if (file.CreationTimeUtc.HasValue == false ||
                     file.CreationTimeUtc != query.CreationTimeUtc)
            {
                upload = true;
            }

            else if (file.LastWriteTimeUtc.HasValue == false ||
                     file.LastWriteTimeUtc != query.LastWriteTimeUtc)
            {
                upload = true;
            }

            else if (file.LastUploadDate.HasValue == false ||
                     now - file.LastUploadDate >= maxFileAge)
            {
                upload = true;
            }

            else if (file.LastHashCheckDate.HasValue == false ||
                     string.IsNullOrEmpty(file.Hash) == true ||
                     now - file.LastHashCheckDate >= maxFileHashAge)
            {
                var hashFileQuery = new HashFileQuery
                {
                    File = query.File,
                };

                var hashFileQueryResult = await _hashFileQueryHandler
                                          .Handle(hashFileQuery, cancellationToken)
                                          .ConfigureAwait(Await.Default);

                if (string.Equals(file.Hash, hashFileQueryResult.Hash, StringComparison.Ordinal) == false)
                {
                    upload = true;
                }
            }

            queryResult.FileNeedsUpload = upload;

            return(queryResult);
        }