private void WithActiveReplicatorAndURLEndpointListeners(bool isCloseNotDelete)
        {
            WaitAssert waitIdleAssert1    = new WaitAssert();
            WaitAssert waitStoppedAssert1 = new WaitAssert();

            _listener = CreateListener();
            var _listener2 = CreateNewListener();

            _listener.Config.Database.ActiveStoppables.Count.Should().Be(2);
            _listener2.Config.Database.ActiveStoppables.Count.Should().Be(2);

            using (var doc1 = new MutableDocument("doc1"))
                using (var doc2 = new MutableDocument("doc2")) {
                    doc1.SetString("name", "Sam");
                    Db.Save(doc1);
                    doc2.SetString("name", "Mary");
                    OtherDb.Save(doc2);
                }

            var target  = new DatabaseEndpoint(Db);
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb);
            var repl1   = new Replicator(config1);

            repl1.AddChangeListener((sender, args) => {
                waitIdleAssert1.RunConditionalAssert(() => {
                    return(args.Status.Activity == ReplicatorActivityLevel.Idle);
                });

                waitStoppedAssert1.RunConditionalAssert(() => {
                    return(args.Status.Activity == ReplicatorActivityLevel.Stopped);
                });
            });

            repl1.Start();

            waitIdleAssert1.WaitForResult(TimeSpan.FromSeconds(10));
            OtherDb.ActiveStoppables.Count.Should().Be(3);

            if (isCloseNotDelete)
            {
                OtherDb.Close();
            }
            else
            {
                OtherDb.Delete();
            }

            OtherDb.ActiveStoppables.Count.Should().Be(0);
            OtherDb.IsClosedLocked.Should().Be(true);

            waitStoppedAssert1.WaitForResult(TimeSpan.FromSeconds(30));
        }
Beispiel #2
0
        private static void DatabaseReplica()
        {
            var db = _Database;

            using (var database2 = new Database("backup")) {
                // EE feature: This code will not compile on the community edition
                // # tag::database-replica[]
                var targetDatabase = new DatabaseEndpoint(database2);
                var config         = new ReplicatorConfiguration(db, targetDatabase)
                {
                    ReplicatorType = ReplicatorType.Push
                };

                var replicator = new Replicator(config);
                replicator.Start();
                // # end::database-replica[]

                _Replicator?.Stop();
                _Replicator = replicator;
            }
        }
        private void WithActiveReplicationsAndURLEndpointListener(bool isCloseNotDelete)
        {
            var waitIdleAssert1    = new ManualResetEventSlim();
            var waitIdleAssert2    = new ManualResetEventSlim();
            var waitStoppedAssert1 = new ManualResetEventSlim();
            var waitStoppedAssert2 = new ManualResetEventSlim();

            using (var doc = new MutableDocument()) {
                OtherDb.Save(doc);
            }

            _listener = CreateListener();
            _listener.Config.Database.ActiveStoppables.Count.Should().Be(1);

            using (var doc1 = new MutableDocument()) {
                Db.Save(doc1);
            }

            var target  = new DatabaseEndpoint(Db);
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb);
            var repl1   = new Replicator(config1);

            Database.Delete("urlepTestDb", Directory);
            var urlepTestDb = OpenDB("urlepTestDb");

            using (var doc2 = new MutableDocument()) {
                urlepTestDb.Save(doc2);
            }

            var config2 = CreateConfig(_listener.LocalEndpoint(), ReplicatorType.PushAndPull, true,
                                       serverCert: _listener.TlsIdentity.Certs[0], sourceDb: urlepTestDb);
            var repl2 = new Replicator(config2);

            EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) =>
            {
                if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed ==
                    args.Status.Progress.Total)
                {
                    if (sender == repl1)
                    {
                        waitIdleAssert1.Set();
                    }
                    else
                    {
                        waitIdleAssert2.Set();
                    }
                }
                else if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                {
                    if (sender == repl1)
                    {
                        waitStoppedAssert1.Set();
                    }
                    else
                    {
                        waitStoppedAssert2.Set();
                    }
                }
            };

            repl1.AddChangeListener(changeListener);
            repl2.AddChangeListener(changeListener);
            repl1.Start();
            repl2.Start();

            WaitHandle.WaitAll(new[] { waitIdleAssert1.WaitHandle, waitIdleAssert2.WaitHandle }, _timeout)
            .Should().BeTrue();

            OtherDb.ActiveStoppables.Count.Should().Be(2);
            urlepTestDb.ActiveStoppables.Count.Should().Be(1);

            if (isCloseNotDelete)
            {
                urlepTestDb.Close();
                OtherDb.Close();
            }
            else
            {
                urlepTestDb.Delete();
                OtherDb.Delete();
            }

            OtherDb.ActiveStoppables.Count.Should().Be(0);
            urlepTestDb.ActiveStoppables.Count.Should().Be(0);
            OtherDb.IsClosedLocked.Should().Be(true);
            urlepTestDb.IsClosedLocked.Should().Be(true);

            WaitHandle.WaitAll(new[] { waitStoppedAssert1.WaitHandle, waitStoppedAssert2.WaitHandle }, TimeSpan.FromSeconds(20))
            .Should().BeTrue();

            waitIdleAssert1.Dispose();
            waitIdleAssert2.Dispose();
            waitStoppedAssert1.Dispose();
            waitStoppedAssert2.Dispose();

            Thread.Sleep(500);
        }
        public void TestReplicatorAndListenerOnSameDatabase()
        {
            using (var doc = new MutableDocument()) {
                OtherDb.Save(doc);
            }

            CreateListener();
            using (var doc1 = new MutableDocument()) {
                Db.Save(doc1);
            }

            var target  = new DatabaseEndpoint(Db);
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb);
            var repl1   = new Replicator(config1);

            Database.Delete("urlepTestDb", Directory);
            var urlepTestDb = OpenDB("urlepTestDb");

            using (var doc2 = new MutableDocument()) {
                urlepTestDb.Save(doc2);
            }

            var config2 = CreateConfig(_listener.LocalEndpoint(), ReplicatorType.PushAndPull, true,
                                       serverCert: _listener.TlsIdentity.Certs[0], sourceDb: urlepTestDb);
            var repl2 = new Replicator(config2);

            var wait1 = new ManualResetEventSlim();
            var wait2 = new ManualResetEventSlim();
            EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) =>
            {
                if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed ==
                    args.Status.Progress.Total)
                {
                    if (OtherDb.Count == 3 && Db.Count == 3 && urlepTestDb.Count == 3)
                    {
                        ((Replicator)sender).Stop();
                    }
                }
                else if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                {
                    if (sender == repl1)
                    {
                        wait1.Set();
                    }
                    else
                    {
                        wait2.Set();
                    }
                }
            };

            var token1 = repl1.AddChangeListener(changeListener);
            var token2 = repl2.AddChangeListener(changeListener);

            repl1.Start();
            repl2.Start();
            WaitHandle.WaitAll(new[] { wait1.WaitHandle, wait2.WaitHandle }, TimeSpan.FromSeconds(20))
            .Should().BeTrue();

            repl1.RemoveChangeListener(token1);
            repl2.RemoveChangeListener(token2);

            Db.Count.Should().Be(3, "because otherwise not all docs were received into Db");
            OtherDb.Count.Should().Be(3, "because otherwise not all docs were received into OtherDb");
            urlepTestDb.Count.Should().Be(3, "because otherwise not all docs were received into urlepTestDb");

            repl1.Dispose();
            repl2.Dispose();
            wait1.Dispose();
            wait2.Dispose();
            urlepTestDb.Delete();

            _listener.Stop();

            Thread.Sleep(500); // wait for everything to stop
        }
Beispiel #5
0
        public async Task <DatabaseCluster> RegisterAsync(RegisterDatabaseClusterRequest request)
        {
            Ensure.NotNull(request, nameof(request));

            #region Preconditions

            if (request.Name == null)
            {
                throw new ArgumentNullException(nameof(request.Name));
            }

            if (request.DatabaseId <= 0)
            {
                throw new ArgumentException("Must be > 0", nameof(request.DatabaseId));
            }

            if (request.Resource.LocationId <= 0)
            {
                throw new ArgumentException("Must be > 0", "locationId");
            }

            #endregion

            var location = Locations.Get(request.Resource.LocationId);

            var databaseId = request.DatabaseId;

            var clusterId = await DatabaseClusterId.NextAsync(db.Context, request.DatabaseId);

            var cluster = new DatabaseCluster(
                id: clusterId,
                name: request.Name,
                resource: request.Resource
                );

            await db.DatabaseClusters.InsertAsync(cluster);

            // Create the cluster's instances
            if (request.Instances != null)
            {
                foreach (var instance in request.Instances)
                {
                    instance.DatabaseId = databaseId;
                    instance.ClusterId  = clusterId;

                    await instanceService.RegisterAsync(instance);
                }
            }

            // Create the cluster's endpoints
            if (request.Endpoints != null)
            {
                foreach (var e in request.Endpoints)
                {
                    var endpointId = await DatabaseEndpointId.NextAsync(db.Context, databaseId);

                    var endpoint = new DatabaseEndpoint(
                        id: endpointId,
                        host: e.Host,
                        location: location,
                        port: (ushort)e.Port,
                        flags: e.Flags
                        );

                    await db.DatabaseEndpoints.InsertAsync(endpoint);
                }
            }

            return(cluster);
        }