public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf)
        {
            var id = Guid.NewGuid();

            using (var sqlConnection = new SqliteConnection($"Data Source={fixture.ClientSqliteDb}"))
            {
                var script = $@"INSERT INTO ServiceTickets 
                            (ServiceTicketID, Title, Description, StatusValue, EscalationLevel, Opened, Closed, CustomerID) 
                            VALUES 
                            (@pk, 'Line for conflict', 'Description client', 1, 0, datetime('now'), NULL, 1)";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.Add(new SqliteParameter("pk", id));
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.Configuration = conf;
            agent.Configuration.Add(fixture.Tables);
            var session = await agent.SynchronizeAsync();

            //just check, even if it's not the real test :)
            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(0, session.TotalSyncConflicts);


            using (var sqlConnection = new SqliteConnection($"Data Source={fixture.ClientSqliteDb}"))
            {
                var script = $@"Update ServiceTickets 
                                Set Title = 'Updated from Client'
                                Where ServiceTicketId = @pk";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.Add(new SqliteParameter("pk", id));
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Update ""ServiceTickets"" 
                                Set ""Title"" = 'Updated from Server'
                                Where ""ServiceTicketID"" = '{id}'";

                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.ApplyChangedFailed += (s, args) => args.Action = ConflictAction.ClientWins;

            await Assert.RaisesAsync <ApplyChangeFailedEventArgs>(
                h => agent.ApplyChangedFailed += h,
                h => agent.ApplyChangedFailed -= h, async() =>
            {
                session = await agent.SynchronizeAsync();
            });

            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(1, session.TotalSyncConflicts);

            string expectedRes = string.Empty;

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select ""Title"" from ""ServiceTickets"" Where ""ServiceTicketID""='{id}'";

                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Updated from Client", expectedRes);
        }
        public async Task ConflictInsertInsertConfigurationClientWins(SyncConfiguration conf)
        {
            Guid id = Guid.NewGuid();

            using (var sqlConnection = new SqliteConnection($"Data Source={fixture.ClientSqliteDb}"))
            {
                var script = $@"INSERT INTO ServiceTickets 
                            (ServiceTicketID, Title, Description, StatusValue, EscalationLevel, Opened, Closed, CustomerID) 
                            VALUES 
                            (@pk, 'Conflict Line Client', 'Description client', 1, 0, datetime('now'), NULL, 1)";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.Add(new SqliteParameter("pk", id));
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"INSERT INTO ""ServiceTickets"" 
                            (""ServiceTicketID"", ""Title"", ""Description"", ""StatusValue"", ""EscalationLevel"", ""Opened"", ""Closed"", ""CustomerID"") 
                            VALUES 
                            ('{id.ToString()}', 'Conflict Line Server', 'Description client', 1, 0, now(), NULL, 1)";

                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.Configuration = conf;
            agent.Configuration.Add(fixture.Tables);
            agent.Configuration.ConflictResolutionPolicy = ConflictResolutionPolicy.ClientWins;
            var session = await agent.SynchronizeAsync();

            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(1, session.TotalSyncConflicts);

            string expectedRes = string.Empty;

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select ""Title"" from ""ServiceTickets"" Where ""ServiceTicketID""='{id.ToString()}'";

                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Conflict Line Client", expectedRes);
        }
Example #3
0
 public SyncServiceConflictEventArgs(SyncConfiguration configuration, MetadataItem item, ItemStatus status)
 {
     Configuration = configuration;
     Item          = item;
     NewStatus     = status;
 }
Example #4
0
        public async Task ConflictInsertInsertConfigurationClientWins(SyncConfiguration conf)
        {
            Guid id = Guid.NewGuid();

            using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString))
            {
                var script = $@"INSERT [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            (N'{id.ToString()}', N'Conflict Line Client', N'Description client', 1, 0, getdate(), NULL, 1)";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"INSERT [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            (N'{id.ToString()}', N'Conflict Line Server', N'Description client', 1, 0, getdate(), NULL, 1)";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var server = new KestrellTestServer())
            {
                var serverHandler = new RequestDelegate(async context =>
                {
                    conf.Tables = fixture.Tables;
                    conf.ConflictResolutionPolicy = ConflictResolutionPolicy.ClientWins;

                    serverProvider.SetConfiguration(conf);
                    proxyServerProvider.SerializationFormat = conf.SerializationFormat;

                    await proxyServerProvider.HandleRequestAsync(context);
                });
                var clientHandler = new ResponseDelegate(async(serviceUri) =>
                {
                    proxyClientProvider.ServiceUri          = new Uri(serviceUri);
                    proxyClientProvider.SerializationFormat = conf.SerializationFormat;

                    var session = await agent.SynchronizeAsync();

                    // check statistics
                    Assert.Equal(0, session.TotalChangesDownloaded);
                    Assert.Equal(1, session.TotalChangesUploaded);
                    Assert.Equal(1, session.TotalSyncConflicts);
                });
                await server.Run(serverHandler, clientHandler);
            }


            string expectedRes = string.Empty;

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id.ToString()}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Conflict Line Client", expectedRes);
        }
Example #5
0
        public async Task <ProviderRun> RunAsync(CoreProvider serverProvider,
                                                 ProviderFixture <CoreProvider> serverFixture,
                                                 string scopeName       = null, string[] tables = null,
                                                 SyncConfiguration conf = null,
                                                 bool reuseAgent        = true)
        {
            // server proxy
            var proxyServerProvider = new WebProxyServerProvider(serverProvider);
            var proxyClientProvider = new WebProxyClientProvider();

            var syncTables = tables ?? serverFixture.Tables;

            // local test, through tcp
            if (this.NetworkType == NetworkType.Tcp)
            {
                // create agent
                if (this.Agent == null || !reuseAgent)
                {
                    this.Agent = new SyncAgent(this.ClientProvider, serverProvider, syncTables);
                }

                // copy conf settings
                if (conf != null)
                {
                    serverFixture.CopyConfiguration(this.Agent.Configuration, conf);
                }

                // Add Filers
                if (serverFixture.Filters != null && serverFixture.Filters.Count > 0)
                {
                    serverFixture.Filters.ForEach(f =>
                    {
                        if (!this.Agent.Configuration.Filters.Contains(f))
                        {
                            this.Agent.Configuration.Filters.Add(f);
                        }
                    });
                }

                // Add Filers values
                if (serverFixture.FilterParameters != null && serverFixture.FilterParameters.Count > 0)
                {
                    foreach (var syncParam in serverFixture.FilterParameters)
                    {
                        if (!this.Agent.Parameters.Contains(syncParam))
                        {
                            this.Agent.Parameters.Add(syncParam);
                        }
                    }
                }

                // sync
                try
                {
                    this.BeginRun?.Invoke(this.Agent.RemoteProvider);
                    this.Results = await this.Agent.SynchronizeAsync();

                    this.EndRun?.Invoke(this.Agent.RemoteProvider);
                }
                catch (Exception ex)
                {
                    this.Exception = ex;
                    Console.WriteLine(ex);
                }
            }

            // -----------------------------------------------------------------------
            // HTTP
            // -----------------------------------------------------------------------

            // tests through http proxy
            if (this.NetworkType == NetworkType.Http)
            {
                // client handler
                using (var server = new KestrellTestServer())
                {
                    // server handler
                    var serverHandler = new RequestDelegate(async context =>
                    {
                        var syncConfiguration = new SyncConfiguration(syncTables);// set proxy conf
                        // copy conf settings

                        if (conf != null)
                        {
                            serverFixture.CopyConfiguration(syncConfiguration, conf);
                        }


                        // set proxy conf
                        proxyServerProvider.Configuration = syncConfiguration;

                        // test if <> directory name works
                        proxyServerProvider.Options = new SyncOptions();
                        proxyServerProvider.Options.BatchDirectory = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "server");

                        // Add Filers
                        if (serverFixture.Filters != null && serverFixture.Filters.Count > 0)
                        {
                            serverFixture.Filters.ForEach(f =>
                            {
                                if (!proxyServerProvider.Configuration.Filters.Contains(f))
                                {
                                    proxyServerProvider.Configuration.Filters.Add(f);
                                }
                            });
                        }


                        // sync
                        try
                        {
                            this.BeginRun?.Invoke(proxyServerProvider.LocalProvider);
                            await proxyServerProvider.HandleRequestAsync(context);
                            this.EndRun?.Invoke(proxyServerProvider.LocalProvider);
                        }
                        catch (Exception ew)
                        {
                            Console.WriteLine(ew);
                        }
                    });

                    var clientHandler = new ResponseDelegate(async(serviceUri) =>
                    {
                        // create agent
                        if (this.Agent == null || !reuseAgent)
                        {
                            this.Agent = new SyncAgent(this.ClientProvider, proxyClientProvider);
                        }

                        if (serverFixture.FilterParameters != null && serverFixture.FilterParameters.Count > 0)
                        {
                            foreach (var syncParam in serverFixture.FilterParameters)
                            {
                                if (!this.Agent.Parameters.Contains(syncParam))
                                {
                                    this.Agent.Parameters.Add(syncParam);
                                }
                            }
                        }

                        ((WebProxyClientProvider)this.Agent.RemoteProvider).ServiceUri = new Uri(serviceUri);

                        try
                        {
                            this.Results = await this.Agent.SynchronizeAsync();
                        }
                        catch (Exception ew)
                        {
                            this.Exception = ew;
                            Console.WriteLine(ew);
                        }
                    });
                    await server.Run(serverHandler, clientHandler);
                }
            }
            return(this);
        }
Example #6
0
        public override IEnumerable <ADRawEntry> GetDataPage()
        {
            ExTraceGlobals.TenantRelocationTracer.TraceDebug((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration GetDataPage ...");
            WatermarkMap watermarks         = SyncConfiguration.GetReplicationCursors(base.RootOrgConfigurationSession);
            WatermarkMap configNcWatermarks = SyncConfiguration.GetReplicationCursors(base.RootOrgConfigurationSession, true, false);
            string       dcName             = base.RootOrgConfigurationSession.DomainController;

            ExTraceGlobals.TenantRelocationTracer.TraceDebug <string>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration dcName {0}", dcName);
            base.TenantConfigurationSession.DomainController = dcName;
            base.RecipientSession.DomainController           = dcName;
            Guid watermarksInvocationId = base.RootOrgConfigurationSession.GetInvocationIdByFqdn(dcName);

            ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration watermarksInvocationId {0}", watermarksInvocationId);
            long maxUsn = watermarks[watermarksInvocationId];

            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration maxUsn {0}", maxUsn);
            this.PageToken.IsTenantConfigUnitInConfigNc = !ADSession.IsTenantConfigInDomainNC(base.RecipientSession.SessionSettings.GetAccountOrResourceForestFqdn());
            if (this.PageToken.InvocationId == Guid.Empty)
            {
                this.PageToken.SetInvocationId(watermarksInvocationId, dcName);
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.InvocationId to {0}", this.PageToken.InvocationId);
            }
            this.moreDataForThisPage = true;
            while (this.ShouldReadMoreData())
            {
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <string>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.State = {0}", this.PageToken.State.ToString());
                switch (this.PageToken.State)
                {
                case TenantRelocationSyncState.PreSyncAllObjects:
                    if (this.PageToken.PreSyncLdapPagingCookie == null)
                    {
                        this.PageToken.PendingConfigNcWatermarks     = configNcWatermarks;
                        this.PageToken.PendingWatermarks             = watermarks;
                        this.PageToken.PendingWatermarksInvocationId = watermarksInvocationId;
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.PendingWatermarksInvocationId to {0}", this.PageToken.PendingWatermarksInvocationId);
                    }
                    foreach (ADRawEntry entry in this.PreSyncAllObjects())
                    {
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration PreSyncAllObjects yield {0}", entry.Id);
                        yield return(entry);
                    }
                    break;

                case TenantRelocationSyncState.EnumerateConfigUnitLiveObjects:
                    foreach (ADRawEntry entry2 in this.ReadLiveObjects(maxUsn))
                    {
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateConfigUnitLiveObjects yield {0}", entry2.Id);
                        yield return(entry2);
                    }
                    this.PageToken.PendingWatermarksInvocationId = watermarksInvocationId;
                    ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.PendingWatermarksInvocationId to {0}", this.PageToken.PendingWatermarksInvocationId);
                    if (this.PageToken.IsTenantConfigUnitInConfigNc)
                    {
                        this.PageToken.PendingConfigNcWatermarks = configNcWatermarks;
                    }
                    else
                    {
                        this.PageToken.PendingWatermarks = watermarks;
                    }
                    break;

                case TenantRelocationSyncState.EnumerateConfigUnitLinksInPage:
                    ExTraceGlobals.TenantRelocationTracer.TraceDebug((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateConfigUnitLinksInPage skips");
                    this.PageToken.SwitchToEnumerateLiveObjectsState();
                    break;

                case TenantRelocationSyncState.EnumerateOrganizationalUnitLiveObjects:
                    foreach (ADRawEntry entry3 in this.ReadLiveObjects(maxUsn))
                    {
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateOrganizationalUnitLiveObjects yield {0}", entry3.Id);
                        yield return(entry3);
                    }
                    if (this.PageToken.IsTenantConfigUnitInConfigNc)
                    {
                        this.PageToken.PendingWatermarksInvocationId = watermarksInvocationId;
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.PendingWatermarksInvocationId to {0}", this.PageToken.PendingWatermarksInvocationId);
                        this.PageToken.PendingWatermarks = watermarks;
                    }
                    break;

                case TenantRelocationSyncState.EnumerateOrganizationalUnitLinksInPage:
                    ExTraceGlobals.TenantRelocationTracer.TraceDebug((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateConfigUnitLinksInPage skips");
                    this.PageToken.SwitchToEnumerateLiveObjectsState();
                    break;

                case TenantRelocationSyncState.EnumerateConfigUnitDeletedObjects:
                    foreach (ADRawEntry entry4 in this.ReadDeletedObjects())
                    {
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateConfigUnitDeletedObjects yield {0}", entry4.Id);
                        yield return(entry4);
                    }
                    break;

                case TenantRelocationSyncState.EnumerateOrganizationalUnitDeletedObjects:
                    if (!this.PageToken.IsTenantConfigUnitInConfigNc)
                    {
                        this.PageToken.SwitchToNextState();
                    }
                    else
                    {
                        foreach (ADRawEntry entry5 in this.ReadDeletedObjects())
                        {
                            ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateOrganizationalUnitDeletedObjects yield {0}", entry5.Id);
                            yield return(entry5);
                        }
                    }
                    break;

                case TenantRelocationSyncState.EnumerateSpecialObjects:
                    foreach (ADRawEntry entry6 in this.ReadSpecialObjects())
                    {
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <ADObjectId>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration EnumerateSpecialObjects yield {0}", entry6.Id);
                        yield return(entry6);
                    }
                    if (!this.PageToken.IsTenantConfigUnitInConfigNc)
                    {
                        this.PageToken.PendingWatermarksInvocationId = watermarksInvocationId;
                        ExTraceGlobals.TenantRelocationTracer.TraceDebug <Guid>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.PendingWatermarksInvocationId to {0}", this.PageToken.PendingWatermarksInvocationId);
                        this.PageToken.PendingConfigNcWatermarks = configNcWatermarks;
                    }
                    this.PageToken.SwitchToNextState();
                    break;

                default:
                    ExTraceGlobals.TenantRelocationTracer.TraceError <string>((long)SyncConfiguration.TraceId, "Invalid PageToken stat {0}", this.PageToken.State.ToString());
                    throw new ArgumentException(this.PageToken.State.ToString());
                }
            }
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.OrganizationalUnitObjectUSN = {0}", this.PageToken.OrganizationalUnitObjectUSN);
            if (this.PageToken.OrganizationalUnitObjectUSN > maxUsn + 1L)
            {
                this.PageToken.OrganizationalUnitObjectUSN = maxUsn + 1L;
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.OrganizationalUnitObjectUSN to {0}", this.PageToken.OrganizationalUnitObjectUSN);
            }
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.OrganizationalUnitTombstoneUSN = {0}", this.PageToken.OrganizationalUnitTombstoneUSN);
            if (this.PageToken.OrganizationalUnitTombstoneUSN > maxUsn + 1L)
            {
                this.PageToken.OrganizationalUnitTombstoneUSN = maxUsn + 1L;
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.OrganizationalUnitTombstoneUSN to {0}", this.PageToken.OrganizationalUnitTombstoneUSN);
            }
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.ConfigUnitObjectUSN = {0}", this.PageToken.ConfigUnitObjectUSN);
            if (this.PageToken.ConfigUnitObjectUSN > maxUsn + 1L)
            {
                this.PageToken.ConfigUnitObjectUSN = maxUsn + 1L;
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.ConfigUnitObjectUSN = {0}", this.PageToken.ConfigUnitObjectUSN);
            }
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.ConfigUnitTombstoneUSN = {0}", this.PageToken.ConfigUnitTombstoneUSN);
            if (this.PageToken.ConfigUnitTombstoneUSN > maxUsn + 1L)
            {
                this.PageToken.ConfigUnitTombstoneUSN = maxUsn + 1L;
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.ConfigUnitTombstoneUSN = {0}", this.PageToken.ConfigUnitTombstoneUSN);
            }
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.SpecialObjectsUSN = {0}", this.PageToken.SpecialObjectsUSN);
            if (this.PageToken.SpecialObjectsUSN > maxUsn + 1L)
            {
                this.PageToken.SpecialObjectsUSN = maxUsn + 1L;
                ExTraceGlobals.TenantRelocationTracer.TraceDebug <long>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration this.PageToken.SpecialObjectsUSN = {0}", this.PageToken.SpecialObjectsUSN);
            }
            this.PageToken.LastReadFailureStartTime = DateTime.MinValue;
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.LastReadFailureStartTime to {0}", this.PageToken.LastReadFailureStartTime);
            this.PageToken.Timestamp = DateTime.UtcNow;
            ExTraceGlobals.TenantRelocationTracer.TraceDebug <DateTime>((long)SyncConfiguration.TraceId, "TenantRelocationSyncConfiguration set this.PageToken.Timestamp to {0}", this.PageToken.Timestamp);
            yield break;
        }
Example #7
0
        public async Task ConflictInsertInsertConfigurationClientWins(SyncConfiguration conf)
        {
            Guid id = Guid.NewGuid();

            using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString))
            {
                var script = $@"INSERT INTO [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            (@id, 'Conflict Line Client', 'Description client', 1, 0, datetime('now'), NULL, 1)";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.AddWithValue("@id", id);

                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"INSERT [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            ('{id.ToString()}', 'Conflict Line Server', 'Description client', 1, 0, getdate(), NULL, 1)";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.Configuration.DownloadBatchSizeInKB = conf.DownloadBatchSizeInKB;
            agent.Configuration.UseBulkOperations     = conf.UseBulkOperations;
            agent.Configuration.SerializationFormat   = conf.SerializationFormat;
            agent.Configuration.Add(fixture.Tables);
            agent.Configuration.ConflictResolutionPolicy = ConflictResolutionPolicy.ClientWins;
            var session = await agent.SynchronizeAsync();

            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(1, session.TotalSyncConflicts);

            string expectedRes = string.Empty;

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id.ToString()}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Conflict Line Client", expectedRes);
        }
Example #8
0
        internal SyncContext Sync(string value)
        {
            if (String.IsNullOrEmpty(value))
            {
                throw new Exception("Loading a project requires a name. Ex : dotnet sync --load project01");
            }

            Project project = DataStore.Current.LoadProject(value);

            if (project == null)
            {
                throw new Exception($"Project {value} does not exists.");
            }

            if (project.ServerProvider == null || string.IsNullOrEmpty(project.ServerProvider.ConnectionString))
            {
                throw new Exception($"Server provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help");
            }

            if (project.ClientProvider == null || string.IsNullOrEmpty(project.ClientProvider.ConnectionString))
            {
                throw new Exception($"Client provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help");
            }

            if (project.ServerProvider.ProviderType != ProviderType.Web && (project.Tables == null || project.Tables.Count <= 0))
            {
                throw new Exception($"No table configured for project {project.Name}. See help: dotnet sync table --help");
            }

            IProvider serverProvider, clientprovider;

            switch (project.ServerProvider.ProviderType)
            {
            case ProviderType.Sqlite:
                throw new Exception("Can't use Sqlite as a server provider");

            case ProviderType.Web:
                serverProvider = new WebProxyClientProvider(new Uri(project.ServerProvider.ConnectionString));
                break;

            case ProviderType.MySql:
                serverProvider = new MySqlSyncProvider(project.ServerProvider.ConnectionString);
                break;

            case ProviderType.SqlServer:
            default:
                serverProvider = new SqlSyncProvider(project.ServerProvider.ConnectionString);
                break;
            }

            switch (project.ClientProvider.ProviderType)
            {
            case ProviderType.Web:
                throw new Exception("Web proxy is used as a proxy server. You have to use an ASP.NET web backend. CLI uses a proxy as server provider");

            case ProviderType.Sqlite:
                clientprovider = new SqliteSyncProvider(project.ClientProvider.ConnectionString);
                break;

            case ProviderType.MySql:
                clientprovider = new MySqlSyncProvider(project.ClientProvider.ConnectionString);
                break;

            case ProviderType.SqlServer:
            default:
                clientprovider = new SqlSyncProvider(project.ClientProvider.ConnectionString);
                break;
            }

            SyncAgent agent = null;

            if (project.ServerProvider.ProviderType != ProviderType.Web)
            {
                agent = new SyncAgent(clientprovider, serverProvider);

                SyncConfiguration syncConfiguration = agent.Configuration;

                foreach (var t in project.Tables.OrderBy(tbl => tbl.Order))
                {
                    // Potentially user can pass something like [SalesLT].[Product]
                    // or SalesLT.Product or Product. ObjectNameParser will handle it
                    ObjectNameParser parser = new ObjectNameParser(t.Name);

                    var tableName = parser.ObjectName;
                    var schema    = string.IsNullOrEmpty(t.Schema) ? parser.SchemaName : t.Schema;

                    var dmTable = new DmTable(tableName);

                    if (!String.IsNullOrEmpty(schema))
                    {
                        dmTable.Schema = schema;
                    }

                    dmTable.SyncDirection = t.Direction;

                    syncConfiguration.Add(dmTable);
                }

                syncConfiguration.BatchDirectory           = string.IsNullOrEmpty(project.Configuration.BatchDirectory) ? null : project.Configuration.BatchDirectory;
                syncConfiguration.SerializationFormat      = project.Configuration.SerializationFormat;
                syncConfiguration.UseBulkOperations        = project.Configuration.UseBulkOperations;
                syncConfiguration.DownloadBatchSizeInKB    = (int)Math.Min(Int32.MaxValue, project.Configuration.DownloadBatchSizeInKB);
                syncConfiguration.ConflictResolutionPolicy = project.Configuration.ConflictResolutionPolicy;
            }
            else
            {
                agent = new SyncAgent(clientprovider, serverProvider);
            }


            agent.TableChangesSelected += (sender, a) =>
                                          Console.WriteLine($"Changes selected for table {a.TableChangesSelected.TableName}: {a.TableChangesSelected.TotalChanges}");

            agent.TableChangesApplied += (sender, a) =>
                                         Console.WriteLine($"Changes applied for table {a.TableChangesApplied.TableName}: [{a.TableChangesApplied.State}] {a.TableChangesApplied.Applied}");

            // synchronous call
            var syncContext = agent.SynchronizeAsync().GetAwaiter().GetResult();

            var tsEnded   = TimeSpan.FromTicks(syncContext.CompleteTime.Ticks);
            var tsStarted = TimeSpan.FromTicks(syncContext.StartTime.Ticks);

            var durationTs  = tsEnded.Subtract(tsStarted);
            var durationstr = $"{durationTs.Hours}:{durationTs.Minutes}:{durationTs.Seconds}.{durationTs.Milliseconds}";

            Console.ForegroundColor = ConsoleColor.Green;
            var s = $"Synchronization done. " + Environment.NewLine +
                    $"\tTotal changes downloaded: {syncContext.TotalChangesDownloaded} " + Environment.NewLine +
                    $"\tTotal changes uploaded: {syncContext.TotalChangesUploaded}" + Environment.NewLine +
                    $"\tTotal duration :{durationstr} ";

            Console.WriteLine(s);
            Console.ResetColor();


            return(syncContext);
        }
Example #9
0
        private static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=sarasa;User Id=sa;Password=1234;Connect Timeout=120"))
            {
                SqlCommand cmd = new SqlCommand(@"
                    SELECT * FROM notes WHERE note.language = 'es'"
                                                , conn);

                List <SyncArrayConfiguration> arrayConfig = new List <SyncArrayConfiguration>()
                {
                    new SyncArrayConfiguration
                    {
                        SqlCommand = new SqlCommand(@"
                            SELECT id_object AS '_id', id, description, languageId
                            FROM dbo.Tags
                            WHERE languageId = 'es'"
                                                    , conn),
                        AttributeName = "tags"
                    },
                    new SyncArrayConfiguration
                    {
                        SqlCommand = new SqlCommand(@"
                            SELECT id_object AS '_id', id, description, xmlData, languageId
                            FROM dbo.Categories
                            WHERE languageId = 'es'"
                                                    , conn),
                        AttributeName = "categories",
                        XmlFields     = new string[] { "xmlData" }
                    }
                };

                SyncDeleteConfiguration deleteCmd = new SyncDeleteConfiguration
                {
                    SqlCommand = new SqlCommand(@"
                        SELECT id_object AS '_id', createdOn
                        FROM dbo.DeleteLog
                        WHERE id_language = 'es'"
                                                , conn),
                    ColumnsToCompareWithLastSyncDate = new string[] { "[createdOn]" },
                };

                var nodes =
                    new Uri[] {
                    new Uri("http://localhost:9200"),
                    new Uri("http://localhost:9201")
                };
                var connectionPool = new SniffingConnectionPool(nodes);
                var esConfig       = new ConnectionConfiguration(connectionPool).UsePrettyResponses();

                var syncConfig = new SyncConfiguration()
                {
                    SqlConnection       = conn,
                    SqlCommand          = cmd,
                    ArraysConfiguration = arrayConfig,
                    ColumnsToCompareWithLastSyncDate = new string[] { "[lastupdate]" },
                    DeleteConfiguration        = deleteCmd,
                    ElasticSearchConfiguration = esConfig,
                    BulkSize = 500,
                    _Index   = new Index("sarasa"),
                    _Type    = "notes"
                };

                var sync = new Sync(syncConfig);

                try
                {
                    var response = sync.Exec();
                    if (response.BulkResponses.Any())
                    {
                        foreach (var bulkResponse in response.BulkResponses)
                        {
                            Console.WriteLine("success: " + bulkResponse.Success);
                            Console.WriteLine("http status code: " + bulkResponse.HttpStatusCode);
                            Console.WriteLine("affected documents: " + bulkResponse.AffectedDocuments);
                            Console.WriteLine("started on: " + bulkResponse.StartedOn);
                            Console.WriteLine("bulk duration: " + bulkResponse.Duration + "ms");
                            if (!response.Success)
                            {
                                Console.WriteLine("es original exception: " + bulkResponse.ESexception);
                            }
                            Console.WriteLine("\n");
                        }
                        Console.WriteLine("\nbulk avg duration: " + response.BulkResponses.Average(x => x.Duration) + "ms");
                        Console.WriteLine("\n");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("an error has occurred: " + ex.Message);
                }
                finally
                {
                    Console.WriteLine("Execution has completed. Press any key to continue...");
                    Console.ReadKey();
                }
            }
        }
Example #10
0
        public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf)
        {
            var id = Guid.NewGuid().ToString();

            using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString))
            {
                var script = $@"INSERT INTO [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            (@id, 'Line for conflict', 'Description client', 1, 0, datetime('now'), NULL, 1)";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.AddWithValue("@id", id);

                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.Configuration.DownloadBatchSizeInKB = conf.DownloadBatchSizeInKB;
            agent.Configuration.UseBulkOperations     = conf.UseBulkOperations;
            agent.Configuration.SerializationFormat   = conf.SerializationFormat;
            agent.Configuration.Add(fixture.Tables);
            var session = await agent.SynchronizeAsync();

            //just check, even if it's not the real test :)
            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(0, session.TotalSyncConflicts);


            using (var sqlConnection = new SqliteConnection(fixture.ClientSqliteConnectionString))
            {
                var script = $@"Update [ServiceTickets] 
                                Set Title = 'Updated from Client'
                                Where ServiceTicketId = @id";

                using (var sqlCmd = new SqliteCommand(script, sqlConnection))
                {
                    sqlCmd.Parameters.AddWithValue("@id", id);

                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Update [ServiceTickets] 
                                Set Title = 'Updated from Server'
                                Where ServiceTicketId = '{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.ApplyChangedFailed += (s, args) => args.Action = ConflictAction.ClientWins;

            await Assert.RaisesAsync <ApplyChangeFailedEventArgs>(
                h => agent.ApplyChangedFailed += h,
                h => agent.ApplyChangedFailed -= h, async() =>
            {
                session = await agent.SynchronizeAsync();
            });

            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(1, session.TotalSyncConflicts);

            string expectedRes = string.Empty;

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Updated from Client", expectedRes);
        }
Example #11
0
        public async Task UpdateFromClient(SyncConfiguration conf)
        {
            Guid newId = Guid.NewGuid();

            var insertRowScript =
                $@"INSERT INTO [ServiceTickets] ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                VALUES ('{newId.ToString()}', 'Insert One Row in SQLite client', 'Description Insert One Row', 1, 0, datetime('now'), NULL, 1)";

            using (var sqlConnection = new SQLiteConnection(fixture.ClientSQLiteConnectionString))
            {
                using (var sqlCmd = new SQLiteCommand(insertRowScript, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }
            using (var server = new KestrellTestServer())
            {
                var serverHandler = new RequestDelegate(async context =>
                {
                    conf.Tables = fixture.Tables;
                    serverProvider.SetConfiguration(conf);
                    proxyServerProvider.SerializationFormat = conf.SerializationFormat;

                    await proxyServerProvider.HandleRequestAsync(context);
                });
                var clientHandler = new ResponseDelegate(async(serviceUri) =>
                {
                    proxyClientProvider.ServiceUri          = new Uri(serviceUri);
                    proxyClientProvider.SerializationFormat = conf.SerializationFormat;

                    var session = await agent.SynchronizeAsync();

                    Assert.Equal(0, session.TotalChangesDownloaded);
                    Assert.Equal(1, session.TotalChangesUploaded);
                });
                await server.Run(serverHandler, clientHandler);
            }

            var updateRowScript =
                $@" Update [ServiceTickets] Set [Title] = 'Updated from SQLite Client side !' Where ServiceTicketId = '{newId.ToString()}'";

            using (var sqlConnection = new SQLiteConnection(fixture.ClientSQLiteConnectionString))
            {
                using (var sqlCmd = new SQLiteCommand(updateRowScript, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }
            using (var server = new KestrellTestServer())
            {
                var serverHandler = new RequestDelegate(async context =>
                {
                    conf.Tables = fixture.Tables;
                    serverProvider.SetConfiguration(conf);
                    proxyServerProvider.SerializationFormat = conf.SerializationFormat;

                    await proxyServerProvider.HandleRequestAsync(context);
                });
                var clientHandler = new ResponseDelegate(async(serviceUri) =>
                {
                    proxyClientProvider.ServiceUri          = new Uri(serviceUri);
                    proxyClientProvider.SerializationFormat = conf.SerializationFormat;

                    var session = await agent.SynchronizeAsync();

                    Assert.Equal(0, session.TotalChangesDownloaded);
                    Assert.Equal(1, session.TotalChangesUploaded);
                });
                await server.Run(serverHandler, clientHandler);
            }
        }
Example #12
0
        private bool CheckReplicationStatus(ITopologyConfigurationSession session, WatermarkMap finishWaterMark, bool useConfigNC)
        {
            WatermarkMap replicationCursors = SyncConfiguration.GetReplicationCursors(session, useConfigNC, false);

            return(replicationCursors.ContainsAllChanges(finishWaterMark));
        }
Example #13
0
 public CustomSyncEngine(DatabaseService databaseService, SyncConfiguration syncConfiguration) : base(syncConfiguration)
 {
     this.databaseService    = databaseService;
     customContractResolvers = new Dictionary <Type, CustomContractResolver>();
 }
        public async Task InsertUpdateDeleteFromServer(SyncConfiguration conf)
        {
            Guid insertedId = Guid.NewGuid();
            Guid updatedId  = Guid.NewGuid();
            Guid deletedId  = Guid.NewGuid();


            var script =
                $@"INSERT INTO ""ServiceTickets"" (""ServiceTicketID"", ""Title"", ""Description"", ""StatusValue"", ""EscalationLevel"", ""Opened"", ""Closed"", ""CustomerID"") 
               VALUES ('{updatedId.ToString()}', 'Updated', 'Description', 1, 0, now(), NULL, 1);
               INSERT INTO ""ServiceTickets""(""ServiceTicketID"", ""Title"", ""Description"", ""StatusValue"", ""EscalationLevel"", ""Opened"", ""Closed"", ""CustomerID"") 
               VALUES('{deletedId.ToString()}', 'Deleted', 'Description', 1, 0, now(), NULL, 1)";

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }
            agent.Configuration = conf;
            agent.Configuration.Add(fixture.Tables);
            var session = await agent.SynchronizeAsync();

            Assert.Equal(2, session.TotalChangesDownloaded);
            Assert.Equal(0, session.TotalChangesUploaded);

            script =
                $@"INSERT INTO ""ServiceTickets"" (""ServiceTicketID"", ""Title"", ""Description"", ""StatusValue"", ""EscalationLevel"", ""Opened"", ""Closed"", ""CustomerID"") 
               VALUES ('{insertedId.ToString()}', 'Inserted', 'Description', 1, 0, now(), NULL, 1);
               DELETE FROM ""ServiceTickets"" WHERE ""ServiceTicketID"" = '{deletedId.ToString()}';
               UPDATE ""ServiceTickets"" set ""Description"" = 'Updated again' WHERE  ""ServiceTicketID"" = '{updatedId.ToString()}';";

            using (var sqlConnection = new NpgsqlConnection(fixture.ServerConnectionString))
            {
                using (var sqlCmd = new NpgsqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            int insertApplied = 0;
            int updateApplied = 0;
            int deleteApplied = 0;

            agent.TableChangesApplied += (sender, args) =>
            {
                switch (args.TableChangesApplied.State)
                {
                case Data.DmRowState.Added:
                    insertApplied += args.TableChangesApplied.Applied;
                    break;

                case Data.DmRowState.Modified:
                    updateApplied += args.TableChangesApplied.Applied;
                    break;

                case Data.DmRowState.Deleted:
                    deleteApplied += args.TableChangesApplied.Applied;
                    break;
                }
            };

            session = await agent.SynchronizeAsync();

            Assert.Equal(3, session.TotalChangesDownloaded);
            Assert.Equal(1, insertApplied);
            Assert.Equal(1, updateApplied);
            Assert.Equal(1, deleteApplied);
            Assert.Equal(0, session.TotalChangesUploaded);
        }
Example #15
0
 public CustomSyncEngine(DatabaseContext databaseContext, SyncConfiguration syncConfiguration) : base(syncConfiguration)
 {
     this.databaseContext    = databaseContext;
     customContractResolvers = new Dictionary <Type, CustomContractResolver>();
 }
        public async Task <(SyncContext, SyncConfiguration)> EnsureConfigurationAsync(SyncContext context, SyncConfiguration configuration = null)
        {
            HttpMessage httpMessage = new HttpMessage();

            httpMessage.SyncContext = context;
            httpMessage.Step        = HttpStep.EnsureConfiguration;

            //Post request and get response
            var httpMessageResponse = await this.httpRequestHandler.ProcessRequest(httpMessage, cancellationToken);

            if (httpMessageResponse == null)
            {
                throw new Exception("Can't have an empty body");
            }

            if (httpMessageResponse.EnsureConfiguration == null || httpMessageResponse.EnsureConfiguration.Configuration == null || httpMessageResponse.EnsureConfiguration.ConfigurationSet == null || httpMessageResponse.EnsureConfiguration.ConfigurationSet.Tables.Count <= 0)
            {
                throw new ArgumentException("Configuration can't be null");
            }

            // get config & deserialize set
            var conf = httpMessageResponse.EnsureConfiguration.Configuration;
            var set  = httpMessageResponse.EnsureConfiguration.ConfigurationSet.ConvertToDmSet();

            httpMessageResponse.EnsureConfiguration.ConfigurationSet.Clear();
            httpMessageResponse.EnsureConfiguration.ConfigurationSet.Dispose();
            httpMessageResponse.EnsureConfiguration.ConfigurationSet = null;
            conf.ScopeSet = set;

            // get context
            var syncContext = httpMessageResponse.SyncContext;

            // because we need it after
            this.syncConfiguration = conf;

            return(syncContext, conf);
        }
Example #17
0
        public async System.Threading.Tasks.Task Setup()
        {
            // :code-block-start: initialize-realm
            app = App.Create(myRealmAppId);
            // :code-block-end:
            user = app.LogInAsync(Credentials.EmailPassword("*****@*****.**", "foobar")).Result;
            // :code-block-start: open-synced-realm
            config = new SyncConfiguration("myPart", user);
            //:hide-start:
            config.ObjectClasses = new[]
            {
                typeof(Task),
                typeof(MyClass),
                typeof(dotnet.User),
                typeof(CustomGetterSetter)
            };
            Realm realm;

            //:hide-end:
            try
            {
                realm = await Realm.GetInstanceAsync(config);
            }
            catch (RealmFileAccessErrorException ex)
            {
                Console.WriteLine($@"Error creating or opening the
                    realm file. {ex.Message}");
            }
            //:hide-start:
            realm = await Realm.GetInstanceAsync(config);

            realm.Write(() =>
            {
                realm.RemoveAll <Task>();
            });
            //:hide-end:
            // :code-block-end:
            // :code-block-start: open-synced-realm-sync
            var synchronousRealm = await Realm.GetInstanceAsync(config);

            // :code-block-end:
            // :code-block-start: create
            var testTask = new Task
            {
                Name      = "Do this thing",
                Status    = TaskStatus.Open.ToString(),
                Partition = "myPart"
            };

            realm.Write(() =>
            {
                realm.Add(testTask);
            });
            // :code-block-end:
            testTaskId = testTask.Id;

            /* var schemas = config.ObjectClasses;
             * foreach (var schema in schemas)
             * {
             *   Console.WriteLine(schema.FullName);
             * }*/


            return;
        }
Example #18
0
        public async Task Setup()
        {
            app              = App.Create(myRealmAppId);
            user             = app.LogInAsync(Credentials.EmailPassword("*****@*****.**", "foobar")).Result;
            config           = new SyncConfiguration("myPart", user);
            mongoClient      = user.GetMongoClient("mongodb-atlas");
            dbPlantInventory = mongoClient.GetDatabase("inventory");
            plantsCollection = dbPlantInventory.GetCollection <Plant>("plants");

            venus = new Plant
            {
                Name      = "Venus Flytrap",
                Sunlight  = Sunlight.Full,
                Color     = PlantColor.White,
                Type      = PlantType.Perennial,
                Partition = "Store 42"
            };
            sweetBasil = new Plant
            {
                Name      = "Sweet Basil",
                Sunlight  = Sunlight.Partial,
                Color     = PlantColor.Green,
                Type      = PlantType.Annual,
                Partition = "Store 42"
            };
            thaiBasil = new Plant
            {
                Name      = "Thai Basil",
                Sunlight  = Sunlight.Partial,
                Color     = PlantColor.Green,
                Type      = PlantType.Perennial,
                Partition = "Store 42"
            };
            helianthus = new Plant
            {
                Name      = "Helianthus",
                Sunlight  = Sunlight.Full,
                Color     = PlantColor.Yellow,
                Type      = PlantType.Annual,
                Partition = "Store 42"
            };
            petunia = new Plant
            {
                Name      = "Petunia",
                Sunlight  = Sunlight.Full,
                Color     = PlantColor.Purple,
                Type      = PlantType.Annual,
                Partition = "Store 47"
            };

            var listofPlants = new List <Plant>
            {
                venus,
                sweetBasil,
                thaiBasil,
                helianthus,
                petunia
            };

            var insertResult = await plantsCollection.InsertManyAsync(listofPlants);



            return;
        }
Example #19
0
    private static async Task TestSyncSQLite()
    {
        // Get SQL Server connection string
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

        configurationBuilder.AddJsonFile("config.json", true);
        IConfiguration Configuration = configurationBuilder.Build();
        var            serverConfig  = Configuration["AppConfiguration:ServerConnectionString"];
        var            clientConfig  = Configuration["AppConfiguration:ClientSQLiteConnectionString"];

        SqlSyncProvider    serverProvider = new SqlSyncProvider(serverConfig);
        SQLiteSyncProvider clientProvider = new SQLiteSyncProvider(clientConfig);

        // With a config when we are in local mode (no proxy)
        SyncConfiguration configuration = new SyncConfiguration(new string[] { "Customers", "ServiceTickets" });

        SyncAgent agent = new SyncAgent(clientProvider, serverProvider, configuration);

        agent.SyncProgress += SyncProgress;
        //(s,e) =>
        //{
        //    switch (e.Context.SyncStage)
        //    {
        //        case SyncStage.EnsureConfiguration:
        //            break;
        //        case SyncStage.EnsureDatabase:
        //            if (e.DatabaseScript != null)
        //                e.Action = ChangeApplicationAction.Rollback;
        //            break;
        //        case SyncStage.SelectedChanges:
        //            Console.WriteLine($"Selected changes : {e.ChangesStatistics.TotalSelectedChanges}. I:{e.ChangesStatistics.TotalSelectedChangesInserts}. U:{e.ChangesStatistics.TotalSelectedChangesUpdates}. D:{e.ChangesStatistics.TotalSelectedChangesDeletes}");
        //            break;
        //        case SyncStage.ApplyingChanges:
        //            Console.WriteLine($"Going to apply changes.");
        //            e.Action = ChangeApplicationAction.Continue;
        //            break;
        //        case SyncStage.AppliedChanges:
        //            Console.WriteLine($"Applied changes : {e.ChangesStatistics.TotalAppliedChanges}");
        //            e.Action = ChangeApplicationAction.Continue;
        //            break;
        //        case SyncStage.ApplyingInserts:
        //            Console.WriteLine($"Applying Inserts : {e.ChangesStatistics.AppliedChanges.Where(ac => ac.State == DmRowState.Added).Sum(ac => ac.ChangesApplied) }");
        //            e.Action = ChangeApplicationAction.Continue;
        //            break;
        //        case SyncStage.ApplyingDeletes:
        //            Console.WriteLine($"Applying Deletes : {e.ChangesStatistics.AppliedChanges.Where(ac => ac.State == DmRowState.Deleted).Sum(ac => ac.ChangesApplied) }");
        //            break;
        //        case SyncStage.ApplyingUpdates:
        //            Console.WriteLine($"Applying Updates : {e.ChangesStatistics.AppliedChanges.Where(ac => ac.State == DmRowState.Modified).Sum(ac => ac.ChangesApplied) }");
        //            e.Action = ChangeApplicationAction.Continue;
        //            break;
        //    }
        //};
        agent.ApplyChangedFailed += ApplyChangedFailed;

        do
        {
            Console.Clear();
            Console.WriteLine("Sync Start");
            try
            {
                var s = await agent.SynchronizeAsync();
            }
            catch (SyncException e)
            {
                Console.WriteLine(e.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("UNKNOW EXCEPTION : " + e.Message);
            }


            Console.WriteLine("Sync Ended. Press a key to start again, or Escapte to end");
        } while (Console.ReadKey().Key != ConsoleKey.Escape);

        Console.WriteLine("End");
    }
Example #20
0
    public async static Task SyncHttpThroughKestellAsync()
    {
        // server provider
        var serverProvider = new SqlSyncProvider(GetDatabaseConnectionString("AdventureWorks"));
        // proxy server based on server provider
        var proxyServerProvider = new WebProxyServerProvider(serverProvider);

        // client provider
        var client1Provider = new SqlSyncProvider(GetDatabaseConnectionString("Adv"));
        // proxy client provider
        var proxyClientProvider = new WebProxyClientProvider();

        var tables = new string[] { "ProductCategory",
                                    "ProductDescription", "ProductModel",
                                    "Product", "ProductModelProductDescription",
                                    "Address", "Customer", "CustomerAddress",
                                    "SalesOrderHeader", "SalesOrderDetail" };

        var configuration = new SyncConfiguration(tables)
        {
            ScopeName              = "AdventureWorks",
            ScopeInfoTableName     = "tscopeinfo",
            SerializationFormat    = Dotmim.Sync.Enumerations.SerializationFormat.Binary,
            DownloadBatchSizeInKB  = 400,
            StoredProceduresPrefix = "s",
            StoredProceduresSuffix = "",
            TrackingTablesPrefix   = "t",
            TrackingTablesSuffix   = "",
        };


        var serverHandler = new RequestDelegate(async context =>
        {
            proxyServerProvider.Configuration = configuration;

            await proxyServerProvider.HandleRequestAsync(context);
        });

        using (var server = new KestrellTestServer())
        {
            var clientHandler = new ResponseDelegate(async(serviceUri) =>
            {
                proxyClientProvider.ServiceUri = new Uri(serviceUri);

                var syncAgent = new SyncAgent(client1Provider, proxyClientProvider);

                do
                {
                    Console.Clear();
                    Console.WriteLine("Sync Start");
                    try
                    {
                        CancellationTokenSource cts = new CancellationTokenSource();

                        Console.WriteLine("--------------------------------------------------");
                        Console.WriteLine("1 : Normal synchronization.");
                        Console.WriteLine("2 : Fill configuration from server side");
                        Console.WriteLine("3 : Synchronization with reinitialize");
                        Console.WriteLine("4 : Synchronization with upload and reinitialize");
                        Console.WriteLine("5 : Deprovision everything from client side (tables included)");
                        Console.WriteLine("6 : Deprovision everything from client side (tables not included)");
                        Console.WriteLine("7 : Deprovision everything from server side (tables not included)");
                        Console.WriteLine("8 : Provision everything on the client side (tables included)");
                        Console.WriteLine("9 : Provision everything on the server side (tables not included)");
                        Console.WriteLine("10 : Insert datas on client");
                        Console.WriteLine("--------------------------------------------------");
                        Console.WriteLine("What's your choice ? ");
                        Console.WriteLine("--------------------------------------------------");
                        var choice = Console.ReadLine();

                        if (int.TryParse(choice, out int choiceNumber))
                        {
                            Console.WriteLine($"You choose {choice}. Start operation....");
                            switch (choiceNumber)
                            {
                            case 1:
                                var s1 = await syncAgent.SynchronizeAsync(cts.Token);
                                Console.WriteLine(s1);
                                break;

                            case 2:
                                SyncContext ctx = new SyncContext(Guid.NewGuid());
                                SqlSyncProvider syncConfigProvider = new SqlSyncProvider(GetDatabaseConnectionString("AdventureWorks"));
                                (ctx, configuration.Schema)        = await syncConfigProvider.EnsureSchemaAsync(ctx, new Dotmim.Sync.Messages.MessageEnsureSchema
                                {
                                    Schema = configuration.Schema,
                                    SerializationFormat = Dotmim.Sync.Enumerations.SerializationFormat.Json
                                });
                                break;

                            case 3:
                                s1 = await syncAgent.SynchronizeAsync(SyncType.Reinitialize, cts.Token);
                                Console.WriteLine(s1);
                                break;

                            case 4:
                                s1 = await syncAgent.SynchronizeAsync(SyncType.ReinitializeWithUpload, cts.Token);
                                Console.WriteLine(s1);
                                break;

                            case 5:
                                SqlSyncProvider clientSyncProvider = syncAgent.LocalProvider as SqlSyncProvider;
                                await clientSyncProvider.DeprovisionAsync(configuration, SyncProvision.All | SyncProvision.Table);
                                Console.WriteLine("Deprovision complete on client");
                                break;

                            case 6:
                                SqlSyncProvider client2SyncProvider = syncAgent.LocalProvider as SqlSyncProvider;
                                await client2SyncProvider.DeprovisionAsync(configuration, SyncProvision.All);
                                Console.WriteLine("Deprovision complete on client");
                                break;

                            case 7:
                                SqlSyncProvider remoteSyncProvider = new SqlSyncProvider(GetDatabaseConnectionString("AdventureWorks"));
                                await remoteSyncProvider.DeprovisionAsync(configuration, SyncProvision.All);
                                Console.WriteLine("Deprovision complete on remote");
                                break;

                            case 8:
                                SqlSyncProvider clientSyncProvider2 = syncAgent.LocalProvider as SqlSyncProvider;
                                await clientSyncProvider2.ProvisionAsync(configuration, SyncProvision.All | SyncProvision.Table);
                                Console.WriteLine("Provision complete on client");
                                break;

                            case 9:
                                SqlSyncProvider remoteSyncProvider2 = new SqlSyncProvider(GetDatabaseConnectionString("AdventureWorks"));
                                await remoteSyncProvider2.ProvisionAsync(configuration, SyncProvision.All);
                                Console.WriteLine("Provision complete on remote");
                                break;

                            case 10:
                                var c       = GetDatabaseConnectionString("Adv");
                                var catId   = await InsertProductCategory(c);
                                var modelId = await InsertProductModel(c);
                                await InsertProduct(c, catId, modelId);
                                Console.WriteLine("Inserted a model, a category and a product.");
                                break;

                            default:
                                break;
                            }
                        }
                    }
                    catch (SyncException e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("UNKNOW EXCEPTION : " + e.Message);
                    }


                    Console.WriteLine("--------------------------------------------------");
                    Console.WriteLine("Press a key to choose again, or Escapte to end");
                } while (Console.ReadKey().Key != ConsoleKey.Escape);
            });
            await server.Run(serverHandler, clientHandler);
        }
    }
Example #21
0
        public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf)
        {
            var id = Guid.NewGuid().ToString();

            using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString))
            {
                var script = $@"INSERT [ServiceTickets] 
                            ([ServiceTicketID], [Title], [Description], [StatusValue], [EscalationLevel], [Opened], [Closed], [CustomerID]) 
                            VALUES 
                            (N'{id}', N'Line for conflict', N'Description client', 1, 0, getdate(), NULL, 1)";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var server = new KestrellTestServer())
            {
                var serverHandler = new RequestDelegate(async context =>
                {
                    conf.Tables = fixture.Tables;
                    serverProvider.SetConfiguration(conf);
                    proxyServerProvider.SerializationFormat = conf.SerializationFormat;

                    await proxyServerProvider.HandleRequestAsync(context);
                });
                var clientHandler = new ResponseDelegate(async(serviceUri) =>
                {
                    proxyClientProvider.ServiceUri          = new Uri(serviceUri);
                    proxyClientProvider.SerializationFormat = conf.SerializationFormat;

                    var session = await agent.SynchronizeAsync();

                    // check statistics
                    Assert.Equal(0, session.TotalChangesDownloaded);
                    Assert.Equal(1, session.TotalChangesUploaded);
                    Assert.Equal(0, session.TotalSyncConflicts);
                });
                await server.Run(serverHandler, clientHandler);
            }


            using (var sqlConnection = new SqlConnection(fixture.Client1ConnectionString))
            {
                var script = $@"Update [ServiceTickets] 
                                Set Title = 'Updated from Client'
                                Where ServiceTicketId = '{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Update [ServiceTickets] 
                                Set Title = 'Updated from Server'
                                Where ServiceTicketId = '{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }


            using (var server = new KestrellTestServer())
            {
                var serverHandler = new RequestDelegate(async context =>
                {
                    conf.Tables = fixture.Tables;
                    serverProvider.SetConfiguration(conf);
                    proxyServerProvider.SerializationFormat = conf.SerializationFormat;

                    // Since we move to server side, it's server to handle errors
                    serverProvider.ApplyChangedFailed += (s, args) =>
                    {
                        args.Action = ApplyAction.RetryWithForceWrite;
                    };


                    await proxyServerProvider.HandleRequestAsync(context);
                });
                var clientHandler = new ResponseDelegate(async(serviceUri) =>
                {
                    proxyClientProvider.ServiceUri          = new Uri(serviceUri);
                    proxyClientProvider.SerializationFormat = conf.SerializationFormat;

                    SyncContext session = null;
                    await Assert.RaisesAsync <ApplyChangeFailedEventArgs>(
                        h => serverProvider.ApplyChangedFailed += h,
                        h => serverProvider.ApplyChangedFailed -= h, async() =>
                    {
                        session = await agent.SynchronizeAsync();
                    });

                    // check statistics
                    Assert.Equal(0, session.TotalChangesDownloaded);
                    Assert.Equal(1, session.TotalChangesUploaded);
                    Assert.Equal(1, session.TotalSyncConflicts);
                });
                await server.Run(serverHandler, clientHandler);
            }

            string expectedRes = string.Empty;

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Updated from Client", expectedRes);
        }
Example #22
0
        public async Task ConflictUpdateUpdateClientWins(SyncConfiguration conf)
        {
            var id = Guid.NewGuid().ToString();

            using (var sqlConnection = new MySqlConnection(fixture.ClientMySqlConnectionString))
            {
                var script = $@"INSERT INTO `ServiceTickets` 
                            (`ServiceTicketID`, `Title`, `Description`, `StatusValue`, `EscalationLevel`, `Opened`, `Closed`, `CustomerID`) 
                            VALUES 
                            ('{id}', 'Line for conflict', 'Description client', 1, 0, now(), NULL, 1)";

                using (var sqlCmd = new MySqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.Configuration = conf;
            agent.Configuration.Add(fixture.Tables);
            var session = await agent.SynchronizeAsync();

            //just check, even if it's not the real test :)
            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(0, session.TotalSyncConflicts);


            using (var sqlConnection = new MySqlConnection(fixture.ClientMySqlConnectionString))
            {
                var script = $@"Update `ServiceTickets` 
                                Set Title = 'Updated from Client'
                                Where ServiceTicketId = '{id}'";

                using (var sqlCmd = new MySqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Update [ServiceTickets] 
                                Set Title = 'Updated from Server'
                                Where ServiceTicketId = '{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    sqlCmd.ExecuteNonQuery();
                    sqlConnection.Close();
                }
            }

            agent.ApplyChangedFailed += (s, args) => args.Action = ConflictAction.ClientWins;

            await Assert.RaisesAsync <ApplyChangeFailedEventArgs>(
                h => agent.ApplyChangedFailed += h,
                h => agent.ApplyChangedFailed -= h, async() =>
            {
                session = await agent.SynchronizeAsync();
            });

            // check statistics
            Assert.Equal(0, session.TotalChangesDownloaded);
            Assert.Equal(1, session.TotalChangesUploaded);
            Assert.Equal(1, session.TotalSyncConflicts);

            string expectedRes = string.Empty;

            using (var sqlConnection = new SqlConnection(fixture.ServerConnectionString))
            {
                var script = $@"Select Title from [ServiceTickets] Where ServiceTicketID='{id}'";

                using (var sqlCmd = new SqlCommand(script, sqlConnection))
                {
                    sqlConnection.Open();
                    expectedRes = sqlCmd.ExecuteScalar() as string;
                    sqlConnection.Close();
                }
            }

            // check good title on client
            Assert.Equal("Updated from Client", expectedRes);
        }
        public EmployeeItemViewModel(INavigation navigation, DatabaseService databaseService, SyncConfiguration syncConfiguration)
        {
            this.navigation   = navigation;
            customSyncEngine  = new CustomSyncEngine(databaseService, syncConfiguration);
            transaction       = customSyncEngine.Realm.BeginWrite();
            synchronizationId = databaseService.GetSynchronizationId();

            IsActiveItems = new List <bool>()
            {
                true, false
            };
            DepartmentItems = new List <ReferenceItem>();
            DepartmentItems.Add(new ReferenceItem()
            {
                Id = Guid.Empty.ToString(), Name = "[None]"
            });
            List <Department> departments = databaseService.GetDepartments().ToList();

            for (int i = 0; i < departments.Count; i++)
            {
                DepartmentItems.Add(new ReferenceItem()
                {
                    Id = departments[i].Id, Name = departments[i].Name
                });
            }
        }