예제 #1
0
        public void TestWriteWithDesiredSpeed()
        {
            var keyDistributor = new KeyDistributor(64);

            var threads = Enumerable.Range(0, 5).Select(number =>
            {
                var repository = CreateBoxEventRepository((id, obj) => keyDistributor.Distribute(id.ScopeId).ToString());

                var testEventWriter = new TestEventWriter(repository, OperationsSpeed.PerSecond(10000), 1000);
                var thread          = new Thread(testEventWriter.BeginExecution);
                thread.Start();
                return(new { Thread = thread, Writer = testEventWriter });
            }).ToList();

            Thread.Sleep(TimeSpan.FromSeconds(30));

            threads.ForEach(x => x.Writer.StopExecution());
            threads.ForEach(x => x.Thread.Join());
        }
예제 #2
0
        public void TestWriteAndRead64Shard()
        {
            boxIds = new[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };

            using (var eventRepository = CreateBoxEventRepository((eventId, obj) =>
            {
                var keyDistributor = new KeyDistributor(64);
                return(keyDistributor.Distribute(eventId.ScopeId).ToString());
            }, 0))
            {
                var       expectedEvents = new List <Event>();
                const int count          = 30;
                for (var i = 0; i < count; ++i)
                {
                    Console.WriteLine("Start write event {0}", i);
                    var scopeId      = GenerateScopeId();
                    var eventContent = GenerateEventContent();
                    var eventInfo    = eventRepository.AddEvent(scopeId, eventContent);
                    Assert.AreEqual(scopeId, eventInfo.Id.ScopeId);

                    expectedEvents.Add(new Event
                    {
                        EventInfo    = eventInfo,
                        EventContent = eventContent,
                    });
                }

                var shards = new string[64].Select((x, idx) => (idx.ToString())).ToArray();
                Console.WriteLine("Get events: all.");
                var actualEvents = eventRepository.GetEvents(null, shards).ToArray();
                CheckEqualEvents(expectedEvents.ToArray(), actualEvents);
                for (var i = 0; i < expectedEvents.Count; ++i)
                {
                    Console.WriteLine("Get events: from {0}.", i);
                    actualEvents = eventRepository.GetEvents(expectedEvents[i].EventInfo, shards).ToArray();
                    CheckEqualEvents(expectedEvents.Skip(i + 1).ToArray(), actualEvents);
                }
            }
        }
        public void TestGuidDistribution()
        {
            const int shardsCount    = 10;
            var       keyDistributor = KeyDistributor.Create(shardsCount);
            var       array          = new int[shardsCount];
            const int guidsCount     = 10000;
            var       sw             = Stopwatch.StartNew();

            for (var i = 0; i < guidsCount; i++)
            {
                var idx = keyDistributor.Distribute(Guid.NewGuid().ToString());
                if (idx < 0 || idx >= shardsCount)
                {
                    Assert.That(false);
                }
                array[idx]++;
            }
            Console.WriteLine("Time=" + sw.Elapsed);
            var diff = array.Max() - array.Min();

            Console.WriteLine("Diff = " + diff);
            Assert.That(diff < guidsCount / 50);
        }
        public void TestRandomStringDistribution()
        {
            const int shardsCount    = 10;
            var       keyDistributor = KeyDistributor.Create(shardsCount);
            var       array          = new int[shardsCount];
            var       path           = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tests/EventLog/Sharding/Files/dict.txt");
            var       words          = File.ReadAllText(path).Split('\n', '\r').Where(s => !string.IsNullOrEmpty(s)).ToArray();
            var       sw             = Stopwatch.StartNew();

            for (var i = 0; i < words.Length; i++)
            {
                var idx = keyDistributor.Distribute(words[i]);
                if (idx < 0 || idx >= shardsCount)
                {
                    Assert.That(false);
                }
                array[idx]++;
            }
            Console.WriteLine("Time=" + sw.Elapsed);
            var diff = array.Max() - array.Min();

            Console.WriteLine("Diff = " + diff);
            Assert.That(diff < words.Length / 100);
        }
예제 #5
0
 public override void SetUp()
 {
     base.SetUp();
     keyDistributor        = new KeyDistributor(shardsCount);
     globalEventRepository = CreateBoxEventRepository();
 }
        private string CalculateShard(EventId eventId, object eventContent)
        {
            var keyDistributor = new KeyDistributor(ShardsCount);

            return(keyDistributor.Distribute(eventId.ScopeId).ToString());
        }
예제 #7
0
        static async Task Main(string[] args)
        {
            string basePath = (Debugger.IsAttached) ? Directory.GetCurrentDirectory() : AppDomain.CurrentDomain.BaseDirectory;

            var configBuilder = new ConfigurationBuilder()
                                .SetBasePath(basePath)
                                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                                .AddEnvironmentVariables();
            var config = configBuilder.Build();

            // connect to RabbitMQ
            var conn = Utils.ConnectRabbitMQ(config);

            // token signing key
            byte[] tokenKey = null;

            // configure keys through RabbitMQ exchange
            await KeyDistributor.ConfigureAsync(
                config["RabbitMQ:Exchanges:KeyDistribution"],
                conn,
                keys => {
                TelemetryConfiguration.Active.InstrumentationKey = keys.AppInsightsInstrumKey;
                tokenKey = keys.JwtIssuerKey;
            });

            // set app insights developer mode (remove lags when sending telemetry)
            TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = true;

            // set service name in app insights
            TelemetryConfiguration.Active.TelemetryInitializers.Add(new CustomTelemetryInitializer(serviceName));

            // telemetry client instance
            var telemetry = new TelemetryClient();

            // token validation parameters
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateAudience         = false,
                ValidateIssuer           = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = new SymmetricSecurityKey(tokenKey)
            };

            // security options for RabbitMQ service
            var securityOptions = new SecurityOptions(
                // map of request types to scope names
                new Dictionary <string, string>()
            {
                { nameof(Ping1), "1" },
                { nameof(Ping2), "2" },
                { nameof(Ping3), "3" },
                { nameof(Ping4), "4" }
            },
                tokenValidationParameters);

            // set host configuration
            var hostBuilder = new HostBuilder()
                              .ConfigureHostConfiguration(c => c
                                                          .SetBasePath(basePath)
                                                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true))
                              .ConfigureServices((context, services) => {
                services.AddSingleton <TelemetryClient>(telemetry);
                services.AddSingleton <SecurityOptions>(securityOptions);
                services.AddSingleton <IConnection>(conn);
                services.AddHostedService <BangService>();
            });
            var host = hostBuilder.Build();

            // send ready signal
            await ReadyChecker.SendReadyAsync(config["RabbitMQ:Exchanges:ReadyCheck"], conn, serviceName);

            // run host and wait for shutdown signal
            await host.StartAsync();

            await Shutdowner.ShutdownAsync(config["RabbitMQ:Exchanges:Shutdown"], conn, () => host.StopAsync());

            // flush telemetry
            telemetry?.Flush();
            Task.Delay(1000).Wait();
            Console.WriteLine("Bye!");
        }
예제 #8
0
        static async Task Main(string[] args)
        {
            string basePath = (Debugger.IsAttached) ? Directory.GetCurrentDirectory() : AppDomain.CurrentDomain.BaseDirectory;

            var configBuilder = new ConfigurationBuilder()
                                .SetBasePath(basePath)
                                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                                .AddEnvironmentVariables();

            if (Debugger.IsAttached)
            {
                configBuilder.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: false);
            }

            var config = configBuilder.Build();

            // connect to RabbitMQ
            var conn = Utils.ConnectRabbitMQ(config);

            // token signing key
            byte[] tokenKey = null;

            // app insights key
            string appInsKey = null;

            // configure keys through RabbitMQ exchange
            await KeyDistributor.ConfigureAsync(
                config["RabbitMQ:Exchanges:KeyDistribution"],
                conn,
                keys => {
                appInsKey = keys.AppInsightsInstrumKey;
                tokenKey  = keys.JwtIssuerKey;
            });

            // set app insights developer mode (remove lags when sending telemetry)
            TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = true;

            // token validation parameters
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateAudience         = false,
                ValidateIssuer           = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = new SymmetricSecurityKey(tokenKey)
            };

            // set host configuration
            var hostBuilder = new WebHostBuilder()
                              .UseConfiguration(config)
                              .ConfigureLogging(logging =>
            {
                logging.AddConfiguration(config.GetSection("Logging"));
                logging.AddConsole();
            })
                              .ConfigureServices(services =>
            {
                services.AddSingleton <IConnection>(conn);
                services.AddSingleton <ITelemetryInitializer>(new CustomTelemetryInitializer("apigw"));
                services.AddApplicationInsightsTelemetry(appInsKey);
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = tokenValidationParameters;
                    options.SaveToken = true;
                });
                services.AddMvc(options => options.Filters.Add(new ExceptionFilter()));
            })
                              .Configure(app =>
            {
                app.UseAuthentication();
                app.UseMvc();
            })
                              .UseKestrel();
            var host = hostBuilder.Build();

            // send ready signal
            await ReadyChecker.SendReadyAsync(config["RabbitMQ:Exchanges:ReadyCheck"], conn, serviceName);

            // run host and wait for shutdown signal
            await host.StartAsync();

            await Shutdowner.ShutdownAsync(config["RabbitMQ:Exchanges:Shutdown"], conn, () => host.StopAsync());

            // telemetry client instance
            var telemetry = host.Services.GetService <TelemetryClient>();

            // flush telemetry
            telemetry?.Flush();
            Task.Delay(1000).Wait();
            Console.WriteLine("Bye!");
        }
        static async Task Main(string[] args)
        {
            string basePath = (Debugger.IsAttached) ? Directory.GetCurrentDirectory() : AppDomain.CurrentDomain.BaseDirectory;

            // build config
            var configBuilder = new ConfigurationBuilder()
                                .SetBasePath(basePath)
                                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                                .AddEnvironmentVariables();

            if (Debugger.IsAttached)
            {
                configBuilder.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: false);
            }

            var config = configBuilder.Build();

            // connect to RabbitMQ
            var conn = Utils.ConnectRabbitMQ(config);

            // wait peers to be ready
            var waitPeers = ReadyChecker.WaitPeersAsync(config["RabbitMQ:Exchanges:ReadyCheck"], conn, new List <string> {
                "apigw", "bang", "bar", "fib", "foo"
            });

            // get App Insights instrumentation key from CLI
            Console.WriteLine("Please enter your Application Insights instrumentation key: ");
            var instrumKey = Console.ReadLine();

            // generate key and token
            var tokenKey = GenKey();

            // distribute keys
            await KeyDistributor.ConfigurePeersAsync(config["RabbitMQ:Exchanges:KeyDistribution"], conn, new Keys { AppInsightsInstrumKey = instrumKey, JwtIssuerKey = tokenKey });

            // if peers are ready
            if (await Task.WhenAny(waitPeers, Task.Delay(15000)) == waitPeers)
            {
                // Task completed within timeout.
                // Consider that the task may have faulted or been canceled.
                // We re-await the task so that any exceptions/cancellation is rethrown.
                await waitPeers;

                bool shutdown = false;

                // perform demo scenarios based on user choise
                using (var http = new HttpClient())
                {
                    http.BaseAddress = new Uri(config["ApiGW:Url"]);
                    while (!shutdown)
                    {
                        try
                        {
                            string url = null;
                            switch (MainDialog())
                            {
                            case '1':
                                url = "api/demo/fooping1";
                                break;

                            case '2':
                                url = "api/demo/barping2";
                                break;

                            case '3':
                                url = "api/demo/fibping3";
                                break;

                            case '4':
                                url = "api/demo/fibping4";
                                break;

                            case 'q':
                                shutdown = true;
                                break;
                            }
                            if (shutdown)
                            {
                                await Shutdowner.ShutdownPeersAsync(config["RabbitMQ:Exchanges:Shutdown"], conn);
                            }
                            else
                            {
                                HttpResponseMessage resp = await http.GetAsync(url);

                                if (resp.StatusCode == HttpStatusCode.Unauthorized)
                                {
                                    var username = LoginDialog();
                                    var token    = GenToken(tokenKey, username);
                                    http.DefaultRequestHeaders.Authorization =
                                        new AuthenticationHeaderValue("Bearer", token);
                                    Console.WriteLine($"Bearer JWT for user '{username}' will be sent in the header of every request since now.");
                                }
                                else
                                {
                                    resp.EnsureSuccessStatusCode();
                                    Console.WriteLine();
                                    Console.WriteLine("----------------------------------------");
                                    Console.WriteLine($"HTTP GET '/{url}' completed at {DateTime.Now.ToString()}.");
                                    Console.WriteLine("----------------------------------------");
                                }
                            }
                        }
                        catch (HttpRequestException ex)
                        {
                            Console.WriteLine();
                            Console.WriteLine("----------------------------------------");
                            Console.WriteLine("Message: " + ex.Message);
                            Console.WriteLine("----------------------------------------");
                        }
                    }
                }
            }
            else
            {
                // timeout/cancellation logic
                Console.WriteLine();
                Console.WriteLine("Sorry, but not all services are ready for demo.");
                await Shutdowner.ShutdownPeersAsync(config["RabbitMQ:Exchanges:Shutdown"], conn);

                return;
            }
            Console.WriteLine("Bye!");
        }