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)); } }
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; } }
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]); } } }
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(); } } }
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}"); }
private List <ReplicationTopologyDestinationNode> HandleDestinations(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> destinations) { return(destinations .Destinations .Select(HandleDestination) .ToList()); }
/// <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; })); } }
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; } }
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(); } }
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); }
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); } }); }
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); }
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); } }); }
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(); } }
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); }
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.."); } }
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))); }
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)); }
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); }
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))); }
protected override ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> PostProcessLocalOnly(ReplicationDocument <ReplicationDestination.ReplicationDestinationWithConfigurationOrigin> local) { foreach (var destination in local.Destinations) { destination.HasLocal = true; } return(local); }
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); }