예제 #1
0
        private async Task CheckDestinations(ReplicationDocument replicationDocument)
        {
            var badReplication = new List <string>();
            var request        = ApplicationModel.Current.Server.Value.SelectedDatabase.Value
                                 .AsyncDatabaseCommands
                                 .CreateRequest(string.Format("/admin/replicationInfo").NoCache(), "POST");
            await request.WriteAsync(RavenJObject.FromObject(replicationDocument).ToString());

            var responseAsJson = await request.ReadResponseJsonAsync();

            var replicationInfo = ApplicationModel.Current.Server.Value.DocumentStore.Conventions.CreateSerializer()
                                  .Deserialize <ReplicationInfoStatus[]>(new RavenJTokenReader(responseAsJson));

            foreach (var replicationInfoStatus in replicationInfo)
            {
                if (replicationInfoStatus.Status != "Valid")
                {
                    badReplication.Add(replicationInfoStatus.Url + " - " + replicationInfoStatus.Code);
                }
            }

            if (badReplication.Count != 0)
            {
                var mesage = "Some of the replications could not be reached:" + Environment.NewLine +
                             string.Join(Environment.NewLine, badReplication);

                ApplicationModel.Current.Notifications.Add(new Notification(mesage, NotificationLevel.Warning));
            }
        }
예제 #2
0
        private void RefreshReplicationInformationInternal(string url, Func <ReplicationDocument> getReplicationDestinations)
        {
            lock (this)
            {
                var serverHash = ServerHash.GetServerHash(url);

                JsonDocument document;
                var          fromFailoverUrls = false;

                try
                {
                    var replicationDestinations = getReplicationDestinations();
                    document           = replicationDestinations == null ? null : RavenJObject.FromObject(replicationDestinations).ToJsonDocument();
                    failureCounts[url] = new FailureCounter();                     // we just hit the master, so we can reset its failure count
                }
                catch (Exception e)
                {
                    log.ErrorException("Could not contact master for new replication information", e);
                    document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash);

                    if (document == null)
                    {
                        if (FailoverServers != null && FailoverServers.Length > 0)                         // try to use configured failover servers
                        {
                            var failoverServers = new ReplicationDocument {
                                Destinations = new List <ReplicationDestination>()
                            };

                            foreach (var failover in FailoverServers)
                            {
                                failoverServers.Destinations.Add(failover);
                            }

                            document = new JsonDocument
                            {
                                DataAsJson = RavenJObject.FromObject(failoverServers)
                            };

                            fromFailoverUrls = true;
                        }
                    }
                }


                if (document == null)
                {
                    lastReplicationUpdate = SystemTime.UtcNow;                     // checked and not found
                    return;
                }

                if (!fromFailoverUrls)
                {
                    ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document);
                }

                UpdateReplicationInformationFromDocument(document);

                lastReplicationUpdate = SystemTime.UtcNow;
            }
        }
예제 #3
0
        private IEnumerable <DynamicJsonValue> GenerateNodesFromReplicationDocument(ReplicationDocument replicationDocument)
        {
            var destinations = new DynamicJsonValue[replicationDocument.Destinations.Count];
            var etags        = new long[replicationDocument.Destinations.Count];

            for (int index = 0; index < replicationDocument.Destinations.Count; index++)
            {
                var des = replicationDocument.Destinations[index];
                if (des.CanBeFailover() == false || des.Disabled || des.IgnoredClient ||
                    des.SpecifiedCollections?.Count > 0)
                {
                    continue;
                }
                etags[index] = Database.DocumentReplicationLoader.GetLastReplicatedEtagForDestination(des) ??
                               -1;
                destinations[index] = new DynamicJsonValue
                {
                    [nameof(ServerNode.Url)]      = des.Url,
                    [nameof(ServerNode.ApiKey)]   = des.ApiKey,
                    [nameof(ServerNode.Database)] = des.Database
                };
            }

            // We want to have the client failover to the most up to date destination if it needs to, so we sort
            // them by the last replicated etag

            Array.Sort(etags, destinations);
            for (int i = destinations.Length - 1; i >= 0; i--)
            {
                if (destinations[i] != null)
                {
                    yield return(destinations[i]);
                }
            }
        }
예제 #4
0
        public static void UpdateReplication(InstanceDescription selfInstance, IInstanceEnumerator instanceEnumerator, string databaseName)
        {
            // Setup replication:
            using (var documentStore = new DocumentStore()
            {
                Url = selfInstance.InternalUrl
            })
            {
                log.Info("Ensuring database {0} is replicated from {1} at {2}", databaseName, selfInstance.Id, selfInstance.InternalUrl);

                documentStore.Initialize();

                using (var session = documentStore.OpenSession(databaseName))
                {
                    var documentId = new ReplicationDocument().Id; // Just to stay in sync with changes from RavenDb

                    var replicationDocument = session.Load <ReplicationDocument>(documentId) ?? new ReplicationDocument();

                    replicationDocument.Destinations = EnumerateReplicationDestinations(instanceEnumerator, selfInstance.IsRoleMaster).Select(i => new ReplicationDestination()
                    {
                        Url = string.Format("{0}/databases/{1}", i.InternalUrl, databaseName)
                    }).ToList();
                    session.Store(replicationDocument);
                    session.SaveChanges();
                }
            }
        }
예제 #5
0
        private DocumentCount GetDocumentsLeftCountFromAnotherSourceServer(
            ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> replicationDocument,
            ServerInfo serverInfo)
        {
            var replicationDestination = replicationDocument
                                         .Destinations
                                         .FirstOrDefault(x => FetchTargetServerUrl(x).Equals(serverInfo.SourceUrl, StringComparison.CurrentCultureIgnoreCase) &&
                                                         x.Database.Equals(serverInfo.DatabaseName, StringComparison.CurrentCultureIgnoreCase));

            if (replicationDestination != null)
            {
                return(DocumentsLeftCountFromAnotherSourceServer(serverInfo, replicationDestination));
            }

            if (serverInfo.SourcesToIgnore.Contains(DatabaseId) == false)
            {
                serverInfo.SourcesToIgnore.Add(DatabaseId);
                //couldn't find replication destination for this url,
                //going to try to do it through other destinations

                foreach (var destination in replicationDocument.Destinations)
                {
                    try
                    {
                        return(DocumentsLeftCountFromAnotherSourceServer(serverInfo, destination));
                    }
                    catch (Exception e)
                    {
                        //couldn't reach this destination through this one, will continue
                    }
                }
            }

            throw new InvalidOperationException($"Couldn't find replication destination for url: {serverInfo.SourceUrl} and database: {serverInfo.DatabaseName}");
        }
예제 #6
0
 private List <ReplicationTopologyDestinationNode> HandleDestinations(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> destinations)
 {
     return(destinations
            .Destinations
            .Select(HandleDestination)
            .ToList());
 }
예제 #7
0
        /// <summary>
        /// Refreshes the replication information.
        /// Expert use only.
        /// </summary>
#if SILVERLIGHT || NETFX_CORE
        public Task RefreshReplicationInformation(AsyncServerClient commands)
        {
            lock (this)
            {
                var serverHash = ServerHash.GetServerHash(commands.Url);
                return(commands.DirectGetAsync(new OperationMetadata(commands.Url), RavenReplicationDestinations).ContinueWith((Task <JsonDocument> getTask) =>
                {
                    JsonDocument document;

                    var fromFailoverUrls = false;

                    if (getTask.Status == TaskStatus.RanToCompletion)
                    {
                        document = getTask.Result;
                        failureCounts[commands.Url] = new FailureCounter();                         // we just hit the master, so we can reset its failure count
                    }
                    else
                    {
                        log.ErrorException("Could not contact master for new replication information", getTask.Exception);
                        document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash);

                        if (document == null)
                        {
                            if (FailoverServers != null && FailoverServers.Length > 0)                             // try to use configured failover servers
                            {
                                var failoverServers = new ReplicationDocument {
                                    Destinations = new List <ReplicationDestination>()
                                };

                                foreach (var failover in FailoverServers)
                                {
                                    failoverServers.Destinations.Add(failover);
                                }

                                document = new JsonDocument();
                                document.DataAsJson = RavenJObject.FromObject(failoverServers);

                                fromFailoverUrls = true;
                            }
                        }
                    }

                    if (IsInvalidDestinationsDocument(document))
                    {
                        lastReplicationUpdate = SystemTime.UtcNow;                         // checked and not found
                        return;
                    }

                    if (!fromFailoverUrls)
                    {
                        ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document);
                    }

                    UpdateReplicationInformationFromDocument(document);

                    lastReplicationUpdate = SystemTime.UtcNow;
                }));
            }
        }
예제 #8
0
        public void RefreshReplicationInformation(ServerClient commands)
        {
            lock (this)
            {
                var serverHash = ServerHash.GetServerHash(commands.Url);

                JsonDocument document;
                var          fromFailoverUrls = false;

                try
                {
                    document = commands.DirectGet(new OperationMetadata(commands.Url, commands.PrimaryCredentials), RavenReplicationDestinations);
                    failureCounts[commands.Url] = new FailureCounter();                     // we just hit the master, so we can reset its failure count
                }
                catch (Exception e)
                {
                    log.ErrorException("Could not contact master for new replication information", e);
                    document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash);

                    if (document == null)
                    {
                        if (FailoverServers != null && FailoverServers.Length > 0)                         // try to use configured failover servers
                        {
                            var failoverServers = new ReplicationDocument {
                                Destinations = new List <ReplicationDestination>()
                            };

                            foreach (var failover in FailoverServers)
                            {
                                failoverServers.Destinations.Add(failover);
                            }

                            document            = new JsonDocument();
                            document.DataAsJson = RavenJObject.FromObject(failoverServers);

                            fromFailoverUrls = true;
                        }
                    }
                }


                if (document == null)
                {
                    lastReplicationUpdate = SystemTime.UtcNow;                     // checked and not found
                    return;
                }

                if (!fromFailoverUrls)
                {
                    ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document);
                }

                UpdateReplicationInformationFromDocument(document);

                lastReplicationUpdate = SystemTime.UtcNow;
            }
        }
예제 #9
0
        private void HandleBundleAfterCreation(CreateSettingsModel settingsModel, string databaseName, string encryptionKey)
        {
            var session = ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(databaseName);

            var versioningSection = settingsModel.GetSection <VersioningSettingsSectionModel>();

            if (versioningSection != null)
            {
                StoreVersioningData(versioningSection.VersioningConfigurations, session);
            }

            var replicationSection = settingsModel.GetSection <ReplicationSettingsSectionModel>();

            if (replicationSection != null)
            {
                var replicationDocument = new ReplicationDocument();
                foreach (var replicationDestination in replicationSection.ReplicationDestinations
                         .Where(replicationDestination => !string.IsNullOrWhiteSpace(replicationDestination.Url) || !string.IsNullOrWhiteSpace(replicationDestination.ClientVisibleUrl)))
                {
                    replicationDocument.Destinations.Add(replicationDestination);
                }

                session.Store(replicationDocument);
            }

            var sqlReplicationSettings = settingsModel.GetSection <SqlReplicationSettingsSectionModel>();

            if (sqlReplicationSettings != null)
            {
                sqlReplicationSettings.UpdateIds();

                foreach (var sqlReplicationConfig in sqlReplicationSettings.SqlReplicationConfigs)
                {
                    session.Store(sqlReplicationConfig);
                }
            }


            var authorizationSection = settingsModel.GetSection <AuthorizationSettingsSectionModel>();

            if (authorizationSection != null)
            {
                StoreAuthorizationData(authorizationSection, session);
            }

            session.SaveChangesAsync();

            if (!string.IsNullOrEmpty(encryptionKey))
            {
                new ShowEncryptionMessage(encryptionKey).Show();
            }
        }
예제 #10
0
        private ReplicationInfoStatus[] CheckDestinations(ReplicationDocument replicationDocument)
        {
            var results = new ReplicationInfoStatus[replicationDocument.Destinations.Count];

            Parallel.ForEach(replicationDocument.Destinations, (replicationDestination, state, i) =>
            {
                var url = replicationDestination.Url;

                if (!url.ToLower().Contains("/databases/"))
                {
                    url += "/databases/" + replicationDestination.Database;
                }

                var result = new ReplicationInfoStatus
                {
                    Url    = url,
                    Status = "Valid",
                    Code   = (int)HttpStatusCode.OK
                };

                results[i] = result;

                var ravenConnectionStringOptions = new RavenConnectionStringOptions
                {
                    ApiKey          = replicationDestination.ApiKey,
                    DefaultDatabase = replicationDestination.Database,
                };
                if (string.IsNullOrEmpty(replicationDestination.Username) == false)
                {
                    ravenConnectionStringOptions.Credentials = new NetworkCredential(replicationDestination.Username,
                                                                                     replicationDestination.Password,
                                                                                     replicationDestination.Domain ?? string.Empty);
                }

                var requestFactory = new HttpRavenRequestFactory();
                var request        = requestFactory.Create(url + "/replication/info", HttpMethods.Post, ravenConnectionStringOptions);
                try
                {
                    request.ExecuteRequest();
                }
                catch (WebException e)
                {
                    FillStatus(result, e);
                }
            });

            return(results);
        }
예제 #11
0
 public override void LoadFor(DatabaseDocument database)
 {
     ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(database.Id)
     .LoadAsync <ReplicationDocument>("Raven/Replication/Destinations")
     .ContinueOnSuccessInTheUIThread(document =>
     {
         if (document == null)
         {
             return;
         }
         ReplicationData = document;
         ReplicationDestinations.Clear();
         foreach (var replicationDestination in ReplicationData.Destinations)
         {
             ReplicationDestinations.Add(replicationDestination);
         }
     });
 }
예제 #12
0
        public static void UpdateReplication(InstanceDescription selfInstance, IInstanceEnumerator instanceEnumerator, DocumentDatabase database)
        {
            log.Info("Ensuring default database is replicated from {0} at {1}", selfInstance.Id, selfInstance.InternalUrl);

            var documentId = new ReplicationDocument().Id;

            var replicationDocument = new ReplicationDocument()
            {
                Destinations =
                    EnumerateReplicationDestinations(instanceEnumerator, selfInstance.IsRoleMaster).
                    Select(i => new ReplicationDestination()
                {
                    Url = i.InternalUrl
                }).
                    ToList()
            };

            database.Put(documentId, null, RavenJObject.FromObject(replicationDocument), new RavenJObject(), null);
        }
예제 #13
0
        private static void CreateReplication(IDocumentStore documentStore, string sourceDatabaseName, string destinationUrl, string destinationDatabaseName)
        {
            using (var session = documentStore.OpenSession(sourceDatabaseName))
            {
                var replicationDocument = new ReplicationDocument
                {
                    Destinations = new List <ReplicationDestination>
                    {
                        new ReplicationDestination
                        {
                            Url      = destinationUrl,
                            Database = destinationDatabaseName
                        }
                    }
                };

                session.Store(replicationDocument);
                session.SaveChanges();
            }
        }
 public override void LoadFor(DatabaseDocument _)
 {
     ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(ApplicationModel.Current.Server.Value.SelectedDatabase.Value.Name)
     .LoadAsync <ReplicationDocument>("Raven/Replication/Destinations")
     .ContinueOnSuccessInTheUIThread(document =>
     {
         if (document == null)
         {
             return;
         }
         ReplicationData = document;
         ReplicationDestinations.Clear();
         OriginalReplicationDestinations = new ObservableCollection <ReplicationDestination>();
         foreach (var replicationDestination in ReplicationData.Destinations)
         {
             ReplicationDestinations.Add(replicationDestination);
             OriginalReplicationDestinations.Add(replicationDestination);
         }
     });
 }
예제 #15
0
        private static void CreateReplication(IDocumentStore documentStore, string url)
        {
            using (var session = documentStore.OpenSession("Replication"))
            {
                var replicationDocument = new ReplicationDocument
                {
                    Destinations = new List <ReplicationDestination>
                    {
                        new ReplicationDestination
                        {
                            Url      = url,
                            Database = "Replication"
                        }
                    }
                };

                session.Store(replicationDocument);
                session.SaveChanges();
            }
        }
예제 #16
0
        private static List <ReplicationDestination> SetupReplication(IDocumentStore source, string databaseName, Func <IDocumentStore, bool> shouldSkipIndexReplication, params IDocumentStore[] destinations)
        {
            var replicationDocument = new ReplicationDocument
            {
                Destinations = new List <ReplicationDestination>(destinations.Select(destination =>
                                                                                     new ReplicationDestination
                {
                    Database             = databaseName,
                    Url                  = destination.Url,
                    SkipIndexReplication = shouldSkipIndexReplication(destination)
                }))
            };

            using (var session = source.OpenSession(databaseName))
            {
                session.Store(replicationDocument, Constants.RavenReplicationDestinations);
                session.SaveChanges();
            }

            return(replicationDocument.Destinations);
        }
예제 #17
0
        private void InitializeOutgoingReplications()
        {
            _replicationDocument = GetReplicationDocument();
            if (_replicationDocument?.Destinations == null || //precaution
                _replicationDocument.Destinations.Count == 0)
            {
                if (_log.IsInfoEnabled)
                {
                    _log.Info("Tried to initialize outgoing replications, but there is no replication document or destinations are empty. Nothing to do...");
                }
                return;
            }

            if (_log.IsInfoEnabled)
            {
                _log.Info($"Initializing {_replicationDocument.Destinations.Count:#,#} outgoing replications..");
            }

            foreach (var destination in _replicationDocument.Destinations)
            {
                if (destination.Disabled)
                {
                    continue;
                }

                AddAndStartOutgoingReplication(destination);
                if (_log.IsInfoEnabled)
                {
                    _log.Info($"Initialized outgoing replication for [{destination.Database}/{destination.Url}]");
                }
            }

            if (_log.IsInfoEnabled)
            {
                _log.Info("Finished initialization of outgoing replications..");
            }
        }
예제 #18
0
        public override void Execute(object parameter)
        {
            var databaseName = ApplicationModel.Current.Server.Value.SelectedDatabase.Value.Name;

            var periodicBackup = settingsModel.GetSection <PeriodicBackupSettingsSectionModel>();

            if (periodicBackup != null)
            {
                SavePeriodicBackup(databaseName, periodicBackup);
            }


            if (databaseName == Constants.SystemDatabase)
            {
                SaveApiKeys();
                if (SaveWindowsAuth())
                {
                    ApplicationModel.Current.Notifications.Add(new Notification("Api keys and Windows Authentication saved"));
                }
                else
                {
                    ApplicationModel.Current.Notifications.Add(new Notification("Only Api keys where saved, something when wrong with Windows Authentication", NotificationLevel.Error));
                }
                return;
            }
            var session = ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(databaseName);

            var quotaSettings = settingsModel.GetSection <QuotaSettingsSectionModel>();

            if (quotaSettings != null)
            {
                settingsModel.DatabaseDocument.Settings[Constants.SizeHardLimitInKB] =
                    (quotaSettings.MaxSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.SizeSoftLimitInKB] =
                    (quotaSettings.WarnSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsHardLimit] =
                    (quotaSettings.MaxDocs).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsSoftLimit] =
                    (quotaSettings.WarnDocs).ToString(CultureInfo.InvariantCulture);
                if (settingsModel.DatabaseDocument.Id == null)
                {
                    settingsModel.DatabaseDocument.Id = databaseName;
                }
                DatabaseCommands.CreateDatabaseAsync(settingsModel.DatabaseDocument);
            }

            var replicationSettings = settingsModel.GetSection <ReplicationSettingsSectionModel>();

            if (replicationSettings != null)
            {
                session.LoadAsync <ReplicationDocument>("Raven/Replication/Destinations")
                .ContinueOnSuccessInTheUIThread(document =>
                {
                    if (document == null)
                    {
                        document = new ReplicationDocument();
                    }

                    document.Destinations.Clear();
                    foreach (var destination in replicationSettings.ReplicationDestinations
                             .Where(destination => !string.IsNullOrWhiteSpace(destination.Url)))
                    {
                        document.Destinations.Add(destination);
                    }

                    session.Store(document);
                    session.SaveChangesAsync().Catch();
                })
                .Catch();
            }

            var sqlReplicationSettings = settingsModel.GetSection <SqlReplicationSettingsSectionModel>();

            if (sqlReplicationSettings != null)
            {
                if (sqlReplicationSettings.SqlReplicationConfigs.Any(config => config.Name == "Temp_Name") == false && sqlReplicationSettings.SqlReplicationConfigs.Any(config => string.IsNullOrWhiteSpace(config.Name)) == false)
                {
                    var problemWithTable = false;
                    foreach (var sqlReplicationConfigModel in sqlReplicationSettings.SqlReplicationConfigs)
                    {
                        var hashset = new HashSet <string>();
                        foreach (var sqlReplicationTable in sqlReplicationConfigModel.SqlReplicationTables)
                        {
                            var exists = !hashset.Add(sqlReplicationTable.TableName);
                            if (string.IsNullOrWhiteSpace(sqlReplicationTable.DocumentKeyColumn) || string.IsNullOrWhiteSpace(sqlReplicationTable.TableName) || exists)
                            {
                                problemWithTable = true;
                                break;
                            }
                        }
                        if (problemWithTable)
                        {
                            break;
                        }
                    }

                    if (problemWithTable)
                    {
                        ApplicationModel.Current.AddNotification(new Notification("Sql Replicaiton settings were not saved, all tables must distinct names and have document keys", NotificationLevel.Error));
                    }
                    else
                    {
                        session.Advanced.LoadStartingWithAsync <SqlReplicationConfig>("Raven/SqlReplication/Configuration/")
                        .ContinueOnSuccessInTheUIThread(documents =>
                        {
                            sqlReplicationSettings.UpdateIds();
                            if (documents != null)
                            {
                                foreach (var sqlReplicationConfig in documents)
                                {
                                    if (sqlReplicationSettings.SqlReplicationConfigs.All(config => config.Id != sqlReplicationConfig.Id))
                                    {
                                        session.Delete(sqlReplicationConfig);
                                    }
                                }
                            }

                            foreach (var sqlReplicationConfig in sqlReplicationSettings.SqlReplicationConfigs)
                            {
                                sqlReplicationConfig.Id = "Raven/SqlReplication/Configuration/" + sqlReplicationConfig.Name;
                                session.Store(sqlReplicationConfig.ToSqlReplicationConfig());
                            }

                            session.SaveChangesAsync().Catch();
                        })
                        .Catch();
                    }
                }
                else
                {
                    ApplicationModel.Current.AddNotification(new Notification("Sql Replicaiton settings not saved, all settings must have a name and it must be different from \"Temp_Name\"", NotificationLevel.Error));
                }
            }

            var versioningSettings = settingsModel.GetSection <VersioningSettingsSectionModel>();

            if (versioningSettings != null)
            {
                var versionsToDelete = versioningSettings.OriginalVersioningConfigurations
                                       .Where(
                    originalVersioningConfiguration =>
                    versioningSettings.VersioningConfigurations.Contains(originalVersioningConfiguration) == false)
                                       .ToList();
                foreach (var versioningConfiguration in versionsToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(versioningConfiguration.Id);
                }

                foreach (var versioningConfiguration in versioningSettings.VersioningConfigurations)
                {
                    if (versioningConfiguration.Id.StartsWith("Raven/Versioning/", StringComparison.InvariantCultureIgnoreCase) == false)
                    {
                        versioningConfiguration.Id = "Raven/Versioning/" + versioningConfiguration.Id;
                    }
                    session.Store(versioningConfiguration);
                }
            }

            var authorizationSettings = settingsModel.GetSection <AuthorizationSettingsSectionModel>();

            if (authorizationSettings != null)
            {
                var usersToDelete = authorizationSettings.OriginalAuthorizationUsers
                                    .Where(authorizationUser => authorizationSettings.AuthorizationUsers.Contains(authorizationUser) == false)
                                    .ToList();
                foreach (var authorizationUser in usersToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(authorizationUser.Id);
                }

                var rolesToDelete = authorizationSettings.OriginalAuthorizationRoles
                                    .Where(authorizationRole => authorizationSettings.AuthorizationRoles.Contains(authorizationRole) == false)
                                    .ToList();
                foreach (var authorizationRole in rolesToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(authorizationRole.Id);
                }

                foreach (var authorizationRole in authorizationSettings.AuthorizationRoles)
                {
                    session.Store(authorizationRole);
                }

                foreach (var authorizationUser in authorizationSettings.AuthorizationUsers)
                {
                    session.Store(authorizationUser);
                }
            }

            session.SaveChangesAsync()
            .ContinueOnSuccessInTheUIThread(() => ApplicationModel.Current.AddNotification(new Notification("Updated Settings for: " + databaseName)));
        }
예제 #19
0
        protected override async Task ExecuteAsync(object parameter)
        {
            if (ApplicationModel.Current == null || ApplicationModel.Current.Server.Value == null || ApplicationModel.Current.Server.Value.SelectedDatabase.Value == null)
            {
                return;
            }
            if (settingsModel == null)
            {
                return;
            }

            var databaseName = ApplicationModel.Current.Server.Value.SelectedDatabase.Value.Name;
            var session      = ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(databaseName);

            if (databaseName == Constants.SystemDatabase)
            {
                var systemSession = ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession();
                await SaveApiKeys(systemSession);

                var savedWinAuth = SaveWindowsAuth(systemSession);
                if (needToSaveChanges)
                {
                    await systemSession.SaveChangesAsync();
                }
                ApplicationModel.Current.Notifications.Add(savedWinAuth
                                        ? new Notification("Api keys and Windows Authentication saved")
                                        : new Notification("Only Api keys where saved, something when wrong with Windows Authentication", NotificationLevel.Error));
                return;
            }

            var periodicBackup = settingsModel.GetSection <PeriodicBackupSettingsSectionModel>();

            if (periodicBackup != null)
            {
                await SavePeriodicBackup(periodicBackup, session);
            }

            var quotaSettings = settingsModel.GetSection <QuotaSettingsSectionModel>();

            if (quotaSettings != null)
            {
                settingsModel.DatabaseDocument.Settings[Constants.SizeHardLimitInKB] =
                    (quotaSettings.MaxSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.SizeSoftLimitInKB] =
                    (quotaSettings.WarnSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsHardLimit] =
                    (quotaSettings.MaxDocs).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsSoftLimit] =
                    (quotaSettings.WarnDocs).ToString(CultureInfo.InvariantCulture);

                if (settingsModel.DatabaseDocument.Id == null)
                {
                    settingsModel.DatabaseDocument.Id = databaseName;
                }
                await DatabaseCommands.CreateDatabaseAsync(settingsModel.DatabaseDocument);
            }

            var replicationSettings = settingsModel.GetSection <ReplicationSettingsSectionModel>();

            if (replicationSettings != null)
            {
                ReplicationDocument document;
                try
                {
                    document = await session.LoadAsync <ReplicationDocument>("Raven/Replication/Destinations") ?? new ReplicationDocument();
                }
                catch
                {
                    document = new ReplicationDocument();
                }

                document.Destinations.Clear();
                foreach (var destination in replicationSettings.ReplicationDestinations.Where(destination => !string.IsNullOrWhiteSpace(destination.Url)))
                {
                    document.Destinations.Add(destination);
                }
                try
                {
                    await CheckDestinations(document);

                    session.Store(document);
                    needToSaveChanges = true;
                }
                catch (Exception e)
                {
                    ApplicationModel.Current.AddErrorNotification(e);
                }
            }

            var scriptedSettings = settingsModel.GetSection <ScriptedIndexSettingsSectionModel>();

            if (scriptedSettings != null)
            {
                scriptedSettings.StoreChanges();
                foreach (var scriptedIndexResults in scriptedSettings.ScriptedIndexes)
                {
                    if (scriptedIndexResults.Value != null)
                    {
                        scriptedIndexResults.Value.Id = ScriptedIndexResults.IdPrefix + scriptedIndexResults.Key;
                        session.Store(scriptedIndexResults.Value, scriptedIndexResults.Value.Id);
                    }
                }

                foreach (var indexName in scriptedSettings.DeletedIndexes)
                {
                    var id = ScriptedIndexResults.IdPrefix + indexName;

                    await DatabaseCommands.DeleteDocumentAsync(id);
                }

                needToSaveChanges = true;
            }

            var sqlReplicationSettings = settingsModel.GetSection <SqlReplicationSettingsSectionModel>();

            if (sqlReplicationSettings != null)
            {
                if (sqlReplicationSettings.SqlReplicationConfigs.Any(config => string.IsNullOrWhiteSpace(config.Name)) == false)
                {
                    var problemWithTable = false;
                    foreach (var sqlReplicationConfigModel in sqlReplicationSettings.SqlReplicationConfigs)
                    {
                        var hashset = new HashSet <string>();
                        foreach (var sqlReplicationTable in sqlReplicationConfigModel.SqlReplicationTables)
                        {
                            var exists = !hashset.Add(sqlReplicationTable.TableName);
                            if (string.IsNullOrWhiteSpace(sqlReplicationTable.DocumentKeyColumn) ||
                                string.IsNullOrWhiteSpace(sqlReplicationTable.TableName) || exists)
                            {
                                problemWithTable = true;
                                break;
                            }
                        }
                        if (problemWithTable)
                        {
                            break;
                        }
                    }

                    if (problemWithTable)
                    {
                        ApplicationModel.Current.AddNotification(
                            new Notification(
                                "Sql Replication settings were not saved, all tables must distinct names and have document keys",
                                NotificationLevel.Error));
                    }
                    else
                    {
                        var hasChanges = new List <string>();
                        var documents  = await session.Advanced.LoadStartingWithAsync <SqlReplicationConfig>("Raven/SqlReplication/Configuration/");

                        sqlReplicationSettings.UpdateIds();
                        if (documents != null)
                        {
                            hasChanges = sqlReplicationSettings.SqlReplicationConfigs.Where(config => HasChanges(config,
                                                                                                                 documents.FirstOrDefault(replicationConfig => replicationConfig.Name == config.Name)))
                                         .Select(config => config.Name).ToList();

                            foreach (var sqlReplicationConfig in documents)
                            {
                                if (sqlReplicationSettings.SqlReplicationConfigs.All(config => config.Id != sqlReplicationConfig.Id))
                                {
                                    session.Delete(sqlReplicationConfig);
                                }
                            }
                        }

                        if (hasChanges != null && hasChanges.Count > 0)
                        {
                            var resetReplication = new ResetReplication(hasChanges);
                            await resetReplication.ShowAsync();

                            if (resetReplication.Selected.Count == 0)
                            {
                                return;
                            }
                            const string ravenSqlreplicationStatus = "Raven/SqlReplication/Status";

                            var status = await session.LoadAsync <SqlReplicationStatus>(ravenSqlreplicationStatus);

                            foreach (var name in resetReplication.Selected)
                            {
                                var lastReplicatedEtag = status.LastReplicatedEtags.FirstOrDefault(etag => etag.Name == name);
                                if (lastReplicatedEtag != null)
                                {
                                    lastReplicatedEtag.LastDocEtag = Etag.Empty;
                                }
                            }

                            session.Store(status);
                        }

                        foreach (var sqlReplicationConfig in sqlReplicationSettings.SqlReplicationConfigs)
                        {
                            sqlReplicationConfig.Id = "Raven/SqlReplication/Configuration/" + sqlReplicationConfig.Name;
                            session.Store(sqlReplicationConfig.ToSqlReplicationConfig());
                        }
                    }
                    needToSaveChanges = true;
                }
                else
                {
                    ApplicationModel.Current.AddNotification(
                        new Notification("Sql Replication settings not saved, all replications must have a name", NotificationLevel.Error));
                }
            }

            var versioningSettings = settingsModel.GetSection <VersioningSettingsSectionModel>();

            if (versioningSettings != null)
            {
                var versionsToDelete = versioningSettings.OriginalVersioningConfigurations
                                       .Where(originalVersioningConfiguration =>
                                              versioningSettings.VersioningConfigurations.Contains(originalVersioningConfiguration) == false)
                                       .ToList();
                foreach (var versioningConfiguration in versionsToDelete)
                {
                    await DatabaseCommands.DeleteDocumentAsync(versioningConfiguration.Id);
                }

                foreach (var versioningConfiguration in versioningSettings.VersioningConfigurations)
                {
                    if (versioningConfiguration.Id.StartsWith("Raven/Versioning/", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        versioningConfiguration.Id = "Raven/Versioning/" + versioningConfiguration.Id;
                    }
                    session.Store(versioningConfiguration);
                }

                if (versioningSettings.DatabaseDocument != null)
                {
                    await DatabaseCommands.CreateDatabaseAsync(versioningSettings.DatabaseDocument);
                }

                needToSaveChanges = true;
            }

            var authorizationSettings = settingsModel.GetSection <AuthorizationSettingsSectionModel>();

            if (authorizationSettings != null)
            {
                var usersToDelete = authorizationSettings.OriginalAuthorizationUsers
                                    .Where(authorizationUser => authorizationSettings.AuthorizationUsers.Contains(authorizationUser) == false)
                                    .ToList();
                foreach (var authorizationUser in usersToDelete)
                {
                    await DatabaseCommands.DeleteDocumentAsync(authorizationUser.Id);
                }

                var rolesToDelete = authorizationSettings.OriginalAuthorizationRoles
                                    .Where(authorizationRole => authorizationSettings.AuthorizationRoles.Contains(authorizationRole) == false)
                                    .ToList();
                foreach (var authorizationRole in rolesToDelete)
                {
                    await DatabaseCommands.DeleteDocumentAsync(authorizationRole.Id);
                }

                foreach (var authorizationRole in authorizationSettings.AuthorizationRoles)
                {
                    session.Store(authorizationRole);
                }

                foreach (var authorizationUser in authorizationSettings.AuthorizationUsers)
                {
                    session.Store(authorizationUser);
                }

                needToSaveChanges = true;
            }

            if (needToSaveChanges)
            {
                await session.SaveChangesAsync();
            }
            ApplicationModel.Current.AddNotification(new Notification("Updated Settings for: " + databaseName));
        }
예제 #20
0
        protected override ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> ApplyGlobalDocumentToLocal(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> global, ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> local, DocumentDatabase systemDatabase, DocumentDatabase localDatabase)
        {
            local.ClientConfiguration = local.ClientConfiguration ?? global.ClientConfiguration;

            foreach (var localDestination in local.Destinations)
            {
                localDestination.HasLocal = true;
            }

            foreach (var globalDestination in global.Destinations)
            {
                globalDestination.HasGlobal = true;

                var localDestination = local.Destinations.FirstOrDefault(x => string.Equals(x.Url, globalDestination.Url, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Database, localDatabase.Name, StringComparison.OrdinalIgnoreCase));
                if (localDestination != null)
                {
                    localDestination.HasGlobal = true;
                    continue;
                }

                globalDestination.Database = localDatabase.Name;
                local.Destinations.Add(globalDestination);
            }

            return(local);
        }
예제 #21
0
        public override void Execute(object parameter)
        {
            var databaseName = ApplicationModel.Current.Server.Value.SelectedDatabase.Value.Name;

            var periodicBackup = settingsModel.GetSection <PeriodicBackupSettingsSectionModel>();

            if (periodicBackup != null)
            {
                SavePeriodicBackup(databaseName, periodicBackup);
            }


            if (databaseName == Constants.SystemDatabase)
            {
                SaveApiKeys();
                if (SaveWindowsAuth())
                {
                    ApplicationModel.Current.Notifications.Add(new Notification("Api keys and Windows Authentication saved"));
                }
                else
                {
                    ApplicationModel.Current.Notifications.Add(new Notification("Only Api keys where saved, something when wrong with Windows Authentication", NotificationLevel.Error));
                }
                return;
            }
            var session = ApplicationModel.Current.Server.Value.DocumentStore.OpenAsyncSession(databaseName);

            var quotaSettings = settingsModel.GetSection <QuotaSettingsSectionModel>();

            if (quotaSettings != null)
            {
                settingsModel.DatabaseDocument.Settings[Constants.SizeHardLimitInKB] =
                    (quotaSettings.MaxSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.SizeSoftLimitInKB] =
                    (quotaSettings.WarnSize * 1024).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsHardLimit] =
                    (quotaSettings.MaxDocs).ToString(CultureInfo.InvariantCulture);
                settingsModel.DatabaseDocument.Settings[Constants.DocsSoftLimit] =
                    (quotaSettings.WarnDocs).ToString(CultureInfo.InvariantCulture);
                if (settingsModel.DatabaseDocument.Id == null)
                {
                    settingsModel.DatabaseDocument.Id = databaseName;
                }
                DatabaseCommands.CreateDatabaseAsync(settingsModel.DatabaseDocument);
            }

            var replicationSettings = settingsModel.GetSection <ReplicationSettingsSectionModel>();

            if (replicationSettings != null)
            {
                session.LoadAsync <ReplicationDocument>("Raven/Replication/Destinations")
                .ContinueOnSuccessInTheUIThread(document =>
                {
                    if (document == null)
                    {
                        document = new ReplicationDocument();
                    }

                    document.Destinations.Clear();
                    foreach (var destination in replicationSettings.ReplicationDestinations
                             .Where(destination => !string.IsNullOrWhiteSpace(destination.Url)))
                    {
                        document.Destinations.Add(destination);
                    }

                    session.Store(document);
                    session.SaveChangesAsync().Catch();
                })
                .Catch();
            }

            var versioningSettings = settingsModel.GetSection <VersioningSettingsSectionModel>();

            if (versioningSettings != null)
            {
                var versionsToDelete = versioningSettings.OriginalVersioningConfigurations
                                       .Where(
                    originalVersioningConfiguration =>
                    versioningSettings.VersioningConfigurations.Contains(originalVersioningConfiguration) == false)
                                       .ToList();
                foreach (var versioningConfiguration in versionsToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(versioningConfiguration.Id);
                }

                foreach (var versioningConfiguration in versioningSettings.VersioningConfigurations)
                {
                    if (versioningConfiguration.Id.StartsWith("Raven/Versioning/", StringComparison.InvariantCultureIgnoreCase) == false)
                    {
                        versioningConfiguration.Id = "Raven/Versioning/" + versioningConfiguration.Id;
                    }
                    session.Store(versioningConfiguration);
                }
            }

            var authorizationSettings = settingsModel.GetSection <AuthorizationSettingsSectionModel>();

            if (authorizationSettings != null)
            {
                var usersToDelete = authorizationSettings.OriginalAuthorizationUsers
                                    .Where(authorizationUser => authorizationSettings.AuthorizationUsers.Contains(authorizationUser) == false)
                                    .ToList();
                foreach (var authorizationUser in usersToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(authorizationUser.Id);
                }

                var rolesToDelete = authorizationSettings.OriginalAuthorizationRoles
                                    .Where(authorizationRole => authorizationSettings.AuthorizationRoles.Contains(authorizationRole) == false)
                                    .ToList();
                foreach (var authorizationRole in rolesToDelete)
                {
                    DatabaseCommands.DeleteDocumentAsync(authorizationRole.Id);
                }

                foreach (var authorizationRole in authorizationSettings.AuthorizationRoles)
                {
                    session.Store(authorizationRole);
                }

                foreach (var authorizationUser in authorizationSettings.AuthorizationUsers)
                {
                    session.Store(authorizationUser);
                }
            }

            session.SaveChangesAsync()
            .ContinueOnSuccessInTheUIThread(() => ApplicationModel.Current.AddNotification(new Notification("Updated Settings for: " + databaseName)));
        }
예제 #22
0
 protected override ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> PostProcessLocalOnly(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> local)
 {
     foreach (var destination in local.Destinations)
     {
         destination.HasLocal = true;
     }
     return(local);
 }
예제 #23
0
        protected override ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> ConvertGlobalDocumentToLocal(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> global, DocumentDatabase systemDatabase, DocumentDatabase localDatabase)
        {
            global.Id     = Constants.RavenReplicationDestinations;
            global.Source = localDatabase.TransactionalStorage.Id.ToString();

            foreach (var destination in global.Destinations)
            {
                destination.HasGlobal = true;
                destination.HasLocal  = false;
                destination.Database  = localDatabase.Name;
            }

            return(global);
        }