public void Should_Publish_To_Host()
        {
            // Act
            _publisher.Publish("TestNotification", tenantIds: new int?[] { null });

            // Assert
            _store.Received()
            .InsertNotification(
                Arg.Is <NotificationInfo>(n => n.TenantIds == "null")
                );
        }
 public async void SendGridTest()
 {
     var config = NotificationConfigBuilder.Build();
     var sgc    = new NotificationConfiguration {
         APIKey = config.APIKey
     };
     var sendgrid = new Email
     {
         Subject = "*****@*****.**",
         To      = new System.Collections.Generic.List <string> {
             "*****@*****.**"
         },
         Content = "Hello world"
     };
     var publisher = new NotificationPublisher <SendGridNotificationAgent <Notification.Concerns.Notification> >(sgc);
     var obj       = publisher.Publish(sendgrid);
 }
        public async void Test1()
        {
            var config = NotificationConfigBuilder.Build();
            var args   = new NotificationConfiguration
            {
                Host     = config.Host,
                Port     = config.Port,
                UserName = config.UserName,
                Password = config.Password
            };
            var smtp = new Email
            {
                Subject = "*****@*****.**",
                To      = new System.Collections.Generic.List <string> {
                    "*****@*****.**"
                },
                Content = "Hello world"
            };

            var publisher = new NotificationPublisher <SMTPNotificationAgent <Notification.Concerns.Notification> >(args);
            var obj       = publisher.Publish(smtp);

            // await obj.SendAsync(
        }
Beispiel #4
0
        private async Task <bool> EnqueueMissingUpdatesAsync(ISynchronizationServerClient destinationSyncClient,
                                                             SourceSynchronizationInformation synchronizationInfo,
                                                             IList <FileHeader> needSyncingAgain)
        {
            LogFilesInfo("There were {0} file(s) that needed synchronization because the previous one went wrong: {1}",
                         needSyncingAgain);

            var filesToSynchronization = new HashSet <FileHeader>(GetFilesToSynchronization(synchronizationInfo.LastSourceFileEtag, NumberOfFilesToCheckForSynchronization),
                                                                  FileHeaderNameEqualityComparer.Instance);

            LogFilesInfo("There were {0} file(s) that needed synchronization because of greater ETag value: {1}",
                         filesToSynchronization);

            foreach (FileHeader needSyncing in needSyncingAgain)
            {
                filesToSynchronization.Add(needSyncing);
            }

            var filteredFilesToSynchronization = filesToSynchronization.Where(
                x => synchronizationStrategy.Filter(x, synchronizationInfo.DestinationServerId, filesToSynchronization)).ToList();

            if (filesToSynchronization.Count > 0)
            {
                LogFilesInfo("There were {0} file(s) that needed synchronization after filtering: {1}", filteredFilesToSynchronization);
            }

            if (filteredFilesToSynchronization.Count == 0)
            {
                var lastFileBeforeFiltering = filesToSynchronization.LastOrDefault();

                if (lastFileBeforeFiltering == null)
                {
                    return(true); // there are no more files that need
                }
                if (lastFileBeforeFiltering.Etag == synchronizationInfo.LastSourceFileEtag)
                {
                    return(true); // already updated etag on destination side
                }
                await destinationSyncClient.IncrementLastETagAsync(storage.Id, FileSystemUrl, lastFileBeforeFiltering.Etag).ConfigureAwait(false);

                return(false); // all docs has been filtered out, update etag on destination side and retry
            }

            var destinationUrl = destinationSyncClient.BaseUrl;

            bool enqueued = true;

            foreach (var fileHeader in filteredFilesToSynchronization)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                var file          = fileHeader.FullPath;
                var localMetadata = GetLocalMetadata(file);

                RavenJObject destinationMetadata;

                try
                {
                    destinationMetadata = await destinationSyncClient.GetMetadataForAsync(file).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Log.WarnException(
                        string.Format("Could not retrieve a metadata of a file '{0}' from {1} in order to determine needed synchronization type", file,
                                      destinationUrl), ex);

                    continue;
                }

                NoSyncReason reason;
                var          work = synchronizationStrategy.DetermineWork(file, localMetadata, destinationMetadata, FileSystemUrl, out reason);
                if (work == null)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("File '{0}' were not synchronized to {1}. {2}", file, destinationUrl, reason.GetDescription());
                    }

                    if (reason == NoSyncReason.ContainedInDestinationHistory)
                    {
                        var etag = localMetadata.Value <Guid>(Constants.MetadataEtagField);
                        await destinationSyncClient.IncrementLastETagAsync(storage.Id, FileSystemUrl, etag).ConfigureAwait(false);

                        RemoveSyncingConfiguration(file, destinationUrl);

                        enqueued = false;
                    }

                    continue;
                }

                if (synchronizationQueue.EnqueueSynchronization(destinationUrl, work))
                {
                    publisher.Publish(new SynchronizationUpdateNotification
                    {
                        FileName = work.FileName,
                        DestinationFileSystemUrl = destinationUrl,
                        SourceServerId           = storage.Id,
                        SourceFileSystemUrl      = FileSystemUrl,
                        Type      = work.SynchronizationType,
                        Action    = SynchronizationAction.Enqueue,
                        Direction = SynchronizationDirection.Outgoing
                    });
                }

                enqueued = true;
            }

            return(enqueued);
        }
Beispiel #5
0
        private async Task EnqueueMissingUpdatesAsync(IAsyncFilesSynchronizationCommands destination,
                                                      SourceSynchronizationInformation lastEtag,
                                                      IList <FileHeader> needSyncingAgain)
        {
            LogFilesInfo("There were {0} file(s) that needed synchronization because the previous one went wrong: {1}",
                         needSyncingAgain);

            var commands = (IAsyncFilesCommandsImpl)destination.Commands;

            var filesToSynchronization = new HashSet <FileHeader>(GetFilesToSynchronization(lastEtag, 100),
                                                                  new FileHeaderNameEqualityComparer());

            LogFilesInfo("There were {0} file(s) that needed synchronization because of greater ETag value: {1}",
                         filesToSynchronization);

            foreach (FileHeader needSyncing in needSyncingAgain)
            {
                filesToSynchronization.Add(needSyncing);
            }

            var filteredFilesToSynchronization =
                filesToSynchronization.Where(
                    x => synchronizationStrategy.Filter(x, lastEtag.DestinationServerId, filesToSynchronization)).ToList();

            if (filesToSynchronization.Count > 0)
            {
                LogFilesInfo("There were {0} file(s) that needed synchronization after filtering: {1}", filteredFilesToSynchronization);
            }

            // Early break. There are no files to synchronize to the selected destination.
            if (!filteredFilesToSynchronization.Any())
            {
                return;
            }

            var baseUrl = commands.UrlFor();

            foreach (var fileHeader in filteredFilesToSynchronization)
            {
                var file          = fileHeader.FullPath;
                var localMetadata = GetLocalMetadata(file);

                RavenJObject destinationMetadata;

                try
                {
                    destinationMetadata = await destination.Commands.GetMetadataForAsync(file);
                }
                catch (Exception ex)
                {
                    Log.WarnException(
                        string.Format("Could not retrieve a metadata of a file '{0}' from {1} in order to determine needed synchronization type", file,
                                      baseUrl), ex);

                    continue;
                }

                NoSyncReason reason;
                var          work = synchronizationStrategy.DetermineWork(file, localMetadata, destinationMetadata, FileSystemUrl, out reason);
                if (work == null)
                {
                    Log.Debug("File '{0}' were not synchronized to {1}. {2}", file, baseUrl, reason.GetDescription());

                    if (reason == NoSyncReason.ContainedInDestinationHistory)
                    {
                        var etag = localMetadata.Value <Guid>(Constants.MetadataEtagField);
                        await destination.IncrementLastETagAsync(storage.Id, baseUrl, etag);

                        RemoveSyncingConfiguration(file, baseUrl);
                    }

                    continue;
                }

                if (synchronizationQueue.EnqueueSynchronization(baseUrl, work))
                {
                    publisher.Publish(new SynchronizationUpdateNotification
                    {
                        FileName = work.FileName,
                        DestinationFileSystemUrl = baseUrl,
                        SourceServerId           = storage.Id,
                        SourceFileSystemUrl      = FileSystemUrl,
                        Type      = work.SynchronizationType,
                        Action    = SynchronizationAction.Enqueue,
                        Direction = SynchronizationDirection.Outgoing
                    });
                }
            }
        }
Beispiel #6
0
        private async Task <bool> EnqueueMissingUpdatesAsync(ISynchronizationServerClient destinationSyncClient,
                                                             SourceSynchronizationInformation synchronizationInfo,
                                                             IList <FileHeader> needSyncingAgain)
        {
            LogFilesInfo("There were {0} file(s) that needed synchronization because the previous one went wrong: {1}",
                         needSyncingAgain);

            var filesToSynchronization = new HashSet <FileHeader>(GetFilesToSynchronization(synchronizationInfo.LastSourceFileEtag, NumberOfFilesToCheckForSynchronization),
                                                                  FileHeaderNameEqualityComparer.Instance);

            LogFilesInfo("There were {0} file(s) that needed synchronization because of greater ETag value: {1}",
                         filesToSynchronization);

            foreach (FileHeader needSyncing in needSyncingAgain)
            {
                filesToSynchronization.Add(needSyncing);
            }

            var filteredFilesToSynchronization = filesToSynchronization.Where(
                x => synchronizationStrategy.Filter(x, synchronizationInfo.DestinationServerId, filesToSynchronization)).ToList();

            if (filesToSynchronization.Count > 0)
            {
                LogFilesInfo("There were {0} file(s) that needed synchronization after filtering: {1}", filteredFilesToSynchronization);
            }

            if (filteredFilesToSynchronization.Count == 0)
            {
                var lastFileBeforeFiltering = filesToSynchronization.LastOrDefault();

                if (lastFileBeforeFiltering == null)
                {
                    return(true); // there are no more files that need
                }
                if (lastFileBeforeFiltering.Etag == synchronizationInfo.LastSourceFileEtag)
                {
                    return(true); // already updated etag on destination side
                }
                await destinationSyncClient.IncrementLastETagAsync(storage.Id, FileSystemUrl, lastFileBeforeFiltering.Etag).ConfigureAwait(false);

                return(false); // all docs has been filtered out, update etag on destination side and retry
            }

            var destinationUrl = destinationSyncClient.BaseUrl;

            bool enqueued             = false;
            var  maxEtagOfFilteredDoc = Etag.Empty;

            foreach (var fileHeader in filteredFilesToSynchronization)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                var file          = fileHeader.FullPath;
                var localMetadata = GetLocalMetadata(file);

                RavenJObject destinationMetadata;

                try
                {
                    destinationMetadata = await destinationSyncClient.GetMetadataForAsync(file).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Log.WarnException(
                        string.Format("Could not retrieve a metadata of a file '{0}' from {1} in order to determine needed synchronization type", file,
                                      destinationUrl), ex);

                    continue;
                }

                NoSyncReason reason;
                var          work = synchronizationStrategy.DetermineWork(file, localMetadata, destinationMetadata, FileSystemUrl, out reason);

                if (work == null)
                {
                    Log.Debug("File '{0}' was not synchronized to {1}. {2}", file, destinationUrl, reason.GetDescription());

                    switch (reason)
                    {
                    case NoSyncReason.ContainedInDestinationHistory:
                    case NoSyncReason.DestinationFileConflicted:
                    case NoSyncReason.NoNeedToDeleteNonExistigFile:
                        var localEtag = Etag.Parse(localMetadata.Value <string>(Constants.MetadataEtagField));

                        if (reason == NoSyncReason.ContainedInDestinationHistory)
                        {
                            RemoveSyncingConfiguration(file, destinationUrl);
                        }
                        else if (reason == NoSyncReason.DestinationFileConflicted)
                        {
                            if (needSyncingAgain.Contains(fileHeader, FileHeaderNameEqualityComparer.Instance) == false)
                            {
                                CreateSyncingConfiguration(fileHeader.Name, fileHeader.Etag, destinationUrl, SynchronizationType.Unknown);
                            }
                        }
                        else if (reason == NoSyncReason.NoNeedToDeleteNonExistigFile)
                        {
                            // after the upgrade to newer build there can be still an existing syncing configuration for it
                            RemoveSyncingConfiguration(file, destinationUrl);
                        }

                        if (EtagUtil.IsGreaterThan(localEtag, maxEtagOfFilteredDoc))
                        {
                            maxEtagOfFilteredDoc = localEtag;
                        }

                        break;
                    }

                    continue;
                }

                if (synchronizationQueue.EnqueueSynchronization(destinationUrl, work))
                {
                    publisher.Publish(new SynchronizationUpdateNotification
                    {
                        FileName = work.FileName,
                        DestinationFileSystemUrl = destinationUrl,
                        SourceServerId           = storage.Id,
                        SourceFileSystemUrl      = FileSystemUrl,
                        Type      = work.SynchronizationType,
                        Action    = SynchronizationAction.Enqueue,
                        Direction = SynchronizationDirection.Outgoing
                    });
                }

                enqueued = true;
            }

            if (enqueued == false && EtagUtil.IsGreaterThan(maxEtagOfFilteredDoc, synchronizationInfo.LastSourceFileEtag))
            {
                await destinationSyncClient.IncrementLastETagAsync(storage.Id, FileSystemUrl, maxEtagOfFilteredDoc).ConfigureAwait(false);

                return(false); // we bumped the last synced etag on a destination server, let it know it need to repeat the operation
            }

            return(true);
        }
Beispiel #7
0
        private async Task <SynchronizationReport> PerformSynchronizationAsync(SynchronizationClient destination,
                                                                               SynchronizationWorkItem work)
        {
            Log.Debug("Starting to perform {0} for a file '{1}' and a destination server {2}",
                      work.GetType().Name, work.FileName, destination.FileSystemUrl);

            if (!CanSynchronizeTo(destination.FileSystemUrl))
            {
                Log.Debug("The limit of active synchronizations to {0} server has been achieved. Cannot process a file '{1}'.",
                          destination.FileSystemUrl, work.FileName);

                synchronizationQueue.EnqueueSynchronization(destination.FileSystemUrl, work);

                return(new SynchronizationReport(work.FileName, work.FileETag, work.SynchronizationType)
                {
                    Exception = new SynchronizationException(string.Format(
                                                                 "The limit of active synchronizations to {0} server has been achieved. Cannot process a file '{1}'.",
                                                                 destination.FileSystemUrl, work.FileName))
                });
            }

            string fileName = work.FileName;

            synchronizationQueue.SynchronizationStarted(work, destination.FileSystemUrl);
            publisher.Publish(new SynchronizationUpdateNotification
            {
                FileName = work.FileName,
                DestinationFileSystemUrl = destination.FileSystemUrl,
                SourceServerId           = storage.Id,
                SourceFileSystemUrl      = FileSystemUrl,
                Type   = work.SynchronizationType,
                Action = SynchronizationAction.Start,
                SynchronizationDirection = SynchronizationDirection.Outgoing
            });

            SynchronizationReport report;

            try
            {
                report = await work.PerformAsync(destination);
            }
            catch (Exception ex)
            {
                report = new SynchronizationReport(work.FileName, work.FileETag, work.SynchronizationType)
                {
                    Exception = ex,
                };
            }

            var synchronizationCancelled = false;

            if (report.Exception == null)
            {
                var moreDetails = string.Empty;

                if (work.SynchronizationType == SynchronizationType.ContentUpdate)
                {
                    moreDetails = string.Format(". {0} bytes were transfered and {1} bytes copied. Need list length was {2}",
                                                report.BytesTransfered, report.BytesCopied, report.NeedListLength);
                }

                UpdateSuccessfulSynchronizationTime();

                Log.Debug("{0} to {1} has finished successfully{2}", work.ToString(), destination.FileSystemUrl, moreDetails);
            }
            else
            {
                if (work.IsCancelled || report.Exception is TaskCanceledException)
                {
                    synchronizationCancelled = true;
                    Log.DebugException(string.Format("{0} to {1} was cancelled", work, destination.FileSystemUrl), report.Exception);
                }
                else
                {
                    Log.WarnException(string.Format("{0} to {1} has finished with the exception", work, destination.FileSystemUrl),
                                      report.Exception);
                }
            }

            Queue.SynchronizationFinished(work, destination.FileSystemUrl);

            if (!synchronizationCancelled)
            {
                CreateSyncingConfiguration(fileName, work.FileETag, destination.FileSystemUrl, work.SynchronizationType);
            }

            publisher.Publish(new SynchronizationUpdateNotification
            {
                FileName = work.FileName,
                DestinationFileSystemUrl = destination.FileSystemUrl,
                SourceServerId           = storage.Id,
                SourceFileSystemUrl      = FileSystemUrl,
                Type   = work.SynchronizationType,
                Action = SynchronizationAction.Finish,
                SynchronizationDirection = SynchronizationDirection.Outgoing
            });

            return(report);
        }