private void RunReplication(ReplicatorConfiguration config, int expectedErrCode, C4ErrorDomain expectedErrDomain)
        {
            Misc.SafeSwap(ref _repl, new Replicator(config));
            _waitAssert = new WaitAssert();
            var token = _repl.AddChangeListener((sender, args) =>
            {
                _waitAssert.RunConditionalAssert(() =>
                {
                    VerifyChange(args, expectedErrCode, expectedErrDomain);
                    if (config.Continuous && args.Status.Activity == ReplicatorActivityLevel.Idle &&
                        args.Status.Progress.Completed == args.Status.Progress.Total)
                    {
                        ((Replicator)sender).Stop();
                    }

                    return(args.Status.Activity == ReplicatorActivityLevel.Stopped);
                });
            });

            _repl.Start();
            try {
                _waitAssert.WaitForResult(TimeSpan.FromSeconds(10));
            } catch {
                _repl.Stop();
                throw;
            } finally {
                _repl.RemoveChangeListener(token);
            }
        }
        private static void InitCouchBase()
        {
            NetDesktop.Activate();

            // Get the database (and create it if it doesn't exist)
            _database = new Database("db");

            // Create replicator to push and pull changes to and from the cloud
            var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/db"));
            var replConfig     = new ReplicatorConfiguration(_database, targetEndpoint);

            // Add authentication
            replConfig.Authenticator  = new BasicAuthenticator("sync_gateway", "password");
            replConfig.ReplicatorType = ReplicatorType.PushAndPull;
            replConfig.Continuous     = true;

            // Create replicator (make sure to add an instance or static variable
            // named _Replicator)
            _Replicator = new Replicator(replConfig);
            _Replicator.AddChangeListener((sender, args) =>
            {
                Instance.DataChanged.Invoke(sender, args);
                _log.Debug($"status={args.Status.Activity}");
                _log.Debug($"progress={args.Status.Progress.Completed}/{args.Status.Progress.Total}");
                _log.Debug($"error={args.Status.Error}");
                if (args.Status.Error != null)
                {
                    _log.Error($"Error :: {args.Status.Error}");
                }
            });

            _Replicator.Start();
        }
Example #3
0
        public void StartReplication()
        {
            try
            {
                var targetUrlEndpoint = new URLEndpoint(new Uri(_remoteSyncUrl, _databaseName));

                var configuration = new ReplicatorConfiguration(Database, targetUrlEndpoint)
                {
                    ReplicatorType = ReplicatorType.PushAndPull,
                    Continuous     = true
                };

                _replicator = new Replicator(configuration);

                _replicatorListenerToken = _replicator.AddChangeListener(OnReplicatorUpdate);

                _replicator.Start();
            }
            catch (Exception ex)
            {
                // We don't want replication errors to prevent us from
                // using the app, but we do want to know about them.
                Console.WriteLine($"Replication Exception - {ex.Message}");
            }
        }
Example #4
0
        public void CreateReplicator(string PeerEndpointString)
        {
            if (_repl != null)
            {
                return;
            }

            Uri host             = new Uri(PeerEndpointString);
            var dbUrl            = new Uri(host, _db.Name);
            var replicatorConfig = new ReplicatorConfiguration(_db, new URLEndpoint(dbUrl)); // <1>

            replicatorConfig.ReplicatorType = ReplicatorType.PushAndPull;
            replicatorConfig.Continuous     = true;

            if (CoreApp.ListenerTLSMode > 0)
            {
                // Explicitly allows self signed certificates. By default, only
                // CA signed cert is allowed
                switch (CoreApp.ListenerCertValidationMode)   // <2>
                {
                case LISTENER_CERT_VALIDATION_MODE.SKIP_VALIDATION:
                    // Use acceptOnlySelfSignedServerCertificate set to true to only accept self signed certs.
                    // There is no cert validation
                    replicatorConfig.AcceptOnlySelfSignedServerCertificate = true;
                    break;

                case LISTENER_CERT_VALIDATION_MODE.ENABLE_VALIDATION_WITH_CERT_PINNING:
                    // Use acceptOnlySelfSignedServerCertificate set to false to only accept CA signed certs
                    // Self signed certs will fail validation

                    replicatorConfig.AcceptOnlySelfSignedServerCertificate = false;

                    // Enable cert pinning to only allow certs that match pinned cert

                    try {
                        var pinnedCert = LoadSelfSignedCertForListenerFromBundle();
                        replicatorConfig.PinnedServerCertificate = pinnedCert;
                    } catch (Exception ex) {
                        Debug.WriteLine($"Failed to load server cert to pin. Will proceed without pinning. {ex}");
                    }

                    break;

                case LISTENER_CERT_VALIDATION_MODE.ENABLE_VALIDATION:
                    // Use acceptOnlySelfSignedServerCertificate set to false to only accept CA signed certs
                    // Self signed certs will fail validation. There is no cert pinning
                    replicatorConfig.AcceptOnlySelfSignedServerCertificate = false;
                    break;
                }
            }

            if (CoreApp.RequiresUserAuth)
            {
                var user = CoreApp.CurrentUser;
                replicatorConfig.Authenticator = new BasicAuthenticator(user.Username, user.Password); // <3>
            }

            _repl          = new Replicator(replicatorConfig); // <4>
            _listenerToken = _repl.AddChangeListener(ReplicationStatusUpdate);
        }
        public MainWindow()
        {
            InitializeComponent();

            log4net.Config.XmlConfigurator.Configure();

            Couchbase.Lite.Support.NetDesktop.Activate();

            var config = new DatabaseConfiguration()
            {
                Directory = AppDomain.CurrentDomain.BaseDirectory
            };

            Database = new Database(DbName, config);

            var configSync = new ReplicatorConfiguration(Database, new URLEndpoint(SyncGatewayUrl))
            {
                ReplicatorType = ReplicatorType.PushAndPull,
                Continuous     = true
            };

            configSync.Authenticator = new BasicAuthenticator("emonthly", "password");

            _replication = new Replicator(configSync);
            _replication.AddChangeListener((sender, args) =>
            {
                Console.WriteLine(args.Status.Activity);
            });
            _replication.Start();
        }
Example #6
0
        private void Connect()
        {
            try
            {
                if (_serverInfo == null)
                {
                    _serverInfo = _serverDal.Get();
                }
                if (_serverInfo == null)
                {
                    return;
                }
                Uri       target   = new Uri($"ws://{_serverInfo.UrlServer}");
                IEndpoint endpoint = new URLEndpoint(target);
                ReplicatorConfiguration replicationConfig = new ReplicatorConfiguration(_dataBaseGetter.Get(), endpoint)
                {
                    Continuous     = true,
                    ReplicatorType = ReplicatorType.PushAndPull,
                    Authenticator  = new BasicAuthenticator(_serverInfo.Login, _serverInfo.Password)
                };
                _replicator = new Replicator(replicationConfig);
                if (CrossConnectivity.IsSupported && CrossConnectivity.Current.IsConnected)
                {
                    _replicator.Start();
                }
                _token = _replicator.AddChangeListener(_replicator_StatusChanged);
            }
            catch (Exception e)
            {
#if DEBUG
#endif
            }
        }
        private Replicator StartReplication(string username, string password, Database db)
        {
            if (String.IsNullOrWhiteSpace(username) || String.IsNullOrWhiteSpace(password))
            {
                throw new InvalidOperationException("User credentials not provided");
            }

            var dbUrl = new Uri(SyncUrl, DbName);

            Debug.WriteLine(
                $"PushPull Replicator:Will connect to  {SyncUrl}");

            var config = new ReplicatorConfiguration(db, new URLEndpoint(dbUrl))
            {
                ReplicatorType = ReplicatorType.PushAndPull,
                Continuous     = true,
                Authenticator  = new BasicAuthenticator(username, password),
                Channels       = new[] { $"channel.{username}" }
            };

            var repl = new Replicator(config);

            repl.AddChangeListener((sender, args) =>
            {
                var s = args.Status;
                Debug.WriteLine(
                    $"PushPull Replicator: {s.Progress.Completed}/{s.Progress.Total}, error {s.Error?.Message ?? "<none>"}, activity = {s.Activity}");
            });

            repl.Start();
            return(repl);
        }
        private void Connect()
        {
            Uri target = new Uri($"{_serverInfo.UrlServer}");
            ReplicatorConfiguration replicationConfig = new ReplicatorConfiguration(_dataBaseGetter.Get(), target);

            replicationConfig.Continuous     = true;
            replicationConfig.ReplicatorType = ReplicatorType.PushAndPull;
            replicationConfig.Authenticator  = new BasicAuthenticator(_serverInfo.Login, _serverInfo.Password);
            _replicator = new Replicator(replicationConfig);
            _replicator.Start();
            _token = _replicator.AddChangeListener(_replicator_StatusChanged);
        }
        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));
        }
        public void TestStopContinuousReplicator()
        {
            var config = CreateConfig(true, false, true);

            using (var r = new Replicator(config)) {
                var stopWhen = new[]
                {
                    ReplicatorActivityLevel.Connecting, ReplicatorActivityLevel.Busy,
                    ReplicatorActivityLevel.Idle, ReplicatorActivityLevel.Idle
                };

                foreach (var when in stopWhen)
                {
                    var stopped    = 0;
                    var waitAssert = new WaitAssert();
                    var token      = r.AddChangeListener((sender, args) =>
                    {
                        waitAssert.RunConditionalAssert(() =>
                        {
                            VerifyChange(args, 0, 0);

                            // On Windows, at least, sometimes the connection is so fast that Connecting never gets called
                            if ((args.Status.Activity == when ||
                                 (when == ReplicatorActivityLevel.Connecting && args.Status.Activity > when)) &&
                                Interlocked.Exchange(ref stopped, 1) == 0)
                            {
                                WriteLine("***** Stop Replicator *****");
                                ((Replicator)sender).Stop();
                            }

                            if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                            {
                                WriteLine("Stopped!");
                            }

                            return(args.Status.Activity == ReplicatorActivityLevel.Stopped);
                        });
                    });

                    WriteLine("***** Start Replicator *****");
                    r.Start();
                    try {
                        waitAssert.WaitForResult(TimeSpan.FromSeconds(5));
                    } finally {
                        r.RemoveChangeListener(token);
                    }

                    Task.Delay(100).Wait();
                }
            }
        }
        public void StartDBConnection()
        {
            Couchbase.Lite.Support.UWP.Activate();

            // Get the database (and create it if it doesn't exist)
            this.database = new Database("einkaufsliste");

            // Create replicator to push and pull changes to and from the cloud
            var targetEndpoint = new URLEndpoint(new Uri("ws://37.252.185.24:4984/db"));
            var replConfig     = new ReplicatorConfiguration(this.database, targetEndpoint)
            {
                ReplicatorType = ReplicatorType.PushAndPull
            };

            replConfig.Channels = new List <String>();
            replConfig.Channels.Add("liste");
            replConfig.Continuous = true;

            // Add authentication
            replConfig.Authenticator = new BasicAuthenticator("UserEin", "Einkaufsliste");

            // Create replicator
            var replicator = new Replicator(replConfig);

            replicator.AddChangeListener((sender, args) =>
            {
                if (args.Status.Error != null)
                {
                    System.Diagnostics.Debug.WriteLine($"Error :: {args.Status.Error}");
                }
                System.Diagnostics.Debug.WriteLine("Test sync");

                using (var query = QueryBuilder.Select(SelectResult.All())
                                   .From(DataSource.Database(this.database)))
                {
                    // Run the query
                    var result = query.Execute();
                    var res    = result.ToArray();
                    foreach (var i in res)
                    {
                        System.Diagnostics.Debug.WriteLine("Output " + Newtonsoft.Json.JsonConvert.SerializeObject(i));
                        System.Diagnostics.Debug.WriteLine("Output " + i.GetDictionary(0).GetString("name"));
                    }

                    result = query.Execute();
                    System.Diagnostics.Debug.WriteLine("Number " + result.Count());
                }
            });

            replicator.Start();
        }
        private void RunReplicatorServerCert(Replicator repl, bool hasIdle, X509Certificate2 serverCert)
        {
            using (var waitIdle = new ManualResetEventSlim())
                using (var waitStopped = new ManualResetEventSlim()) {
                    repl.AddChangeListener((sender, args) =>
                    {
                        var level        = args.Status.Activity;
                        var correctError = hasIdle ? args.Status.Error == null : args.Status.Error != null;
                        if (level == ReplicatorActivityLevel.Idle)
                        {
                            waitIdle.Set();
                        }
                        else if (level == ReplicatorActivityLevel.Stopped && correctError)
                        {
                            waitStopped.Set();
                        }
                    });

                    repl.ServerCertificate.Should().BeNull();
                    repl.Start();

                    if (hasIdle)
                    {
                        waitIdle.Wait(_timeout).Should().BeTrue();
                        if (serverCert == null)
                        {
                            repl.ServerCertificate.Should().BeNull();
                        }
                        else
                        {
                            serverCert.Thumbprint.Should().Be(repl.ServerCertificate?.Thumbprint);
                        }

                        repl.Stop();
                    }

                    waitStopped.Wait(_timeout).Should().BeTrue();
                    if (serverCert == null)
                    {
                        repl.ServerCertificate.Should().BeNull();
                    }
                    else
                    {
                        serverCert.Thumbprint.Should().Be(repl.ServerCertificate?.Thumbprint);
                    }
                }
        }
Example #13
0
        /// <summary>
        /// Starts a replication for the session
        /// </summary>
        /// <param name="username">The username to use for the replication</param>
        /// <param name="password">The password to use for replication auth (optional)</param>
        public static void StartReplication(string username, string password = null)
        {
            var config = new ReplicatorConfiguration(Database, new URLEndpoint(SyncGatewayUrl))
            {
                ReplicatorType = ReplicatorType.PushAndPull,
                Continuous     = true
            };

            if (username != null && password != null)
            {
                config.Authenticator = new BasicAuthenticator(username, password);
            }

            _replication = new Replicator(config);
            _replication.AddChangeListener((sender, args) =>
            {
                Console.WriteLine(args.Status.Activity);
            });
            _replication.Start();
        }
        public void TestStopListener()
        {
            ManualResetEventSlim waitIdleAssert    = new ManualResetEventSlim();
            ManualResetEventSlim waitStoppedAssert = new ManualResetEventSlim();

            var config = CreateListenerConfig(false);

            _listener = Listen(config);

            var target  = _listener.LocalEndpoint();
            var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true,
                                       serverCert: null);

            using (var repl = new Replicator(config1)) {
                var token = repl.AddChangeListener((sender, args) =>
                {
                    if (args.Status.Activity == ReplicatorActivityLevel.Idle)
                    {
                        waitIdleAssert.Set();
                        // Stop listener aka server
                        _listener.Stop();
                    }
                    else if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                    {
                        waitStoppedAssert.Set();
                    }
                });

                repl.Start();

                // Wait until idle then stop the listener
                waitIdleAssert.Wait(TimeSpan.FromSeconds(15)).Should().BeTrue();

                // Wait for the replicator to be stopped
                waitStoppedAssert.Wait(TimeSpan.FromSeconds(20)).Should().BeTrue();

                // Check error
                var error = repl.Status.Error.As <CouchbaseWebsocketException>();
                error.Error.Should().Be((int)CouchbaseLiteError.WebSocketGoingAway);
            }
        }
Example #15
0
        public void StartReplication(string sessionId,
                                     string[] channels,
                                     ReplicatorType replicationType = ReplicatorType.PushAndPull,
                                     bool continuous = true)
        {
            var targetUrlEndpoint = new URLEndpoint(new Uri(_remoteSyncUrl, _databaseName));

            var configuration = new ReplicatorConfiguration(Database, targetUrlEndpoint)
            {
                ReplicatorType = replicationType,
                Continuous     = continuous,
                Authenticator  = new SessionAuthenticator(sessionId),
                Channels       = channels
            };

            _replicator = new Replicator(configuration);

            _replicatorListenerToken = _replicator.AddChangeListener(OnReplicatorUpdate);

            _replicator.Start();
        }
        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
        }
        public void TestStatus()
        {
            ulong maxConnectionCount = 0UL;
            ulong maxActiveCount     = 0UL;

            //init and start a listener
            _listener = CreateListener(false);

            //listener is started at this point
            _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because no client connection has been established.");
            _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because no client connection has been established.");

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

            var targetEndpoint = _listener.LocalEndpoint();
            var config         = new ReplicatorConfiguration(Db, targetEndpoint);

            using (var repl = new Replicator(config)) {
                var waitAssert = new WaitAssert();
                var token      = repl.AddChangeListener((sender, args) =>
                {
                    WriteLine($"Yeehaw {_listener.Status.ConnectionCount} / {_listener.Status.ActiveConnectionCount}");

                    maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
                    maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

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

                repl.Start();
                while (repl.Status.Activity != ReplicatorActivityLevel.Busy)
                {
                    Thread.Sleep(100);
                }

                // For some reason running on mac throws off the timing enough so that the active connection count
                // of 1 is never seen.  So record the value right after it becomes busy.
                maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
                maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

                try {
                    waitAssert.WaitForResult(TimeSpan.FromSeconds(100));
                } finally {
                    repl.RemoveChangeListener(token);
                }
            }

            maxConnectionCount.Should().Be(1);
            maxActiveCount.Should().Be(1);

            //stop the listener
            _listener.Stop();
            _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because the connection is stopped.");
            _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because the connection is stopped.");
        }
        // Two replicators, replicates docs to the listener; validates connection status
        private void ValidateMultipleReplicationsTo(ReplicatorType replicatorType)
        {
            ulong maxConnectionCount = 0UL;
            ulong maxActiveCount     = 0UL;

            var existingDocsInListener = _listener.Config.Database.Count;

            existingDocsInListener.Should().Be(1);

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

            var target     = _listener.LocalEndpoint();
            var serverCert = _listener.TlsIdentity.Certs[0];
            var config1    = CreateConfig(target, replicatorType, true,
                                          serverCert: serverCert, sourceDb: Db);
            var repl1 = new Replicator(config1);

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

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

            var config2 = CreateConfig(target, replicatorType, true,
                                       serverCert: serverCert, sourceDb: urlepTestDb);
            var repl2 = new Replicator(config2);

            var wait1 = new ManualResetEventSlim();
            var wait2 = new ManualResetEventSlim();
            EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) =>
            {
                maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
                maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

                if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed ==
                    args.Status.Progress.Total)
                {
                    if ((replicatorType == ReplicatorType.PushAndPull && OtherDb.Count == 3 &&
                         Db.Count == 3 && urlepTestDb.Count == 3) || (replicatorType == ReplicatorType.Pull && OtherDb.Count == 1 &&
                                                                      Db.Count == 2 && urlepTestDb.Count == 2))
                    {
                        ((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();

            while (repl1.Status.Activity != ReplicatorActivityLevel.Busy ||
                   repl2.Status.Activity != ReplicatorActivityLevel.Busy)
            {
                Thread.Sleep(100);
            }

            // For some reason running on mac throws off the timing enough so that the active connection count
            // of 1 is never seen.  So record the value right after it becomes busy.
            maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount);
            maxActiveCount     = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount);

            WaitHandle.WaitAll(new[] { wait1.WaitHandle, wait2.WaitHandle }, TimeSpan.FromSeconds(30))
            .Should().BeTrue();

            maxConnectionCount.Should().Be(2);
            maxActiveCount.Should().Be(2);

            // all data are transferred to/from
            if (replicatorType == ReplicatorType.PushAndPull)
            {
                _listener.Config.Database.Count.Should().Be(existingDocsInListener + 2UL);
                Db.Count.Should().Be(existingDocsInListener + 2UL);
                urlepTestDb.Count.Should().Be(existingDocsInListener + 2UL);
            }
            else if (replicatorType == ReplicatorType.Pull)
            {
                _listener.Config.Database.Count.Should().Be(1);
                Db.Count.Should().Be(existingDocsInListener + 1UL);
                urlepTestDb.Count.Should().Be(existingDocsInListener + 1UL);
            }

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

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

            _listener.Stop();

            Thread.Sleep(500);
        }
Example #20
0
        private static void GettingStarted()
        {
            // # tag::getting-started[]
            // Get the database (and create it if it doesn't exist)
            var database = new Database("mydb");
            // Create a new document (i.e. a record) in the database
            string id = null;

            using (var mutableDoc = new MutableDocument()) {
                mutableDoc.SetFloat("version", 2.0f)
                .SetString("type", "SDK");

                // Save it to the database
                database.Save(mutableDoc);
                id = mutableDoc.Id;
            }

            // Update a document
            using (var doc = database.GetDocument(id))
                using (var mutableDoc = doc.ToMutable()) {
                    mutableDoc.SetString("language", "C#");
                    database.Save(mutableDoc);

                    using (var docAgain = database.GetDocument(id)) {
                        Console.WriteLine($"Document ID :: {docAgain.Id}");
                        Console.WriteLine($"Learning {docAgain.GetString("language")}");
                    }
                }

            // Create a query to fetch documents of type SDK
            // i.e. SELECT * FROM database WHERE type = "SDK"
            using (var query = QueryBuilder.Select(SelectResult.All())
                               .From(DataSource.Database(database))
                               .Where(Expression.Property("type").EqualTo(Expression.String("SDK")))) {
                // Run the query
                var result = query.Execute();
                Console.WriteLine($"Number of rows :: {result.Count()}");
            }

            // Create replicator to push and pull changes to and from the cloud
            var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/example_sg_db"));
            var replConfig     = new ReplicatorConfiguration(database, targetEndpoint);

            // Add authentication
            replConfig.Authenticator = new BasicAuthenticator("john", "pass");

            // Create replicator
            var replicator = new Replicator(replConfig);

            replicator.AddChangeListener((sender, args) =>
            {
                if (args.Status.Error != null)
                {
                    Console.WriteLine($"Error :: {args.Status.Error}");
                }
            });

            replicator.Start();

            // Later, stop and dispose the replicator *before* closing/disposing the database
            // # end::getting-started[]
        }
Example #21
0
        private static void GettingStarted()
        {
            // tag::getting-started[]
            // Get the database (and create it if it doesn't exist)
            var database = new Database("mydb");

            // Create a new document (i.e. a record) in the database
            string id = null;

            using (var mutableDoc = new MutableDocument())
            {
                mutableDoc.SetFloat("version", 2.0f)
                .SetString("type", "SDK");

                // Save it to the database
                database.Save(mutableDoc);
                id = mutableDoc.Id;
            }

            // Update a document

            // Retrieve doc from database
            using (var doc = database.GetDocument(id))

                // set the doc to mutable
                using (var mutableDoc = doc.ToMutable())
                {
                    // apply some modifications :
                    // add a field & value
                    mutableDoc.SetString("language", "C#");

                    // save the doc
                    database.Save(mutableDoc);

                    // retrieve again from Lite DB to check the updated doc
                    // with the new field
                    using (var docAgain = database.GetDocument(id))
                    {
                        Console.WriteLine($"Document ID :: {docAgain.Id}");
                        Console.WriteLine($"Learning {docAgain.GetString("language")}");
                    }
                }

            // Create a query to fetch documents of type SDK
            // i.e. SELECT * FROM database WHERE type = "SDK"

            using (var query = QueryBuilder.Select(SelectResult.All())
                               .From(DataSource.Database(database))
                               .Where(Expression.Property("type").EqualTo(Expression.String("SDK"))))
            {
                // Run the query
                var result = query.Execute();
                Console.WriteLine($"Number of rows :: {result.Count()}");
            }

            // Create replicator to push and pull changes to and from the remote couchbase DB
            // Through Sync Gateway & WebSockets (ws)

            var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/getting-started-db"));
            var replConfig     = new ReplicatorConfiguration(database, targetEndpoint);

            // Add authentication

            replConfig.Authenticator = new BasicAuthenticator("admin", "password");

            // Create replicator (make sure to add an instance or static variable
            // named _Replicator)

            _Replicator = new Replicator(replConfig);

            // Manage replication error handling

            _Replicator.AddChangeListener((sender, args) =>
            {
                if (args.Status.Error != null)
                {
                    Console.WriteLine($"Error :: {args.Status.Error}");
                }
            });

            _Replicator.Start();

            // Later, stop and dispose the replicator *before* closing/disposing the database
            // end::getting-started[]
        }
Example #22
0
        static void Main(string[] args)
        {
            // This only needs to be done once for whatever platform the executable is running
            // (UWP, iOS, Android, or desktop)
            Couchbase.Lite.Support.NetDesktop.Activate();

            // create database
            var config = new DatabaseConfiguration();

            config.ConflictResolver = new ExampleConflictResolver();
            var database = new Database("my-database", config);

            // create document
            var newTask = new MutableDocument();

            newTask.SetString("type", "task");
            newTask.SetString("owner", "todo");
            newTask.SetDate("createdAt", DateTimeOffset.UtcNow);
            newTask = database.Save(newTask).ToMutable();

            // mutate document
            newTask.SetString("name", "Apples");
            newTask = database.Save(newTask).ToMutable();

            // typed accessors
            newTask.SetDate("createdAt", DateTimeOffset.UtcNow);
            var date = newTask.GetDate("createdAt");

            // database transaction
            database.InBatch(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    using (var doc = new MutableDocument()) {
                        doc.SetString("type", "user");
                        doc.SetString("name", $"user {i}");
                        using (var saved = database.Save(doc)) {
                            Console.WriteLine($"saved user document {saved.GetString("name")}");
                        }
                    }
                }
            });

            // blob
            var bytes = File.ReadAllBytes("avatar.jpg");
            var blob  = new Blob("image/jpg", bytes);

            newTask.SetBlob("avatar", blob);
            newTask = database.Save(newTask).ToMutable();
            var taskBlob = newTask.GetBlob("avatar");
            var data     = taskBlob.Content;

            newTask.Dispose();

            // query
            var query = QueryBuilder.Select(SelectResult.Expression(Meta.ID))
                        .From(DataSource.Database(database))
                        .Where(Expression.Property("type").EqualTo(Expression.String("user"))
                               .And(Expression.Property("admin").EqualTo(Expression.Boolean(false))));

            var rows = query.Execute();

            foreach (var row in rows)
            {
                Console.WriteLine($"doc ID :: ${row.GetString(0)}");
            }


            // live query
            query.AddChangeListener((sender, e) => {
                Console.WriteLine($"Number of rows :: {e.Results.Count()}");
            });

            using (var newDoc = new MutableDocument()) {
                newDoc.SetString("type", "user");
                newDoc.SetBoolean("admin", false);
                database.Save(newDoc);
            }

            // fts example
            // insert documents
            var tasks = new[] { "buy groceries", "play chess", "book travels", "buy museum tickets" };

            foreach (string task in tasks)
            {
                using (var doc = new MutableDocument()) {
                    doc.SetString("type", "task").SetString("name", task); // Chaining is possible
                    database.Save(doc);
                }
            }

            // create Index
            var index = IndexBuilder.FullTextIndex(FullTextIndexItem.Property("name"));

            database.CreateIndex("byName", index);

            using (var ftsQuery = QueryBuilder.Select(SelectResult.Expression(Meta.ID).As("id"))
                                  .From(DataSource.Database(database))
                                  .Where(FullTextExpression.Index("byName").Match("'buy'"))) {
                var ftsRows = ftsQuery.Execute();
                foreach (var row in ftsRows)
                {
                    var doc = database.GetDocument(row.GetString("id")); // Use alias instead of index
                    Console.WriteLine(
                        $"document properties {JsonConvert.SerializeObject(doc.ToDictionary(), Formatting.Indented)}");
                }
            }

            // create conflict

            /*
             * 1. Create a document twice with the same ID (the document will have two conflicting revisions).
             * 2. Upon saving the second revision, the ExampleConflictResolver's resolve method is called.
             * The `theirs` ReadOnlyDocument in the conflict resolver represents the current rev and `mine` is what's being saved.
             * 3. Read the document after the second save operation and verify its property is as expected.
             * The conflict resolver will have deleted the obsolete revision.
             */
            using (var theirs = new MutableDocument("buzz"))
                using (var mine = new MutableDocument("buzz")) {
                    theirs.SetString("status", "theirs");
                    mine.SetString("status", "mine");
                    database.Save(theirs);
                    database.Save(mine);
                }

            var conflictResolverResult = database.GetDocument("buzz");

            Console.WriteLine($"conflictResolverResult doc.status ::: {conflictResolverResult.GetString("status")}");

            // replication (Note: Linux / Mac requires .NET Core 2.0+ due to
            // https://github.com/dotnet/corefx/issues/8768)

            /*
             * Tested with SG 1.5 https://www.couchbase.com/downloads
             * Config file:
             * {
             *        "databases": {
             *          "db": {
             *            "server":"walrus:",
             *            "users": {
             *              "GUEST": {"disabled": false, "admin_channels": ["*"]}
             *            },
             *            "unsupported": {
             *              "replicator_2":true
             *            }
             *          }
             *        }
             *      }
             */
            var url         = new Uri("ws://localhost:4984/db");
            var replConfig  = new ReplicatorConfiguration(database, new URLEndpoint(url));
            var replication = new Replicator(replConfig);

            replication.Start();

            // replication change listener
            replication.AddChangeListener((sender, e) => {
                if (e.Status.Activity == ReplicatorActivityLevel.Stopped)
                {
                    Console.WriteLine("Replication has completed.");
                }
            });

            Console.ReadLine();

            // This is important to do because otherwise the native connection
            // won't be released until the next garbage collection
            query.Dispose();
            database.Dispose();
        }
Example #23
0
        static void Main(string[] args)
        {
            // Get the database (and create it if it doesn't exist)
            var database = new Database("mydb");
            // Create a new document (i.e. a record) in the database
            string id = null;

            using (var mutableDoc = new MutableDocument())
            {
                mutableDoc.SetFloat("version", 2.0f)
                .SetString("type", "SDK");

                // Save it to the database
                database.Save(mutableDoc);
                id = mutableDoc.Id;
            }

            // Update a document
            using (var doc = database.GetDocument(id))
                using (var mutableDoc = doc.ToMutable())
                {
                    mutableDoc.SetString("language", "python");
                    database.Save(mutableDoc);

                    using (var docAgain = database.GetDocument(id))
                    {
                        Console.WriteLine($"Document ID :: {docAgain.Id}");
                        Console.WriteLine($"Learning {docAgain.GetString("language")}");
                    }
                }

            // Create a query to fetch documents of type SDK
            // i.e. SELECT * FROM database WHERE type = "SDK"
            using (var query = QueryBuilder.Select(SelectResult.All())
                               .From(DataSource.Database(database))
                               .Where(Expression.Property("type").EqualTo(Expression.String("SDK"))))
            {
                // Run the query
                var result = query.Execute();
                Console.WriteLine($"Number of rows :: {result.Count()}");
            }


            using (var query = QueryBuilder.Select(
                       SelectResult.Expression(Meta.ID),
                       SelectResult.Property("language"))
                               .From(DataSource.Database(database)))
            {
                foreach (var result in query.Execute())
                {
                    Console.WriteLine($"Document Name :: {result.GetString("language")}");
                }
            }

            // Create replicator to push and pull changes to and from the cloud
            var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/getting-started-db"));
            var replConfig     = new ReplicatorConfiguration(database, targetEndpoint);

            // Add authentication
            replConfig.Authenticator = new BasicAuthenticator("john", "pass");

            // Create replicator (make sure to add an instance or static variable
            // named _Replicator)
            var _Replicator = new Replicator(replConfig);

            _Replicator.AddChangeListener((sender, args) =>
            {
                if (args.Status.Error != null)
                {
                    Console.WriteLine($"Error :: {args.Status.Error}");
                }
            });
            //Path.Combine(AppContext.BaseDirectory, "CouchbaseLite");
            _Replicator.Start();
        }
Example #24
0
    void Start()
    {
        Database.SetLogLevel(LogDomain.All, LogLevel.Verbose);

        // Get the database (and create it if it doesn't exist)
        database = new Database(databaseName, new DatabaseConfiguration()
        {
            Directory = Path.Combine(Application.persistentDataPath, "CouchBase")
        });

        // Create a new document (i.e. a record) in the database
        string id = null;

        using (MutableDocument mutableDoc = new MutableDocument("meta")) {
            mutableDoc.SetFloat("version", 2.0f)
            .SetString("type", "SDK");

            // Save it to the database
            database.Save(mutableDoc);
            id = mutableDoc.Id;
        }

        statusLabel.text += "\n- Saved meta doc";

        // Update a document
        using (Document doc = database.GetDocument("meta"))
            using (MutableDocument mutableDoc = doc.ToMutable()) {
                mutableDoc.SetFloat("version", 2.0f);
                database.Save(mutableDoc);

                using (Document docAgain = database.GetDocument("meta")) {
                    Debug.Log($"Document ID :: {docAgain.Id}");
                    Debug.Log($"Version {docAgain.GetFloat("version")}");
                    statusLabel.text += $"\n- Retrieved: {docAgain.Id}";
                }
            }

        // Create a query to fetch documents of type SDK
        // i.e. SELECT * FROM database WHERE type = "SDK"
        using (IWhere query = QueryBuilder.Select(SelectResult.All())
                              .From(DataSource.Database(database))
                              .Where(Expression.Property("version").EqualTo(Expression.Float(2.0f)))) {
            // Run the query
            IResultSet result = query.Execute();
            int        count  = result.AllResults().Count;
            Debug.Log($"Number of rows :: {count}");
            statusLabel.text += $"\n- Query result: {count}";
        }

#if UNITY_EDITOR
        Debug.LogWarning("CouchBase: In Unity Editor – Not replicating!");
        return;
#endif
        // Create replicator to push and pull changes to and from the cloud
        // NOTE: if Continuous is set to true, make sure to stop it and to clean up everything before exiting the application!
        URLEndpoint             targetEndpoint = new URLEndpoint(new Uri(syncUrl));
        ReplicatorConfiguration replConfig     = new ReplicatorConfiguration(database, targetEndpoint)
        {
            // Add authentication
            Authenticator  = new BasicAuthenticator(username, password),
            ReplicatorType = ReplicatorType.PushAndPull,
            Continuous     = false
        };

        // Create replicator
        replicator = new Replicator(replConfig);
        replicator.AddChangeListener((sender, args) => {
            if (args.Status.Error != null)
            {
                Debug.Log($"Error :: {args.Status.Error}");
            }
            else
            {
                if (replicator.Status.Activity != ReplicatorActivityLevel.Busy && replicator.Status.Activity != ReplicatorActivityLevel.Connecting)
                {
                    syncing = false;
                    Debug.Log($"Done syncing: {replicator.Status.Activity}");
                    doneSyncing = true;
                }
                else
                {
                    Debug.Log($"Progress: {args.Status.Progress.Completed} / {args.Status.Progress.Total}");
                }
            }
        });

        Debug.Log("Starting syncing...");
        statusLabel.text += "\n- Starting syncing...";
        replicator.Start();

        syncing = true;
        // Later, stop and dispose the replicator *before* closing/disposing the database
    }
Example #25
0
        public void TestP2PPassiveCloseAll()
        {
            using (var doc = new MutableDocument("test"))
            {
                doc.SetString("name", "Smokey");
                Db.Save(doc);
            }

            var listener          = new MessageEndpointListener(new MessageEndpointListenerConfiguration(OtherDb, ProtocolType.MessageStream));
            var serverConnection1 = new MockServerConnection(listener, ProtocolType.MessageStream);
            var serverConnection2 = new MockServerConnection(listener, ProtocolType.MessageStream);
            var closeWait1        = new ManualResetEventSlim();
            var closeWait2        = new ManualResetEventSlim();
            var errorLogic        = new ReconnectErrorLogic();
            var config            = new ReplicatorConfiguration(Db,
                                                                new MessageEndpoint("p2ptest1", serverConnection1, ProtocolType.MessageStream,
                                                                                    new MockConnectionFactory(errorLogic)))
            {
                Continuous = true
            };

            var config2 = new ReplicatorConfiguration(Db,
                                                      new MessageEndpoint("p2ptest2", serverConnection2, ProtocolType.MessageStream,
                                                                          new MockConnectionFactory(errorLogic)))
            {
                Continuous = true
            };

            using (var replicator = new Replicator(config))
                using (var replicator2 = new Replicator(config2))
                {
                    EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) =>
                    {
                        if (args.Status.Activity == ReplicatorActivityLevel.Stopped)
                        {
                            if (sender == replicator)
                            {
                                closeWait1.Set();
                            }
                            else
                            {
                                closeWait2.Set();
                            }
                        }
                    };

                    replicator.AddChangeListener(changeListener);
                    replicator2.AddChangeListener(changeListener);
                    replicator.Start();
                    replicator2.Start();

                    errorLogic.ErrorActive = true;
                    listener.CloseAll();

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

                    replicator.Status.Error.Should()
                    .NotBeNull("because closing the passive side creates an error on the active one");
                    replicator2.Status.Error.Should()
                    .NotBeNull("because closing the passive side creates an error on the active one");
                }

            closeWait1.Dispose();
            closeWait2.Dispose();
        }