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);
                }
        }
示例#2
0
        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"));
                }
        }
示例#3
0
        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);
                }
        }
示例#4
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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"));
        }
示例#8
0
        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);
        }
示例#9
0
        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");
                }
        }
示例#10
0
 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 });
     }
 }
示例#11
0
        protected static async Task <ModifyOngoingTaskResult> AddWatcherToReplicationTopology(
            DocumentStore store,
            ExternalReplication watcher)
        {
            var op = new UpdateExternalReplicationOperation(store.Database, watcher);

            return(await store.Admin.Server.SendAsync(op));
        }
示例#12
0
 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" });
     }
 }
示例#13
0
 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);
         }
 }
示例#14
0
        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);
            }
        }
示例#15
0
        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);
        }
示例#16
0
        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));
                }
        }
示例#17
0
        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));
        }
示例#19
0
        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);
        }
示例#20
0
        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"));
                }
        }
示例#21
0
        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
        }
示例#22
0
        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);
                }
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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);
        }
示例#27
0
        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);
            }
        }
示例#28
0
        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);
        }
示例#29
0
        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);
        }
示例#30
0
        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);
        }