public override void Execute(CancellationToken cancellationToken)
        {
            base.Execute(cancellationToken);

            var integrityCheckStopwatch = new Stopwatch();
            var optionalParams          = new PatcherStatistics.OptionalParams
            {
                VersionId = _versionId,
            };

            System.Func <PatcherStatistics.OptionalParams> timedParams = () => new PatcherStatistics.OptionalParams {
                VersionId = optionalParams.VersionId,
                Time      = integrityCheckStopwatch.Elapsed.Seconds,
            };

            try
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ValidationStarted, optionalParams);
                ExecuteInternal(cancellationToken);

                if (Results.Files.All(integrity => integrity.Status == FileIntegrityStatus.Ok))
                {
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ValidationSucceeded, timedParams());
                }
                else
                {
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ValidationFailed, timedParams());
                }
            }
            catch (System.OperationCanceledException)
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ValidationCanceled, timedParams());
                throw;
            }
        }
        private FileIntegrity CheckFile(AppContentSummaryFile file)
        {
            Action onVerificationFailed = () =>
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.FileVerificationFailed, new PatcherStatistics.OptionalParams
                {
                    FileName = file.Path,
                    Size     = file.Size,
                });
            };

            string localPath = _localDirectory.Path.PathCombine(file.Path);

            if (!File.Exists(localPath))
            {
                onVerificationFailed();
                return(new FileIntegrity(file.Path, FileIntegrityStatus.MissingData));
            }

            if (!_localMetaData.IsEntryRegistered(file.Path))
            {
                onVerificationFailed();
                return(new FileIntegrity(file.Path, FileIntegrityStatus.MissingMetaData));
            }

            int actualVersionId = _localMetaData.GetEntryVersionId(file.Path);

            if (actualVersionId != _versionId)
            {
                onVerificationFailed();
                return(FileIntegrity.InvalidVersion(_versionId, actualVersionId, file.Path));
            }

            if (_isCheckingSize)
            {
                long actualSize = new FileInfo(localPath).Length;
                if (actualSize != file.Size)
                {
                    onVerificationFailed();
                    return(FileIntegrity.InvalidSize(file.Size, actualSize, file.Path));
                }
            }

            if (_isCheckingHash)
            {
                string actualFileHash = HashCalculator.ComputeFileHash(localPath);
                if (actualFileHash != file.Hash)
                {
                    onVerificationFailed();
                    return(FileIntegrity.InvalidHash(file.Hash, actualFileHash, file.Path));
                }
            }

            return(new FileIntegrity(file.Path, FileIntegrityStatus.Ok));
        }
        public void Update(CancellationToken cancellationToken)
        {
            Assert.MethodCalledOnlyOnce(ref _updateHasBeenCalled, "Update");
            Assert.ApplicationIsInstalled(_context.App);

            DebugLogger.Log("Updating with diff strategy.");

            var latestVersionId       = _context.App.GetLatestVersionId(true, cancellationToken);
            var currentLocalVersionId = _context.App.GetInstalledVersionId();

            DebugLogger.LogVariable(latestVersionId, "latestVersionId");
            DebugLogger.LogVariable(currentLocalVersionId, "currentLocalVersionId");

            var commandFactory   = new AppUpdaterCommandFactory();
            var geolocateCommand = commandFactory.CreateGeolocateCommand();

            geolocateCommand.Prepare(_status, cancellationToken);
            geolocateCommand.Execute(cancellationToken);

            var checkDiskSpaceCommand = commandFactory.CreateCheckDiskSpaceCommandForDiff(latestVersionId, _context, cancellationToken);

            checkDiskSpaceCommand.Prepare(_status, cancellationToken);
            checkDiskSpaceCommand.Execute(cancellationToken);

            var validateLicense = commandFactory.CreateValidateLicenseCommand(_context);

            validateLicense.Prepare(_status, cancellationToken);
            validateLicense.Execute(cancellationToken);

            var diffCommandsList = new List <DiffCommands>();

            for (int i = currentLocalVersionId + 1; i <= latestVersionId; i++)
            {
                DiffCommands diffCommands;

                var resource = _context.App.RemoteData.GetDiffPackageResource(i, validateLicense.KeySecret, geolocateCommand.CountryCode, cancellationToken);

                diffCommands.Download = new DiffCommands.Context <IDownloadPackageCommand> {
                    Command = commandFactory.CreateDownloadDiffPackageCommand(i, validateLicense.KeySecret,
                                                                              geolocateCommand.CountryCode, _context, cancellationToken),
                    VersionId = i,
                    Size      = resource.Size,
                };
                diffCommands.Download.Command.Prepare(_status, cancellationToken);

                diffCommands.Install = commandFactory.CreateInstallDiffCommand(i, _context);
                diffCommands.Install.Prepare(_status, cancellationToken);

                diffCommandsList.Add(diffCommands);
            }

            foreach (var diffCommands in diffCommandsList)
            {
                var optionalParams = new PatcherStatistics.OptionalParams
                {
                    Size      = diffCommands.Download.Size,
                    VersionId = diffCommands.Download.VersionId
                };

                try
                {
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.PatchDownloadStarted, optionalParams);
                    diffCommands.Download.Command.Execute(cancellationToken);
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.PatchDownloadSucceeded, optionalParams);
                }
                catch (OperationCanceledException)
                {
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.PatchDownloadCanceled, optionalParams);
                    throw;
                }
                catch (Exception)
                {
                    PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.PatchDownloadFailed, optionalParams);
                    throw;
                }

                diffCommands.Install.Execute(cancellationToken);
            }

            _context.App.DownloadDirectory.Clear();
        }
Beispiel #4
0
        public void Update(CancellationToken cancellationToken)
        {
            Assert.MethodCalledOnlyOnce(ref _updateHasBeenCalled, "Update");

            DebugLogger.Log("Updating with content strategy.");

            var commandFactory   = new Commands.AppUpdaterCommandFactory();
            var geolocateCommand = commandFactory.CreateGeolocateCommand();

            geolocateCommand.Prepare(_status);
            geolocateCommand.Execute(cancellationToken);

            var latestVersionId = _context.App.GetLatestVersionId();

            DebugLogger.LogVariable(latestVersionId, "latestVersionId");

            var checkDiskSpaceCommand = commandFactory.CreateCheckDiskSpaceCommandForContent(latestVersionId, _context);

            checkDiskSpaceCommand.Prepare(_status);
            checkDiskSpaceCommand.Execute(cancellationToken);

            var validateLicense = commandFactory.CreateValidateLicenseCommand(_context);

            validateLicense.Prepare(_status);
            validateLicense.Execute(cancellationToken);

            var uninstall = commandFactory.CreateUninstallCommand(_context);

            uninstall.Prepare(_status);

            var resource = _context.App.RemoteData.GetContentPackageResource(latestVersionId, validateLicense.KeySecret, geolocateCommand.CountryCode);

            var downloadContentPackage = commandFactory.CreateDownloadContentPackageCommand(latestVersionId,
                                                                                            validateLicense.KeySecret, geolocateCommand.CountryCode, _context);

            downloadContentPackage.Prepare(_status);

            var installContent = commandFactory.CreateInstallContentCommand(latestVersionId, _context);

            installContent.Prepare(_status);

            uninstall.Execute(cancellationToken);

            var downloadStopwatch = new Stopwatch();
            var optionalParams    = new PatcherStatistics.OptionalParams
            {
                VersionId = latestVersionId,
                Size      = resource.Size,
            };

            Func <PatcherStatistics.OptionalParams> timedParams = () => new PatcherStatistics.OptionalParams {
                VersionId = optionalParams.VersionId,
                Size      = optionalParams.Size,
                Time      = downloadStopwatch.Elapsed.Seconds,
            };

            try
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ContentDownloadStarted, optionalParams);
                downloadStopwatch.Start();
                downloadContentPackage.Execute(cancellationToken);
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ContentDownloadSucceeded, timedParams());
            }
            catch (OperationCanceledException)
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ContentDownloadCanceled, timedParams());
                throw;
            }
            catch (Exception)
            {
                PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.ContentDownloadFailed, timedParams());
                throw;
            }

            installContent.Execute(cancellationToken);

            _context.App.DownloadDirectory.Clear();
        }
Beispiel #5
0
        public override void Execute(CancellationToken cancellationToken)
        {
            try
            {
                PatcherStatistics.TryDispatchSendEvent(PatcherStatistics.Event.LicenseKeyVerificationStarted);

                _logger.LogDebug("Validating license...");

                base.Execute(cancellationToken);

                KeySecret = null;

                var appInfo = _remoteMetaData.GetAppInfo();

                if (!appInfo.UseKeys)
                {
                    _logger.LogDebug("Validating license is not required - application is not using license keys.");
                    return;
                }

                var messageType = LicenseDialogMessageType.None;

                var cachedKey = GetCachedKey();
                _logger.LogTrace("Cached key = " + cachedKey);

                bool didUseCachedKey = false;

                while (KeySecret == null)
                {
                    bool   isUsingCachedKey;
                    string key = GetKey(messageType, cachedKey, out isUsingCachedKey, ref didUseCachedKey);

                    try
                    {
                        _logger.LogTrace("Key = " + key);

                        var cachedKeySecret = GetCachedKeySecret(key);
                        _logger.LogTrace("Cached key secret = " + cachedKeySecret);

                        _logger.LogDebug("Validating key...");

                        KeySecret = _remoteMetaData.GetKeySecret(key, cachedKeySecret);

                        _logger.LogDebug("License has been validated!");
                        PatcherStatistics.TryDispatchSendEvent(PatcherStatistics.Event.LicenseKeyVerificationSucceeded);

                        _logger.LogTrace("KeySecret = " + KeySecret);

                        _logger.LogDebug("Saving key and key secret to cache.");
                        SetCachedKey(key);
                        SetCachedKeySecret(key, KeySecret);
                    }
                    catch (ApiResponseException apiResponseException)
                    {
                        _logger.LogWarning(
                            "Key validation failed due to server or API error. Checking if error can be recognized and displayed to user...",
                            apiResponseException);

                        if (TryToHandleApiErrors(apiResponseException.StatusCode, ref messageType, isUsingCachedKey))
                        {
                            PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.LicenseKeyVerificationFailed);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    catch (ApiConnectionException apiConnectionException)
                    {
                        _logger.LogWarning(
                            "Key validation failed due to connection issues with API server. Setting license dialog message to ServiceUnavailable",
                            apiConnectionException);
                        messageType = LicenseDialogMessageType.ServiceUnavailable;
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError("Validating license has failed.", e);
                throw;
            }
        }