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(); }
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}"); } }
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(); }
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); } } }
/// <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); } }
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); }
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[] }
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[] }
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(); }
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(); }
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 }
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(); }