Example #1
0
        /// <summary>
        /// Builds a <see cref="SqlStrategy"/> with a policy for retrying
        /// actions on transaction failures.
        /// </summary>
        /// <param name="sqlStrategy">The SQL strategy.</param>
        /// <param name="exceptionHandlingStrategy">
        /// The exception handling strategy used to determine which exceptions
        /// should be retried.
        /// </param>
        /// <param name="sqlStrategyConfiguration">
        /// An <see cref="SqlStrategyOptions"/> containing configuration parameters.
        /// </param>
        /// <returns>The strategy instance.</returns>
        public static SqlStrategyBuilder Retry(this SqlStrategyBuilder sqlStrategy, IExceptionHandlingStrategy exceptionHandlingStrategy, SqlStrategyOptions sqlStrategyConfiguration)
        {
            var backoff = Backoff.ExponentialBackoff(TimeSpan.FromSeconds(2), sqlStrategyConfiguration.RetryCount());

            sqlStrategy.Policies.Add(Policy.Handle <SqlException>(exceptionHandlingStrategy.ShouldHandle).WaitAndRetry(backoff, SqlStrategyLoggingDelegates.OnRetry).WithPolicyKey(SqlServerPolicyKeys.TransactionPolicy));
            sqlStrategy.Policies.Add(Policy.Handle <SqlException>(exceptionHandlingStrategy.ShouldHandle).WaitAndRetryAsync(backoff, SqlStrategyLoggingDelegates.OnRetryAsync).WithPolicyKey(SqlServerPolicyKeys.TransactionPolicyAsync));
            return(sqlStrategy);
        }
        protected ExceptionHandlerBase(IExceptionHandlingStrategy exceptionHandlingStrategy)
        {
            Guard.ArgumentNotNull(exceptionHandlingStrategy, nameof(exceptionHandlingStrategy));

            this.exceptionHandlingStrategy = exceptionHandlingStrategy;

            // Before attaching we want to make sure, we only have one subscription at the time
            this.InternalDetach();

            // Call Attach in order to wire up platform-specific crash observation
            this.InternalAttach();
        }
        public BatchEntityRepositoryAdapter(
            IWriteOnlyEntityRepository <TEntityId, TEntityVersion, TEntity, TContext> inner,
            IExceptionHandlingStrategy exceptionHandlingStrategy)
        {
            if (inner == null)
            {
                throw new ArgumentNullException(nameof(inner));
            }
            if (exceptionHandlingStrategy == null)
            {
                throw new ArgumentNullException(nameof(exceptionHandlingStrategy));
            }

            _inner = inner;
            _exceptionHandlingStrategy = exceptionHandlingStrategy;
        }
        /// <summary>
        ///     Sets the SynchronisationContext for ui thread so that async void exceptions can be handled.
        ///     <example>
        ///         Example: Call this method with 'await' and observe the WrapCallback method:
        ///         private async void Test()
        ///         {
        ///         throw new Exception("TestException");
        ///         }
        ///     </example>
        /// </summary>
        /// <param name="strategy"></param>
        /// <returns></returns>
        public static AsyncSynchronizationContext Register(IExceptionHandlingStrategy strategy)
        {
            Guard.ArgumentNotNull(strategy, nameof(strategy));

            exceptionHandlingStrategy = strategy;

            var currentSyncContext = Current;
            if (currentSyncContext == null)
            {
                string nullContextInfo = "Ensure a synchronization context exists before calling this method. A synchronization context usually exists after the UI has been initialized. If your application does not have a UI you can ignore this message.";
                tracer.Info(nullContextInfo);

                return null;
            }

            var customSynchronizationContext = currentSyncContext as AsyncSynchronizationContext;
            if (customSynchronizationContext == null)
            {
                customSynchronizationContext = new AsyncSynchronizationContext(currentSyncContext);
                SetSynchronizationContext(customSynchronizationContext);
            }

            return customSynchronizationContext;
        }
        public ComponentContainer(Application application, IGeneralOptionsDataAccess generalOptionsDataAccess, IComWrapperFactory comWrapperFactory, IExceptionHandlingStrategy exceptionHandlingStrategy)
        {
            if (application == null)
            {
                throw new ArgumentNullException(nameof(application));
            }
            if (generalOptionsDataAccess == null)
            {
                throw new ArgumentNullException(nameof(generalOptionsDataAccess));
            }
            if (comWrapperFactory == null)
            {
                throw new ArgumentNullException(nameof(comWrapperFactory));
            }

            s_logger.Info("Startup...");
            s_logger.Info($"Version: {Assembly.GetExecutingAssembly().GetName().Version}");
            s_logger.Info($"Operating system: {Environment.OSVersion}");

            _profileTypeRegistry = ProfileTypeRegistry.Instance;

            if (GeneralOptionsDataAccess.WpfRenderModeSoftwareOnly)
            {
                RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
            }

            _generalOptionsDataAccess = generalOptionsDataAccess;

            _synchronizationStatus = new SynchronizationStatus();

            var generalOptions = _generalOptionsDataAccess.LoadOptions();

            _daslFilterProvider = new DaslFilterProvider(generalOptions.IncludeCustomMessageClasses);

            SetWpfLocale(generalOptions.CultureName);

            ConfigureServicePointManager(generalOptions);
            ConfigureLogLevel(generalOptions.EnableDebugLog);

            _session = application.Session;

            _outlookAccountPasswordProvider =
                string.IsNullOrEmpty(_session.CurrentProfileName)
              ? NullOutlookAccountPasswordProvider.Instance
              : new OutlookAccountPasswordProvider(_session.CurrentProfileName, application.Version);

            _globalTimeZoneCache = new GlobalTimeZoneCache();


            var applicationDataDirectoryBase = Path.Combine(
                Environment.GetFolderPath(
                    generalOptions.StoreAppDataInRoamingFolder ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.LocalApplicationData),
                "CalDavSynchronizer");

            string optionsFilePath;

            (_applicationDataDirectory, optionsFilePath) = GetOrCreateDataDirectory(applicationDataDirectoryBase, _session.CurrentProfileName);

            _optionsDataAccess = new OptionsDataAccess(optionsFilePath);

            _uiService = new UiService();
            var options = _optionsDataAccess.Load();

            _permanentStatusesViewModel = new PermanentStatusesViewModel(_uiService, this, options);
            _permanentStatusesViewModel.OptionsRequesting += PermanentStatusesViewModel_OptionsRequesting;

            _queryFolderStrategyWrapper = new OutlookFolderStrategyWrapper(QueryOutlookFolderByRequestingItemStrategy.Instance);

            _totalProgressFactory = new TotalProgressFactory(
                _uiService,
                generalOptions.ShowProgressBar,
                generalOptions.ThresholdForProgressDisplay,
                ExceptionHandler.Instance);


            _outlookSession      = new OutlookSession(_session);
            _synchronizerFactory = new SynchronizerFactory(
                GetProfileDataDirectory,
                _totalProgressFactory,
                _outlookSession,
                _daslFilterProvider,
                _outlookAccountPasswordProvider,
                _globalTimeZoneCache,
                _queryFolderStrategyWrapper,
                exceptionHandlingStrategy,
                comWrapperFactory,
                _optionsDataAccess,
                _profileTypeRegistry);

            _synchronizationReportRepository = CreateSynchronizationReportRepository();

            UpdateGeneralOptionDependencies(generalOptions);

            _scheduler = new Scheduler(
                _synchronizerFactory,
                this,
                EnsureSynchronizationContext,
                new FolderChangeWatcherFactory(
                    _session),
                _synchronizationStatus);

            EnsureCacheCompatibility(options);

            _availableVersionService          = new AvailableVersionService();
            _updateChecker                    = new UpdateChecker(_availableVersionService, () => _generalOptionsDataAccess.IgnoreUpdatesTilVersion);
            _updateChecker.NewerVersionFound += UpdateChecker_NewerVersionFound;
            _updateChecker.IsEnabled          = generalOptions.ShouldCheckForNewerVersions;

            _reportGarbageCollection = new ReportGarbageCollection(_synchronizationReportRepository, TimeSpan.FromDays(generalOptions.MaxReportAgeInDays));

            _trayNotifier = generalOptions.EnableTrayIcon ? new TrayNotifier(this) : NullTrayNotifer.Instance;

            try
            {
                using (var syncObjects = GenericComObjectWrapper.Create(_session.SyncObjects))
                {
                    if (syncObjects.Inner != null && syncObjects.Inner.Count > 0)
                    {
                        _syncObject = syncObjects.Inner[1];
                        if (generalOptions.TriggerSyncAfterSendReceive)
                        {
                            _syncObject.SyncEnd += SyncObject_SyncEnd;
                        }
                    }
                }
            }
            catch (COMException ex)
            {
                s_logger.Error("Can't access SyncObjects", ex);
            }

            _oneTimeTaskRunner = new OneTimeTaskRunner(_outlookSession);

            DDayICalWorkaround.DDayICalCustomization.InitializeNoThrow();
        }
 public ExceptionHandler(IExceptionHandlingStrategy exceptionHandlingStrategy)
     : base(exceptionHandlingStrategy)
 {
 }
        public Synchronizer(
            IReadOnlyEntityRepository <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TContext> atypeRepository,
            IReadOnlyEntityRepository <TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> btypeRepository,
            IBatchWriteOnlyEntityRepository <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TContext> atypeWriteRepository,
            IBatchWriteOnlyEntityRepository <TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> btypeWriteRepository,
            IInitialSyncStateCreationStrategy <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> initialSyncStateCreationStrategy,
            IEntityRelationDataAccess <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> entityRelationDataAccess,
            IEntityRelationDataFactory <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> entityRelationDataFactory,
            IInitialEntityMatcher <TAtypeEntityId, TAtypeEntityVersion, TAMatchData, TBtypeEntityId, TBtypeEntityVersion, TBMatchData> initialEntityMatcher,
            IEqualityComparer <TAtypeEntityId> atypeIdComparer, IEqualityComparer <TBtypeEntityId> btypeIdComparer,
            ITotalProgressFactory totalProgressFactory,
            IEqualityComparer <TAtypeEntityVersion> atypeVersionComparer,
            IEqualityComparer <TBtypeEntityVersion> btypeVersionComparer, IEntitySyncStateFactory <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> syncStateFactory,
            IExceptionHandlingStrategy exceptionHandlingStrategy,
            IMatchDataFactory <TAtypeEntity, TAMatchData> aMatchDataFactory,
            IMatchDataFactory <TBtypeEntity, TBMatchData> bMatchDataFactory,
            int?chunkSize,
            IChunkedExecutor chunkedExecutor,
            IFullEntitySynchronizationLoggerFactory <TAtypeEntity, TBtypeEntity> fullEntitySynchronizationLoggerFactory,
            IStateAwareEntityRepository <TAtypeEntityId, TAtypeEntityVersion, TContext, TAtypeStateToken> atypeStateAwareEntityRepository,
            IStateAwareEntityRepository <TBtypeEntityId, TBtypeEntityVersion, TContext, TBtypeStateToken> btypeStateAwareEntityRepository,
            IStateTokenDataAccess <TAtypeStateToken, TBtypeStateToken> stateTokenDataAccess,
            ISynchronizationInterceptorFactory <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> synchronizationInterceptorFactoryOrNull = null)
        {
            if (atypeRepository == null)
            {
                throw new ArgumentNullException(nameof(atypeRepository));
            }
            if (btypeRepository == null)
            {
                throw new ArgumentNullException(nameof(btypeRepository));
            }
            if (atypeWriteRepository == null)
            {
                throw new ArgumentNullException(nameof(atypeWriteRepository));
            }
            if (btypeWriteRepository == null)
            {
                throw new ArgumentNullException(nameof(btypeWriteRepository));
            }
            if (initialSyncStateCreationStrategy == null)
            {
                throw new ArgumentNullException(nameof(initialSyncStateCreationStrategy));
            }
            if (entityRelationDataAccess == null)
            {
                throw new ArgumentNullException(nameof(entityRelationDataAccess));
            }
            if (entityRelationDataFactory == null)
            {
                throw new ArgumentNullException(nameof(entityRelationDataFactory));
            }
            if (initialEntityMatcher == null)
            {
                throw new ArgumentNullException(nameof(initialEntityMatcher));
            }
            if (atypeIdComparer == null)
            {
                throw new ArgumentNullException(nameof(atypeIdComparer));
            }
            if (btypeIdComparer == null)
            {
                throw new ArgumentNullException(nameof(btypeIdComparer));
            }
            if (totalProgressFactory == null)
            {
                throw new ArgumentNullException(nameof(totalProgressFactory));
            }
            if (atypeVersionComparer == null)
            {
                throw new ArgumentNullException(nameof(atypeVersionComparer));
            }
            if (btypeVersionComparer == null)
            {
                throw new ArgumentNullException(nameof(btypeVersionComparer));
            }
            if (syncStateFactory == null)
            {
                throw new ArgumentNullException(nameof(syncStateFactory));
            }
            if (exceptionHandlingStrategy == null)
            {
                throw new ArgumentNullException(nameof(exceptionHandlingStrategy));
            }
            if (aMatchDataFactory == null)
            {
                throw new ArgumentNullException(nameof(aMatchDataFactory));
            }
            if (bMatchDataFactory == null)
            {
                throw new ArgumentNullException(nameof(bMatchDataFactory));
            }
            if (fullEntitySynchronizationLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(fullEntitySynchronizationLoggerFactory));
            }
            if (atypeStateAwareEntityRepository == null)
            {
                throw new ArgumentNullException(nameof(atypeStateAwareEntityRepository));
            }
            if (btypeStateAwareEntityRepository == null)
            {
                throw new ArgumentNullException(nameof(btypeStateAwareEntityRepository));
            }
            if (stateTokenDataAccess == null)
            {
                throw new ArgumentNullException(nameof(stateTokenDataAccess));
            }

            _chunkSize       = chunkSize;
            _chunkedExecutor = chunkedExecutor;
            _fullEntitySynchronizationLoggerFactory = fullEntitySynchronizationLoggerFactory;
            _atypeStateAwareEntityRepository        = atypeStateAwareEntityRepository;
            _btypeStateAwareEntityRepository        = btypeStateAwareEntityRepository;
            _stateTokenDataAccess = stateTokenDataAccess;

            _initialSyncStateCreationStrategy = initialSyncStateCreationStrategy;
            _totalProgressFactory             = totalProgressFactory;
            _atypeIdComparer                   = atypeIdComparer;
            _btypeIdComparer                   = btypeIdComparer;
            _atypeVersionComparer              = atypeVersionComparer;
            _btypeVersionComparer              = btypeVersionComparer;
            _syncStateFactory                  = syncStateFactory;
            _exceptionHandlingStrategy         = exceptionHandlingStrategy;
            _aMatchDataFactory                 = aMatchDataFactory;
            _bMatchDataFactory                 = bMatchDataFactory;
            _synchronizationInterceptorFactory = synchronizationInterceptorFactoryOrNull ?? NullSynchronizationInterceptorFactory <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> .Instance;
            _atypeWriteRepository              = atypeWriteRepository;
            _btypeWriteRepository              = btypeWriteRepository;
            _atypeRepository                   = atypeRepository;
            _btypeRepository                   = btypeRepository;
            _entityRelationDataAccess          = entityRelationDataAccess;
            _entityRelationDataFactory         = entityRelationDataFactory;
            _initialEntityMatcher              = initialEntityMatcher;
            _entitySyncStateChunkCreator       = new EntitySyncStateChunkCreator <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(chunkSize);
        }