public async Task RavenDB_14435() { using (var src = GetDocumentStore()) using (var dst = GetDocumentStore()) { var database = await GetDocumentDatabaseInstanceFor(src); using (var session = src.OpenSession()) { session.Store(new User(), "foo/bar"); session.SaveChanges(); } using (var controller = new ReplicationController(database)) { var databaseWatcher1 = new ExternalReplication(dst.Database, $"ConnectionString-{src.Identifier}_1"); await AddWatcherToReplicationTopology(src, databaseWatcher1, src.Urls); controller.ReplicateOnce(); Assert.NotNull(WaitForDocumentToReplicate <User>(dst, "foo/bar", 10_000)); await Task.Delay(ReplicationLoader.MaxInactiveTime.Add(TimeSpan.FromSeconds(10))); var databaseWatcher2 = new ExternalReplication(dst.Database, $"ConnectionString-{src.Identifier}_2"); await AddWatcherToReplicationTopology(src, databaseWatcher2, src.Urls); await Task.Delay(TimeSpan.FromSeconds(5)); } await EnsureReplicatingAsync(src, dst); } }
public async Task ReplicateToWatcherWithAuth() { var serverCertPath = SetupServerAuthentication(); var dbName = GetDatabaseName(); var adminCert = AskServerForClientCertificate(serverCertPath, new Dictionary <string, DatabaseAccess>(), SecurityClearance.ClusterAdmin); var opCert = AskServerForClientCertificate(serverCertPath, new Dictionary <string, DatabaseAccess>(), SecurityClearance.Operator); using (var store1 = GetDocumentStore(new Options { AdminCertificate = adminCert, ClientCertificate = opCert, ModifyDatabaseName = s => dbName })) using (var store2 = GetDocumentStore(new Options { AdminCertificate = adminCert, ClientCertificate = opCert, ModifyDatabaseName = s => dbName, CreateDatabase = false })) { var watcher2 = new ExternalReplication(store2.Database, "ConnectionString"); await AddWatcherToReplicationTopology(store1, watcher2); using (var session = store1.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "Karmel" }, "users/1"); await session.SaveChangesAsync(); } Assert.True(WaitForDocument <User>(store2, "users/1", (u) => u.Name == "Karmel")); } }
public async Task DisableExternalReplication() { using (var store1 = GetDocumentStore()) using (var store2 = GetDocumentStore()) { var externalList = await SetupReplicationAsync(store1, store2); using (var session = store1.OpenSession()) { session.Store(new User { Name = "John Dow", Age = 30 }, "users/1"); session.SaveChanges(); } var replicated1 = WaitForDocumentToReplicate <User>(store2, "users/1", 10000); Assert.NotNull(replicated1); Assert.Equal("John Dow", replicated1.Name); Assert.Equal(30, replicated1.Age); var db1 = await GetDocumentDatabaseInstanceFor(store1); var db2 = await GetDocumentDatabaseInstanceFor(store2); var replicationConnection = db1.ReplicationLoader.OutgoingHandlers.First(); var external = new ExternalReplication(store1.Database, $"ConnectionString-{store2.Identifier}") { TaskId = externalList.First().TaskId, Disabled = true }; var res = await store1.Maintenance.SendAsync(new UpdateExternalReplicationOperation(external)); Assert.Equal(externalList.First().TaskId, res.TaskId); //make sure the command is processed await db1.ServerStore.Cluster.WaitForIndexNotification(res.RaftCommandIndex); await db2.ServerStore.Cluster.WaitForIndexNotification(res.RaftCommandIndex); var connectionDropped = await WaitForValueAsync(() => replicationConnection.IsConnectionDisposed, true); Assert.True(connectionDropped); using (var session = store1.OpenSession()) { session.Store(new User { Name = "John Dow", Age = 30 }, "users/2"); session.SaveChanges(); } var replicated2 = WaitForDocumentToReplicate <User>(store2, "users/2", 10000); Assert.Null(replicated2); } }
public async Task CannotReplicateTimeSeriesToV42() { var version = "4.2.101"; // todo:Add compatible version of v4.2 when released var getOldStore = GetDocumentStoreAsync(version); await Task.WhenAll(getOldStore); using var oldStore = await getOldStore; using var store = GetDocumentStore(); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "Egor" }, "user/322"); session.TimeSeriesFor("user/322", "a").Append(DateTime.UtcNow, 1); await session.SaveChangesAsync(); } var externalTask = new ExternalReplication(oldStore.Database.ToLowerInvariant(), "MyConnectionString") { Name = "MyExternalReplication", Url = oldStore.Urls.First() }; await SetupReplication(store, externalTask); var replicationLoader = (await GetDocumentDatabaseInstanceFor(store)).ReplicationLoader; Assert.NotEmpty(replicationLoader.OutgoingFailureInfo); Assert.True(WaitForValue(() => replicationLoader.OutgoingFailureInfo.Any(ofi => ofi.Value.RetriesCount > 2), true)); Assert.True(replicationLoader.OutgoingFailureInfo.Any(ofi => ofi.Value.Errors.Any(x => x.GetType() == typeof(LegacyReplicationViolationException)))); Assert.True(replicationLoader.OutgoingFailureInfo.Any(ofi => ofi.Value.Errors.Select(x => x.Message).Any(x => x.Contains("TimeSeries")))); }
public override string UpdateDatabaseRecord(DatabaseRecord record, long etag) { if (Watcher == null) { return(null); } if (Watcher.TaskId == 0) { Watcher.TaskId = etag; } else { //modified watcher, remove the old one ExternalReplication.RemoveExternalReplication(record.ExternalReplications, Watcher.TaskId); } //this covers the case of a new watcher and edit of an old watcher if (string.IsNullOrEmpty(Watcher.Name)) { Watcher.Name = record.EnsureUniqueTaskName(Watcher.GetDefaultTaskName()); } EnsureTaskNameIsNotUsed(record, Watcher.Name); record.ExternalReplications.Add(Watcher); return(null); }
public override string UpdateDatabaseRecord(DatabaseRecord record, long etag) { Debug.Assert(TaskId != 0); switch (TaskType) { case OngoingTaskType.Replication: ExternalReplication.RemoveWatcher(ref record.ExternalReplication, TaskId); break; case OngoingTaskType.Backup: record.DeletePeriodicBackupConfiguration(TaskId); return(TaskId.ToString()); case OngoingTaskType.SqlEtl: var sqlEtl = record.SqlEtls?.Find(x => x.TaskId == TaskId); if (sqlEtl != null) { record.SqlEtls.Remove(sqlEtl); } break; case OngoingTaskType.RavenEtl: var ravenEtl = record.RavenEtls?.Find(x => x.TaskId == TaskId); if (ravenEtl != null) { record.RavenEtls.Remove(ravenEtl); } break; } return(null); }
public async Task CanReplicateToOldServerWithLowerReplicationProtocolVersion(string version) { // https://issues.hibernatingrhinos.com/issue/RavenDB-17346 using var oldStore = await GetDocumentStoreAsync(version); using var store = GetDocumentStore(); { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "Egor" }, "users/1"); await session.SaveChangesAsync(); } } var externalTask = new ExternalReplication(oldStore.Database.ToLowerInvariant(), "MyConnectionString") { Name = "MyExternalReplication", Url = oldStore.Urls.First() }; await SetupReplication(store, externalTask); Assert.True(WaitForDocument <User>(oldStore, "users/1", u => u.Name == "Egor")); }
private void HandleExternalReplication(DatabaseRecord newRecord, ref List <OutgoingReplicationHandler> instancesToDispose) { var changes = ExternalReplication.FindChanges(_externalDestinations, newRecord.ExternalReplication); DropOutgoingConnections(changes.RemovedDestiantions, ref instancesToDispose); var newDestinations = changes.AddedDestinations.Where(o => newRecord.Topology.WhoseTaskIsIt(o, _server.Engine.CurrentState) == _server.NodeTag).ToList(); foreach (var externalReplication in newDestinations.ToList()) { if (newRecord.RavenConnectionStrings.TryGetValue(externalReplication.ConnectionStringName, out var connectionString) == false) { if (_log.IsInfoEnabled) { _log.Info($"Could not find connection string with name {externalReplication.ConnectionStringName} " + $"for the external replication task '{externalReplication.Name}' to '{externalReplication.Database}'."); } newDestinations.Remove(externalReplication); continue; } externalReplication.ConnectionString = connectionString; } StartOutgoingConnections(newDestinations, external: true); _externalDestinations.RemoveAll(changes.RemovedDestiantions.Contains); _externalDestinations.AddRange(newDestinations); }
public async Task DelayedExternalReplication() { using (var store1 = GetDocumentStore()) using (var store2 = GetDocumentStore()) { var delay = TimeSpan.FromSeconds(5); var externalTask = new ExternalReplication(store2.Database, "DelayedExternalReplication") { DelayReplicationFor = delay }; await AddWatcherToReplicationTopology(store1, externalTask); DateTime date; using (var s1 = store1.OpenSession()) { s1.Store(new User(), "foo/bar"); date = DateTime.UtcNow; s1.SaveChanges(); } Assert.True(WaitForDocument(store2, "foo/bar")); var elapsed = DateTime.UtcNow - date; Assert.True(elapsed >= delay, $" only {elapsed}/{delay} ticks elapsed"); } }
protected static async Task SetupReplicationWithCustomDestinations(DocumentStore fromStore, params ReplicationNode[] toNodes) { foreach (var node in toNodes) { var databaseWatcher = new ExternalReplication(node.Database, "connection"); await AddWatcherToReplicationTopology(fromStore, databaseWatcher, new[] { node.Url }); } }
protected static async Task <ModifyOngoingTaskResult> AddWatcherToReplicationTopology( DocumentStore store, ExternalReplication watcher) { var op = new UpdateExternalReplicationOperation(store.Database, watcher); return(await store.Admin.Server.SendAsync(op)); }
public async Task ExternalReplicationToNonExistingNode() { using (var store1 = GetDocumentStore()) { var externalTask = new ExternalReplication(store1.Database + "test", $"Connection to {store1.Database} test"); await AddWatcherToReplicationTopology(store1, externalTask, new[] { "http://1.2.3.4:8080" }); } }
public async Task ExternalReplicationToNonExistingDatabase() { using (var store1 = GetDocumentStore()) using (var store2 = GetDocumentStore()) { var externalTask = new ExternalReplication(store2.Database + "test", $"Connection to {store2.Database} test"); await AddWatcherToReplicationTopology(store1, externalTask); } }
public async Task CanExcludeDatabase() { using (var store = GetDocumentStore()) { var serverWideExternalReplication = new ServerWideExternalReplication { Disabled = true, TopologyDiscoveryUrls = new[] { store.Urls.First() } }; var result = await store.Maintenance.Server.SendAsync(new PutServerWideExternalReplicationOperation(serverWideExternalReplication)); serverWideExternalReplication.Name = result.Name; var record = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store.Database)); Assert.Equal(1, record.ExternalReplications.Count); Assert.Equal(1, record.RavenConnectionStrings.Count); var dbName = $"db/{Guid.NewGuid()}"; var csName = $"cs/{Guid.NewGuid()}"; var connectionString = new RavenConnectionString { Name = csName, Database = dbName, TopologyDiscoveryUrls = new[] { "http://127.0.0.1:12345" } }; var putConnectionStringResult = await store.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(connectionString)); Assert.NotNull(putConnectionStringResult.RaftCommandIndex); var externalReplication = new ExternalReplication(dbName, csName) { Name = "Regular Task", Disabled = true }; await store.Maintenance.SendAsync(new UpdateExternalReplicationOperation(externalReplication)); record = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store.Database)); Assert.Equal(2, record.ExternalReplications.Count); Assert.Equal(2, record.RavenConnectionStrings.Count); serverWideExternalReplication.ExcludedDatabases = new[] { store.Database }; await store.Maintenance.Server.SendAsync(new PutServerWideExternalReplicationOperation(serverWideExternalReplication)); record = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store.Database)); Assert.Equal(1, record.ExternalReplications.Count); Assert.Equal(1, record.RavenConnectionStrings.Count); Assert.Equal(externalReplication.Name, record.ExternalReplications.First().Name); } }
private void HandleExternalReplication(DatabaseRecord newRecord, ref List <OutgoingReplicationHandler> instancesToDispose) { var changes = ExternalReplication.FindChanges(_externalDestinations, newRecord.ExternalReplication); DropOutgoingConnections(changes.RemovedDestiantions, ref instancesToDispose); var newDestinations = changes.AddedDestinations.Where(o => newRecord.Topology.WhoseTaskIsIt(o, false) == _server.NodeTag).ToList(); StartOutgoingConnections(newDestinations, external: true); _externalDestinations.RemoveAll(changes.RemovedDestiantions.Contains); _externalDestinations.AddRange(newDestinations); }
public async Task CanChangeConnectionString() { using (var store1 = GetDocumentStore()) using (var store2 = GetDocumentStore()) { var externalReplication = new ExternalReplication { ConnectionStringName = "ExReplication" }; await store1.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(new RavenConnectionString { Name = externalReplication.ConnectionStringName, Database = "NotExist", TopologyDiscoveryUrls = store1.Urls })); await store1.Maintenance.SendAsync(new UpdateExternalReplicationOperation(externalReplication)); using (var s1 = store1.OpenSession()) { s1.Store(new User(), "foo/bar"); s1.SaveChanges(); } Assert.False(WaitForDocument(store2, "foo/bar", timeout: 5_000)); await store1.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(new RavenConnectionString { Name = externalReplication.ConnectionStringName, Database = store2.Database, TopologyDiscoveryUrls = store1.Urls })); Assert.True(WaitForDocument(store2, "foo/bar", timeout: 5_000)); await store1.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(new RavenConnectionString { Name = externalReplication.ConnectionStringName, Database = "NotExist", TopologyDiscoveryUrls = store1.Urls })); using (var s1 = store1.OpenSession()) { s1.Store(new User(), "foo/bar/2"); s1.SaveChanges(); } Assert.False(WaitForDocument(store2, "foo/bar/2", timeout: 5_000)); } }
private async Task DoReplicationTest(DocumentStore storeA, DocumentStore storeB, string url) { var watcher = new ExternalReplication(storeB.Database, "Connection"); await AddWatcherToReplicationTopology(storeA, watcher, new[] { url }).ConfigureAwait(false); using (var session = storeA.OpenSession()) { session.Store(new User { Name = "foo/bar" }, "foo-id"); session.SaveChanges(); } Assert.True(WaitForDocument(storeB, "foo-id")); }
protected static async Task <ModifyOngoingTaskResult> AddWatcherToReplicationTopology( DocumentStore store, ExternalReplication watcher, string[] urls = null) { await store.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(new RavenConnectionString { Name = watcher.ConnectionStringName, Database = watcher.Database, TopologyDiscoveryUrls = urls ?? store.Urls })); var op = new UpdateExternalReplicationOperation(watcher); return(await store.Maintenance.SendAsync(op)); }
private void HandleExternalReplication(DatabaseRecord newRecord, ref List <OutgoingReplicationHandler> instancesToDispose) { var changes = ExternalReplication.FindChanges(_externalDestinations, newRecord.ExternalReplication); if (changes.RemovedDestiantions.Count > 0) { var removed = _externalDestinations.Where(n => changes.RemovedDestiantions.Contains(n.Url + "@" + n.Database)); DropOutgoingConnections(removed, ref instancesToDispose); } if (changes.AddedDestinations.Count > 0) { var added = newRecord.ExternalReplication.Where(n => changes.AddedDestinations.Contains(n.Url + "@" + n.Database)); StartOutgoingConnections(added.ToList(), external: true); } _externalDestinations.Clear(); _externalDestinations.AddRange(newRecord.ExternalReplication); }
public async Task ReplicateToWatcherWithInvalidAuth() { var serverCertPath = SetupServerAuthentication(); var dbName = GetDatabaseName(); var adminCert = AskServerForClientCertificate(serverCertPath, new Dictionary <string, DatabaseAccess>(), SecurityClearance.ClusterAdmin); var userCert1 = AskServerForClientCertificate(serverCertPath, new Dictionary <string, DatabaseAccess> { [dbName] = DatabaseAccess.Admin }); var userCert2 = AskServerForClientCertificate(serverCertPath, new Dictionary <string, DatabaseAccess> { [dbName + "otherstuff"] = DatabaseAccess.Admin }); using (var store1 = GetDocumentStore(new Options { AdminCertificate = adminCert, ClientCertificate = userCert1, ModifyDatabaseName = s => dbName })) using (var store2 = GetDocumentStore(new Options { AdminCertificate = adminCert, ClientCertificate = userCert2, ModifyDatabaseName = s => dbName, CreateDatabase = false })) { var watcher2 = new ExternalReplication { Database = store2.Database, Url = store2.Urls.First() }; await AddWatcherToReplicationTopology(store1, watcher2); using (var session = store1.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "Karmel" }, "users/1"); await session.SaveChangesAsync(); } Assert.Throws <AuthorizationException>(() => WaitForDocument <User>(store2, "users/1", (u) => u.Name == "Karmel")); } }
private static async Task ExternalReplication() { #region External_Replication_And_Embedded //first, initialize connection with one of cluster nodes var ravenClusterNodeUrl = "http://localhost:8080"; using (var store = new DocumentStore { Urls = new[] { ravenClusterNodeUrl }, Database = "Northwind" }) { store.Initialize(); //first, start the embedded server EmbeddedServer.Instance.StartServer(new ServerOptions { ServerUrl = "http://localhost:8090", AcceptEula = true }); var embeddedServerUrl = (await EmbeddedServer.Instance.GetServerUriAsync().ConfigureAwait(false)).ToString(); // create watcher definition that will be added to existing cluster var externalReplicationWatcher = new ExternalReplication( database: "Northwind", connectionStringName: "Embedded Northwind Instance"); //create the connection string for the embedded instance on the existing cluster await store.Maintenance.SendAsync( new PutConnectionStringOperation <RavenConnectionString>(new RavenConnectionString { Name = externalReplicationWatcher.ConnectionStringName, Database = externalReplicationWatcher.Database, TopologyDiscoveryUrls = new[] { embeddedServerUrl } //urls to discover topology at destination })).ConfigureAwait(false); //create External Replication task from the cluster to the embedded RavenDB instance await store.Maintenance.SendAsync(new UpdateExternalReplicationOperation(externalReplicationWatcher)) .ConfigureAwait(false); } #endregion }
public async Task DisableExternalReplication() { using (var store1 = GetDocumentStore()) using (var store2 = GetDocumentStore()) { var externalList = await SetupReplicationAsync(store1, store2); using (var session = store1.OpenSession()) { session.Store(new User { Name = "John Dow", Age = 30 }, "users/1"); session.SaveChanges(); } var replicated1 = WaitForDocumentToReplicate <User>(store2, "users/1", 10000); Assert.NotNull(replicated1); Assert.Equal("John Dow", replicated1.Name); Assert.Equal(30, replicated1.Age); var external = new ExternalReplication(store1.Database, $"ConnectionString-{store2.Identifier}") { TaskId = externalList.First().TaskId, Disabled = true }; var res = await store1.Maintenance.SendAsync(new UpdateExternalReplicationOperation(external)); Assert.Equal(externalList.First().TaskId, res.TaskId); using (var session = store1.OpenSession()) { session.Store(new User { Name = "John Dow", Age = 30 }, "users/2"); session.SaveChanges(); } var replicated2 = WaitForDocumentToReplicate <User>(store2, "users/2", 10000); Assert.Null(replicated2); } }
public async Task <List <ModifyOngoingTaskResult> > SetupReplicationAsync(IDocumentStore fromStore, params IDocumentStore[] toStores) { var tasks = new List <Task <ModifyOngoingTaskResult> >(); var resList = new List <ModifyOngoingTaskResult>(); foreach (var store in toStores) { var databaseWatcher = new ExternalReplication(store.Database, $"ConnectionString-{store.Identifier}"); ModifyReplicationDestination(databaseWatcher); tasks.Add(AddWatcherToReplicationTopology(fromStore, databaseWatcher, store.Urls)); } await Task.WhenAll(tasks); foreach (var task in tasks) { resList.Add(await task); } return(resList); }
private bool ValidateConnectionString(DatabaseRecord newRecord, ExternalReplication externalReplication, out RavenConnectionString connectionString) { connectionString = null; if (string.IsNullOrEmpty(externalReplication.ConnectionStringName)) { var msg = $"The external replication {externalReplication.Name} to the database '{externalReplication.Database}' " + "has an empty connection string name."; if (_log.IsInfoEnabled) { _log.Info(msg); } _server.NotificationCenter.Add(AlertRaised.Create( Database.Name, "Connection string name is empty", msg, AlertType.Replication, NotificationSeverity.Error)); return(false); } if (newRecord.RavenConnectionStrings.TryGetValue(externalReplication.ConnectionStringName, out connectionString) == false) { var msg = $"Could not find connection string with name {externalReplication.ConnectionStringName} " + $"for the external replication task '{externalReplication.Name}' to '{externalReplication.Database}'."; if (_log.IsInfoEnabled) { _log.Info(msg); } _server.NotificationCenter.Add(AlertRaised.Create( Database.Name, "Connection string not found", msg, AlertType.Replication, NotificationSeverity.Error)); return(false); } return(true); }
private void DoReplicationTest(DocumentStore storeA, DocumentStore storeB, string url) { var watcher = new ExternalReplication { Database = storeB.Database, Url = url, }; AddWatcherToReplicationTopology(storeA, watcher).ConfigureAwait(false); using (var session = storeA.OpenSession()) { session.Store(new User { Name = "foo/bar" }, "foo-id"); session.SaveChanges(); } Assert.True(WaitForDocument(storeB, "foo-id")); }
public override string UpdateDatabaseRecord(DatabaseRecord record, long etag) { if (Watcher == null) { return(null); } if (Watcher.TaskId == 0) { Watcher.TaskId = etag; } else { //modified watcher, remove the old one ExternalReplication.RemoveWatcher(record.ExternalReplications, Watcher.TaskId); } record.ExternalReplications.Add(Watcher); return(null); }
public async Task UpdateServerWideReplicationThroughUpdateReplicationTaskFails() { using (var store = GetDocumentStore()) { var putConfiguration = new ServerWideExternalReplication { Disabled = true, TopologyDiscoveryUrls = new[] { store.Urls.First() }, Name = store.Database }; await store.Maintenance.Server.SendAsync(new PutServerWideExternalReplicationOperation(putConfiguration)); var databaseRecord = await store.Maintenance.Server.SendAsync(new GetDatabaseRecordOperation(store.Database)); var externalReplicationFromDatabaseRecord = databaseRecord.ExternalReplications.First(); var taskId = externalReplicationFromDatabaseRecord.TaskId; var externalReplication = new ExternalReplication { Disabled = true, TaskId = externalReplicationFromDatabaseRecord.TaskId, Name = externalReplicationFromDatabaseRecord.Name, ConnectionStringName = externalReplicationFromDatabaseRecord.ConnectionStringName }; var e = await Assert.ThrowsAsync <RavenException>(() => store.Maintenance.SendAsync(new UpdateExternalReplicationOperation(externalReplication))); Assert.Contains("A regular (non server-wide) external replication name can't start with prefix 'Server Wide External Replication'", e.Message); e = await Assert.ThrowsAsync <RavenException>(() => store.Maintenance.SendAsync(new DeleteOngoingTaskOperation(taskId, OngoingTaskType.Replication))); var expectedError = $"Can't delete task id: {taskId}, name: '{externalReplicationFromDatabaseRecord.Name}', because it is a server-wide external replication task"; Assert.Contains(expectedError, e.Message); var recordConnectionString = databaseRecord.RavenConnectionStrings.First().Value; e = await Assert.ThrowsAsync <RavenException>(() => store.Maintenance.SendAsync(new PutConnectionStringOperation <RavenConnectionString>(recordConnectionString))); Assert.Contains("connection string name can't start with prefix 'Server Wide Raven Connection String'", e.Message); } }
private OngoingTaskReplication GetExternalReplicationInfo(DatabaseTopology dbTopology, ClusterTopology clusterTopology, ExternalReplication watcher) { NodeId responsibale = null; var tag = dbTopology.WhoseTaskIsIt(watcher, ServerStore.Engine.CurrentState); if (tag != null) { responsibale = new NodeId { NodeTag = tag, NodeUrl = clusterTopology.GetUrlFromTag(tag) }; } (string Url, OngoingTaskConnectionStatus Status)res = (null, OngoingTaskConnectionStatus.None); if (tag == ServerStore.NodeTag) { res = Database.ReplicationLoader.GetExternalReplicationDestination(watcher.TaskId); } else { res.Status = OngoingTaskConnectionStatus.NotOnThisNode; } var taskInfo = new OngoingTaskReplication { TaskId = watcher.TaskId, TaskName = watcher.Name, ResponsibleNode = responsibale, DestinationDatabase = watcher.Database, TaskState = watcher.Disabled ? OngoingTaskState.Disabled : OngoingTaskState.Enabled, DestinationUrl = res.Url, TaskConnectionStatus = res.Status, }; return(taskInfo); }
public override string UpdateDatabaseRecord(DatabaseRecord record, long etag) { if (Watcher == null) { return(null); } ExternalReplication.EnsureUniqueDbAndConnectionString(record.ExternalReplication, Watcher); if (Watcher.TaskId == 0) { Watcher.TaskId = etag; } else { //modified watcher, remove the old one ExternalReplication.RemoveWatcher(ref record.ExternalReplication, Watcher.TaskId); } record.ExternalReplication.Add(Watcher); return(null); }
public async Task <List <ModifyOngoingTaskResult> > SetupReplicationAsync(DocumentStore fromStore, params DocumentStore[] toStores) { var tasks = new List <Task <ModifyOngoingTaskResult> >(); var resList = new List <ModifyOngoingTaskResult>(); foreach (var store in toStores) { var databaseWatcher = new ExternalReplication { Database = store.Database, Url = store.Urls[0] }; ModifyReplicationDestination(databaseWatcher); tasks.Add(AddWatcherToReplicationTopology(fromStore, databaseWatcher)); } await Task.WhenAll(tasks); foreach (var task in tasks) { resList.Add(await task); } return(resList); }