Example #1
0
        public async Task Kestrell_Server_Request_EnsureSuccess()
        {
            using (var server = new KestrellTestServer())
            {
                var clientHandler = new ResponseDelegate(async baseAdress => {
                    var httpClient = new HttpClient();

                    var response = await httpClient.GetAsync(baseAdress + "first");
                    response.EnsureSuccessStatusCode();

                    var resString = await response.Content.ReadAsStringAsync();
                    Assert.Equal("first_first", resString);
                });

                var serverHandler = new RequestDelegate(async context =>
                {
                    var pathFirst = new PathString("/first");
                    Assert.Equal(context.Request.Path, pathFirst);

                    await context.Response.WriteAsync("first_first");
                });

                await server.Run(serverHandler, clientHandler);
            };
        }
Example #2
0
    public static async Task SyncHttpThroughKestellAsync()
    {
        // server provider
        var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName));

        // client provider
        var client1Provider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName));
        // proxy client provider
        var proxyClientProvider = new WebProxyClientProvider();

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

        var configuration = new Action <SyncConfiguration>(conf =>
        {
            conf.ScopeName              = "AdventureWorks";
            conf.ScopeInfoTableName     = "tscopeinfo";
            conf.SerializationFormat    = Dotmim.Sync.Enumerations.SerializationFormat.Binary;
            conf.StoredProceduresPrefix = "s";
            conf.StoredProceduresSuffix = "";
            conf.TrackingTablesPrefix   = "t";
            conf.TrackingTablesSuffix   = "";
            conf.Add(tables);
        });


        var optionsClient = new Action <SyncOptions>(opt =>
        {
            opt.BatchDirectory    = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "client");
            opt.BatchSize         = 100;
            opt.CleanMetadatas    = true;
            opt.UseBulkOperations = true;
            opt.UseVerboseErrors  = false;
        });

        var optionsServer = new Action <SyncOptions>(opt =>
        {
            opt.BatchDirectory    = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "server");
            opt.BatchSize         = 100;
            opt.CleanMetadatas    = true;
            opt.UseBulkOperations = true;
            opt.UseVerboseErrors  = false;
        });



        var serverHandler = new RequestDelegate(async context =>
        {
            var proxyServerProvider = WebProxyServerProvider.Create(context, serverProvider, configuration, optionsServer);

            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
                    {
                        var cts = new CancellationTokenSource();

                        Console.WriteLine("--------------------------------------------------");
                        Console.WriteLine("1 : Normal synchronization.");
                        Console.WriteLine("2 : Synchronization with reinitialize");
                        Console.WriteLine("3 : Synchronization with upload and reinitialize");
                        Console.WriteLine("--------------------------------------------------");
                        Console.WriteLine("What's your choice ? ");
                        Console.WriteLine("--------------------------------------------------");
                        var choice = Console.ReadLine();

                        if (int.TryParse(choice, out var 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:
                                s1 = await syncAgent.SynchronizeAsync(SyncType.Reinitialize, cts.Token);
                                Console.WriteLine(s1);
                                break;

                            case 3:
                                s1 = await syncAgent.SynchronizeAsync(SyncType.ReinitializeWithUpload, cts.Token);
                                Console.WriteLine(s1);
                                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 #3
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 #4
0
    public static async Task SyncHttpThroughKestellAsync()
    {
        // server provider
        // Create 2 Sql Sync providers
        var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName));
        var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName));


        // ----------------------------------
        // Client side
        // ----------------------------------
        var clientOptions = new SyncOptions {
            BatchSize = 500
        };

        var proxyClientProvider = new WebClientOrchestrator();

        // ----------------------------------
        // Web Server side
        // ----------------------------------
        var setup = new SyncSetup(allTables)
        {
            ScopeName = "all_tables_scope",
            StoredProceduresPrefix = "s",
            StoredProceduresSuffix = "",
            TrackingTablesPrefix   = "t",
            TrackingTablesSuffix   = "",
            TriggersPrefix         = "",
            TriggersSuffix         = "t"
        };

        // snapshot directory
        var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots");

        // ----------------------------------
        // Create a snapshot
        // ----------------------------------
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine($"Creating snapshot");
        var remoteOrchestrator = new RemoteOrchestrator(serverProvider);
        await remoteOrchestrator.CreateSnapshotAsync(new SyncContext(), setup, directory, 500, CancellationToken.None);

        Console.WriteLine($"Done.");
        Console.ResetColor();


        // ----------------------------------
        // Insert a value after snapshot created
        // ----------------------------------
        using (var c = serverProvider.CreateConnection())
        {
            var command = c.CreateCommand();
            command.CommandText = "INSERT INTO [dbo].[ProductCategory] ([Name]) VALUES ('Bikes revolution');";
            c.Open();
            command.ExecuteNonQuery();
            c.Close();
        }

        var webServerOptions = new WebServerOptions {
            SnapshotsDirectory = directory
        };

        // Creating an agent that will handle all the process
        var agent = new SyncAgent(clientProvider, proxyClientProvider);

        agent.Options = clientOptions;

        var configureServices = new Action <IServiceCollection>(services =>
        {
            services.AddSyncServer <SqlSyncProvider>(serverProvider.ConnectionString, setup, webServerOptions);
        });

        var serverHandler = new RequestDelegate(async context =>
        {
            var webProxyServer = context.RequestServices.GetService(typeof(WebProxyServerOrchestrator)) as WebProxyServerOrchestrator;
            await webProxyServer.HandleRequestAsync(context);
        });

        using (var server = new KestrellTestServer(configureServices))
        {
            var clientHandler = new ResponseDelegate(async(serviceUri) =>
            {
                proxyClientProvider.ServiceUri = serviceUri;
                do
                {
                    Console.Clear();
                    Console.WriteLine("Web sync start");
                    try
                    {
                        var progress = new SynchronousProgress <ProgressArgs>(pa => Console.WriteLine($"{pa.Context.SyncStage}\t {pa.Message}"));
                        var s        = await agent.SynchronizeAsync(progress);
                        Console.WriteLine(s);
                    }
                    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);
            });
            await server.Run(serverHandler, clientHandler);
        }
    }
Example #5
0
        public async Task RemoteOrchestrator_HttpGetEstimatedChanges_WithFilters_ShouldReturnDeletedRowsCount()
        {
            var dbNameSrv = HelperDatabase.GetRandomName("tcp_lo_srv");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameSrv, true);

            var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true);

            var csServer       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameSrv);
            var serverProvider = new SqlSyncProvider(csServer);

            var csClient       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli);
            var clientProvider = new SqlSyncProvider(csClient);

            await new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider), true, true).Database.EnsureCreatedAsync();
            await new AdventureWorksContext((dbNameCli, ProviderType.Sql, clientProvider), true, false).Database.EnsureCreatedAsync();

            var scopeName = "scopesnap1";
            var setup     = GetFilterSetup();

            // Create a kestrell server
            var kestrell = new KestrellTestServer(false);

            // configure server orchestrator
            kestrell.AddSyncServer(serverProvider.GetType(), serverProvider.ConnectionString, scopeName, setup);
            var serviceUri = kestrell.Run();

            var rowsCount = GetFilterServerDatabaseRowsCount((dbNameSrv, ProviderType.Sql, serverProvider));

            var remoteOrchestrator = new WebRemoteOrchestrator(serviceUri);

            // Make a first sync to be sure everything is in place
            var agent      = new SyncAgent(clientProvider, remoteOrchestrator);
            var parameters = new SyncParameters(("CustomerID", AdventureWorksContext.CustomerIdForFilter));

            // Making a first sync, will initialize everything we need
            var r = await agent.SynchronizeAsync(scopeName, parameters);

            Assert.Equal(rowsCount, r.TotalChangesDownloaded);

            // Get the orchestrators
            var localOrchestrator = agent.LocalOrchestrator;

            Guid otherCustomerId;

            // Server side : Create a sales order header + 3 sales order details linked to the filter
            // and create 1 sales order header not linked to filter
            using var ctxServer = new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider), true);

            // get another customer than the filter one
            otherCustomerId = ctxServer.Customer.First(c => c.CustomerId != AdventureWorksContext.CustomerIdForFilter).CustomerId;

            var soh = new SalesOrderHeader
            {
                SalesOrderNumber    = $"SO-99999",
                RevisionNumber      = 1,
                Status              = 5,
                OnlineOrderFlag     = true,
                PurchaseOrderNumber = "PO348186287",
                AccountNumber       = "10-4020-000609",
                CustomerId          = AdventureWorksContext.CustomerIdForFilter,
                ShipToAddressId     = 4,
                BillToAddressId     = 5,
                ShipMethod          = "CAR TRANSPORTATION",
                SubTotal            = 6530.35M,
                TaxAmt              = 70.4279M,
                Freight             = 22.0087M,
                TotalDue            = 6530.35M + 70.4279M + 22.0087M
            };

            var soh2 = new SalesOrderHeader
            {
                SalesOrderNumber    = $"SO-99999",
                RevisionNumber      = 1,
                Status              = 5,
                OnlineOrderFlag     = true,
                PurchaseOrderNumber = "PO348186287",
                AccountNumber       = "10-4020-000609",
                CustomerId          = otherCustomerId,
                ShipToAddressId     = 4,
                BillToAddressId     = 5,
                ShipMethod          = "CAR TRANSPORTATION",
                SubTotal            = 6530.35M,
                TaxAmt              = 70.4279M,
                Freight             = 22.0087M,
                TotalDue            = 6530.35M + 70.4279M + 22.0087M
            };

            var productId = ctxServer.Product.First().ProductId;

            var sod1 = new SalesOrderDetail {
                OrderQty = 1, ProductId = productId, UnitPrice = 3578.2700M
            };
            var sod2 = new SalesOrderDetail {
                OrderQty = 2, ProductId = productId, UnitPrice = 44.5400M
            };
            var sod3 = new SalesOrderDetail {
                OrderQty = 2, ProductId = productId, UnitPrice = 1431.5000M
            };

            soh.SalesOrderDetail.Add(sod1);
            soh.SalesOrderDetail.Add(sod2);
            soh.SalesOrderDetail.Add(sod3);

            ctxServer.SalesOrderHeader.Add(soh);
            ctxServer.SalesOrderHeader.Add(soh2);
            await ctxServer.SaveChangesAsync();

            // Making a second sync, with these new rows
            r = await agent.SynchronizeAsync(scopeName, parameters);

            Assert.Equal(4, r.TotalChangesDownloaded);

            // now delete these lines on server
            ctxServer.SalesOrderDetail.Remove(sod1);
            ctxServer.SalesOrderDetail.Remove(sod2);
            ctxServer.SalesOrderDetail.Remove(sod3);
            ctxServer.SalesOrderHeader.Remove(soh);
            await ctxServer.SaveChangesAsync();


            // Get changes from server
            var clientScope = await localOrchestrator.GetClientScopeInfoAsync(scopeName);

            var changes = await remoteOrchestrator.GetEstimatedChangesCountAsync(clientScope, parameters);

            Assert.Null(changes.ServerBatchInfo);
            Assert.NotNull(changes.ServerChangesSelected);
            Assert.Equal(2, changes.ServerChangesSelected.TableChangesSelected.Count);
            Assert.Equal(4, changes.ServerChangesSelected.TableChangesSelected.Sum(tcs => tcs.Deletes));
            Assert.Equal(0, changes.ServerChangesSelected.TableChangesSelected.Sum(tcs => tcs.Upserts));
            Assert.Contains("SalesOrderDetail", changes.ServerChangesSelected.TableChangesSelected.Select(tcs => tcs.TableName).ToList());
            Assert.Contains("SalesOrderHeader", changes.ServerChangesSelected.TableChangesSelected.Select(tcs => tcs.TableName).ToList());
        }