Exemple #1
0
        protected static async Task <OngoingTasksHandler> InstantiateOutgoingTaskHandler(string name, RavenServer server)
        {
            Assert.True(server.ServerStore.DatabasesLandlord.DatabasesCache.TryGetValue(name, out var db));
            var database = await db;
            var handler  = new OngoingTasksHandler();
            var ctx      = new RequestHandlerContext
            {
                RavenServer = server,
                Database    = database,
                HttpContext = new DefaultHttpContext()
            };

            handler.Init(ctx);
            return(handler);
        }
        public async Task ExternalReplicationFailover()
        {
            var clusterSize = 3;
            var srcLeader   = await CreateRaftClusterAndGetLeader(clusterSize);

            var dstLeader = await CreateRaftClusterAndGetLeader(clusterSize);

            var dstDB = GetDatabaseName();
            var srcDB = GetDatabaseName();

            var dstTopology = await CreateDatabaseInCluster(dstDB, clusterSize, dstLeader.WebUrl);

            var srcTopology = await CreateDatabaseInCluster(srcDB, clusterSize, srcLeader.WebUrl);

            var srcStore = new DocumentStore()
            {
                Urls     = new[] { srcLeader.WebUrl },
                Database = srcDB,
            }.Initialize();

            using (var session = srcStore.OpenSession())
            {
                session.Store(new User {
                    Name = "Karmel"
                }, "users/1");
                session.SaveChanges();
                Assert.True(await WaitForDocumentInClusterAsync <User>(
                                session as DocumentSession,
                                "users/1",
                                u => u.Name.Equals("Karmel"),
                                TimeSpan.FromSeconds(clusterSize + 5)));
            }

            // add watcher with invalid url to test the failover on database topology discovery
            var watcher = new ExternalReplication(dstDB, new[] { "http://127.0.0.1:1234", dstLeader.WebUrl });
            var res     = await AddWatcherToReplicationTopology((DocumentStore)srcStore, watcher);

            var dstStore = new DocumentStore
            {
                Urls     = new[] { dstLeader.WebUrl },
                Database = watcher.Database,
            }.Initialize();

            var dstSession = dstStore.OpenSession();

            dstSession.Load <User>("Karmel");
            Assert.True(await WaitForDocumentInClusterAsync <User>(
                            dstSession as DocumentSession,
                            "users/1",
                            u => u.Name.Equals("Karmel"),
                            TimeSpan.FromSeconds(60)));

            var responsibale = srcLeader.ServerStore.GetClusterTopology().GetUrlFromTag(res.ResponsibleNode);
            var server       = Servers.Single(s => s.WebUrl == responsibale);

            Assert.True(WaitForValue(() => OngoingTasksHandler.GetOngoingTasksFor(srcDB, server.ServerStore).OngoingTasksList.Single(t => t is OngoingTaskReplication).As <OngoingTaskReplication>().DestinationUrl != null, true));

            var watcherTaskUrl = OngoingTasksHandler.GetOngoingTasksFor(srcDB, server.ServerStore).OngoingTasksList.Single(t => t is OngoingTaskReplication).As <OngoingTaskReplication>().DestinationUrl;

            // fail the node to to where the data is sent
            DisposeServerAndWaitForFinishOfDisposal(Servers.Single(s => s.WebUrl == watcherTaskUrl));

            using (var session = srcStore.OpenSession())
            {
                session.Store(new User {
                    Name = "Karmel2"
                }, "users/2");
                session.SaveChanges();
                Assert.True(await WaitForDocumentInClusterAsync <User>(
                                session as DocumentSession,
                                "users/2",
                                u => u.Name.Equals("Karmel2"),
                                TimeSpan.FromSeconds(clusterSize + 5)));
            }
            WaitForUserToContinueTheTest(dstStore as DocumentStore);
            Assert.True(WaitForDocument(dstStore, "users/2", 30_000));

            srcStore.Dispose();
            dstSession.Dispose();
            dstStore.Dispose();
        }
Exemple #3
0
        public async Task CanAddAndModifySingleWatcher()
        {
            var clusterSize  = 3;
            var databaseName = "ReplicationTestDB";
            var leader       = await CreateRaftClusterAndGetLeader(clusterSize);

            ExternalReplication watcher;

            using (var store = new DocumentStore()
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                var doc            = new DatabaseRecord(databaseName);
                var databaseResult = await store.Admin.Server.SendAsync(new CreateDatabaseOperation(doc, clusterSize));

                Assert.Equal(clusterSize, databaseResult.Topology.AllNodes.Count());
                foreach (var server in Servers)
                {
                    await server.ServerStore.Cluster.WaitForIndexNotification(databaseResult.RaftCommandIndex);
                }
                foreach (var server in Servers)
                {
                    await server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName);
                }
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new User { Name = "Karmel" }, "users/1");

                    await session.SaveChangesAsync();
                }
                Assert.True(await WaitForDocumentInClusterAsync <User>(
                                databaseResult.Topology,
                                databaseName,
                                "users/1",
                                u => u.Name.Equals("Karmel"),
                                TimeSpan.FromSeconds(clusterSize + 5)));


                doc = new DatabaseRecord("Watcher");
                var res = await store.Admin.Server.SendAsync(new CreateDatabaseOperation(doc));

                var node = Servers.Single(x => x.WebUrl == res.NodesAddedTo[0]);
                await node.ServerStore.Cluster.WaitForIndexNotification(res.RaftCommandIndex);

                await node.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore("Watcher");

                watcher = new ExternalReplication
                {
                    Database = "Watcher",
                    Url      = res.NodesAddedTo[0],
                    Name     = "MyExternalReplication1"
                };

                await AddWatcherToReplicationTopology((DocumentStore)store, watcher);
            }

            var tasks = OngoingTasksHandler.GetOngoingTasksFor(databaseName, leader.ServerStore);

            Assert.Equal(1, tasks.OngoingTasksList.Count);
            var repTask = tasks.OngoingTasksList[0] as OngoingTaskReplication;

            Assert.Equal(repTask?.DestinationDatabase, watcher.Database);
            Assert.Equal(repTask?.DestinationUrl, watcher.Url);
            Assert.Equal(repTask?.TaskName, watcher.Name);

            watcher.TaskId = Convert.ToInt64(repTask?.TaskId);

            using (var store = new DocumentStore
            {
                Urls = new[] { watcher.Url },
                Database = watcher.Database,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                Assert.True(WaitForDocument <User>(store, "users/1", u => u.Name == "Karmel"));
            }

            using (var store = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                var doc = new DatabaseRecord("Watcher2");
                var res = await store.Admin.Server.SendAsync(new CreateDatabaseOperation(doc));

                var node = Servers.Single(x => x.WebUrl == res.NodesAddedTo[0]);
                await node.ServerStore.Cluster.WaitForIndexNotification(res.RaftCommandIndex);

                await node.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore("Watcher2");

                //modify watcher
                watcher.Database = "Watcher2";
                watcher.Url      = res.NodesAddedTo[0];
                watcher.Name     = "MyExternalReplication2";

                await AddWatcherToReplicationTopology((DocumentStore)store, watcher);
            }

            tasks = OngoingTasksHandler.GetOngoingTasksFor(databaseName, leader.ServerStore);
            Assert.Equal(1, tasks.OngoingTasksList.Count);
            repTask = tasks.OngoingTasksList[0] as OngoingTaskReplication;
            Assert.Equal(repTask?.DestinationDatabase, watcher.Database);
            Assert.Equal(repTask?.DestinationUrl, watcher.Url);
            Assert.Equal(repTask?.TaskName, watcher.Name);

            using (var store = new DocumentStore
            {
                Urls = new[] { watcher.Url },
                Database = watcher.Database,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                Assert.True(WaitForDocument <User>(store, "users/1", u => u.Name == "Karmel"));
            }

            //delete watcher
            using (var store = new DocumentStore
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                await DeleteOngoingTask((DocumentStore)store, watcher.TaskId, OngoingTaskType.Replication);

                tasks = OngoingTasksHandler.GetOngoingTasksFor(databaseName, leader.ServerStore);
                Assert.Equal(0, tasks.OngoingTasksList.Count);
            }
        }
        public async Task EnsureReplicationToWatchers(bool useSsl)
        {
            var clusterSize  = 3;
            var databaseName = GetDatabaseName();
            var leader       = await CreateRaftClusterAndGetLeader(clusterSize, useSsl : useSsl);

            var watchers = new List <ExternalReplication>();

            X509Certificate2 adminCertificate = null;

            if (useSsl)
            {
                adminCertificate = AskServerForClientCertificate(_selfSignedCertFileName, new Dictionary <string, DatabaseAccess>(), SecurityClearance.ClusterAdmin, server: leader);
            }


            using (var store = new DocumentStore()
            {
                Urls = new[] { leader.WebUrl },
                Database = databaseName,
                Certificate = adminCertificate,
                Conventions =
                {
                    DisableTopologyUpdates = true
                }
            }.Initialize())
            {
                var doc            = new DatabaseRecord(databaseName);
                var databaseResult = await store.Admin.Server.SendAsync(new CreateDatabaseOperation(doc, clusterSize));

                Assert.Equal(clusterSize, databaseResult.Topology.AllNodes.Count());
                foreach (var server in Servers)
                {
                    await server.ServerStore.Cluster.WaitForIndexNotification(databaseResult.RaftCommandIndex);
                }
                foreach (var server in Servers)
                {
                    await server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName);
                }
                using (var session = store.OpenAsyncSession())
                {
                    await session.StoreAsync(new User { Name = "Karmel" }, "users/1");

                    await session.SaveChangesAsync();
                }
                Assert.True(await WaitForDocumentInClusterAsync <User>(
                                databaseResult.Topology,
                                databaseName,
                                "users/1",
                                u => u.Name.Equals("Karmel"),
                                TimeSpan.FromSeconds(clusterSize + 5),
                                adminCertificate));

                for (var i = 0; i < 5; i++)
                {
                    doc = new DatabaseRecord($"Watcher{i}");
                    var res = await store.Admin.Server.SendAsync(new CreateDatabaseOperation(doc));

                    var server = Servers.Single(x => x.WebUrl == res.NodesAddedTo[0]);
                    await server.ServerStore.Cluster.WaitForIndexNotification(res.RaftCommandIndex);

                    await server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore($"Watcher{i}");

                    var watcher = new ExternalReplication($"Watcher{i}", res.NodesAddedTo.ToArray());
                    watchers.Add(watcher);

                    await AddWatcherToReplicationTopology((DocumentStore)store, watcher);
                }
            }

            foreach (var watcher in watchers)
            {
                using (var store = new DocumentStore
                {
                    Urls = watcher.TopologyDiscoveryUrls,
                    Database = watcher.Database,
                    Certificate = adminCertificate,
                    Conventions =
                    {
                        DisableTopologyUpdates = true
                    }
                }.Initialize())
                {
                    Assert.True(WaitForDocument <User>(store, "users/1", u => u.Name == "Karmel"));
                }
            }
            var count = 0;

            foreach (var server in Servers)
            {
                count += OngoingTasksHandler.GetOngoingTasksFor(databaseName, server.ServerStore).OngoingTasksList.Count(t => t is OngoingTaskReplication rep && rep.Status != OngoingTaskReplication.ReplicationStatus.NotOnThisNode);
            }
            Assert.Equal(5, count);
        }