public void GetAppName_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions() { ServiceName = "serviceName" }; var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }) .Build(); var result = ConsulRegistration.GetAppName(options, config); Assert.Equal("serviceName", result); options.ServiceName = null; result = ConsulRegistration.GetAppName(options, config); Assert.Equal("foobar", result); config = new ConfigurationBuilder().Build(); result = ConsulRegistration.GetAppName(options, config); Assert.Equal("application", result); }
public void Tags_MapTo_Metadata() { // arrange some tags in configuration var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "consul:discovery:tags:0", "key0=value0" }, { "consul:discovery:tags:1", "key1=value1" }, { "consul:discovery:tags:2", "keyvalue" } }) .Build(); // bind to options var options = new ConsulDiscoveryOptions(); config.Bind(ConsulDiscoveryOptions.CONSUL_DISCOVERY_CONFIGURATION_PREFIX, options); var tags = ConsulRegistration.CreateTags(options); // act - get metadata from tags var result = ConsulServerUtils.GetMetadata(tags); Assert.Contains(result, k => k.Key == "key0"); Assert.Equal("value0", result["key0"]); Assert.Contains(result, k => k.Key == "key1"); Assert.Equal("value1", result["key1"]); Assert.Contains(result, k => k.Key == "keyvalue"); Assert.Equal("keyvalue", result["keyvalue"]); }
public async void SetStatusAsync_CallsConsulClient() { var clientMoq = new Mock <IConsulClient>(); var agentMoq = new Mock <IAgentEndpoint>(); clientMoq.Setup(c => c.Agent).Returns(agentMoq.Object); var opts = new ConsulDiscoveryOptions(); var sch = new TtlScheduler(opts, clientMoq.Object); var builder = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }); var config = builder.Build(); var registration = ConsulRegistration.CreateRegistration(config, opts); var reg = new ConsulServiceRegistry(clientMoq.Object, opts, sch); await reg.SetStatusAsync(registration, "Up"); agentMoq.Verify(a => a.DisableServiceMaintenance(registration.InstanceId, default(CancellationToken)), Times.Once); await reg.SetStatusAsync(registration, "Out_of_Service"); agentMoq.Verify(a => a.EnableServiceMaintenance(registration.InstanceId, "OUT_OF_SERVICE", default(CancellationToken)), Times.Once); }
public void CreateRegistration_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions() { Port = 1100 }; var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }) .Build(); var reg = ConsulRegistration.CreateRegistration(options, new ApplicationInstanceInfo(config)); Assert.StartsWith("foobar-", reg.InstanceId); Assert.False(reg.IsSecure); Assert.Equal("foobar", reg.ServiceId); Assert.Equal(options.HostName, reg.Host); Assert.Equal(1100, reg.Port); var hostName = options.HostName; Assert.Equal(new Uri($"http://{hostName}:1100"), reg.Uri); Assert.NotNull(reg.Service); Assert.Equal(hostName, reg.Service.Address); Assert.StartsWith("foobar-", reg.Service.ID); Assert.Equal("foobar", reg.Service.Name); Assert.Equal(1100, reg.Service.Port); Assert.NotNull(reg.Service.Check); Assert.NotNull(reg.Service.Tags); }
public async void DeregisterAsync_CallsServiceDeregister_RemovesHeartbeatFromScheduler() { var clientMoq = new Mock <IConsulClient>(); var agentMoq = new Mock <IAgentEndpoint>(); clientMoq.Setup(c => c.Agent).Returns(agentMoq.Object); var opts = new ConsulDiscoveryOptions(); var sch = new TtlScheduler(opts, clientMoq.Object); var reg = new ConsulServiceRegistry(clientMoq.Object, opts, sch); var builder = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }); var config = builder.Build(); var registration = ConsulRegistration.CreateRegistration(config, opts); await reg.RegisterAsync(registration); agentMoq.Verify(a => a.ServiceRegister(registration.Service, default(CancellationToken)), Times.Once); Assert.Single(sch._serviceHeartbeats); Assert.Contains(registration.InstanceId, sch._serviceHeartbeats.Keys); await reg.DeregisterAsync(registration); agentMoq.Verify(a => a.ServiceDeregister(registration.Service.ID, default(CancellationToken)), Times.Once); Assert.Empty(sch._serviceHeartbeats); }
public static IApplicationBuilder UseConsulDiscoveryClient(this IApplicationBuilder app) { var services = app.ApplicationServices; var consulDiscoveryOptions = services.GetService <IOptions <ConsulDiscoveryOptions> >()?.Value; var heartbeatOptions = services.GetService <IOptions <HeartbeatOptions> >()?.Value; if (consulDiscoveryOptions == null || !consulDiscoveryOptions.Register) { return(app); } var registration = BuildRegistration(consulDiscoveryOptions, heartbeatOptions); var consulRegistration = new ConsulRegistration(registration, consulDiscoveryOptions); var consulServiceRegistry = services.GetRequiredService <ConsulServiceRegistry>(); consulServiceRegistry.RegisterAsync(consulRegistration).GetAwaiter().GetResult(); if (!consulDiscoveryOptions.Deregister) { return(app); } var discoveryLifecycle = app.ApplicationServices.GetRequiredService <IDiscoveryLifecycle>(); discoveryLifecycle.ApplicationStopping.Register(async() => { await consulServiceRegistry.DeregisterAsync(consulRegistration); }); return(app); }
public void GetDefaultInstanceId_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions() { ServiceName = "serviceName" }; var config = new ConfigurationBuilder().Build(); var result = ConsulRegistration.GetDefaultInstanceId(options, config); Assert.StartsWith("serviceName:", result); config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "vcap:application:instance_id", "vcapid" } }) .Build(); result = ConsulRegistration.GetDefaultInstanceId(options, config); Assert.Equal("serviceName:vcapid", result); config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:instance_id", "springid" } }) .Build(); result = ConsulRegistration.GetDefaultInstanceId(options, config); Assert.Equal("serviceName:springid", result); }
public void NormalizeForConsul_ReturnsExpected() { Assert.Equal("abc1", ConsulRegistration.NormalizeForConsul("abc1")); Assert.Equal("ab-c1", ConsulRegistration.NormalizeForConsul("ab:c1")); Assert.Equal("ab-c1", ConsulRegistration.NormalizeForConsul("ab::c1")); Assert.Throws <ArgumentException>(() => ConsulRegistration.NormalizeForConsul("9abc")); Assert.Throws <ArgumentException>(() => ConsulRegistration.NormalizeForConsul(":abc")); Assert.Throws <ArgumentException>(() => ConsulRegistration.NormalizeForConsul("abc:")); }
public void Construtor_ThrowsOnNulls() { var registry = new Mock <IConsulServiceRegistry>().Object; var options = new ConsulDiscoveryOptions(); var registration = new ConsulRegistration(); Assert.Throws <ArgumentNullException>(() => new ConsulServiceRegistrar(null, options, registration)); Assert.Throws <ArgumentNullException>(() => new ConsulServiceRegistrar(registry, (ConsulDiscoveryOptions)null, registration)); Assert.Throws <ArgumentNullException>(() => new ConsulServiceRegistrar(registry, options, null)); }
public void Start_CallsRegistry() { var regMoq = new Mock <IConsulServiceRegistry>(); var options = new ConsulDiscoveryOptions(); var registration = new ConsulRegistration(); var reg = new ConsulServiceRegistrar(regMoq.Object, options, registration); reg.Start(); Assert.Equal(1, reg._running); regMoq.Verify(a => a.Register(registration), Times.Once); }
public void Deregister_CallsRegistry() { var regMoq = new Mock <IConsulServiceRegistry>(); var options = new ConsulDiscoveryOptions(); var registration = new ConsulRegistration(); var reg = new ConsulServiceRegistrar(regMoq.Object, options, registration); reg.Deregister(); regMoq.Verify(a => a.Deregister(registration), Times.Once); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime) { app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("all"); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); #region ·þÎñ×¢²á if (Env.IsProduction()) { var token = Configuration["Consul:Token"]; var consulIp = Configuration["Consul:Ip"]; var consulPort = Configuration["Consul:Port"]; var serviceName = Configuration["Service:Name"]; var servicePort = Configuration["Service:Port"]; var healthCheck = Configuration["Service:HealthCheck"]; var currentIp = Configuration["Service:Ip"]; var rc = new ConsulRegistration($"http://{consulIp}:{consulPort}", token) { HealthCheckUrl = $"http://{currentIp}:{servicePort}/{healthCheck}" }; var se = new MangoService { Id = Guid.NewGuid().ToString(), IP = currentIp, Port = servicePort, ServiceName = serviceName }; app.RegisterConsulService(rc, se, lifetime); } #endregion }
public void Start_DoesNotStart() { var regMoq = new Mock <IConsulServiceRegistry>(); var options = new ConsulDiscoveryOptions() { Enabled = false }; var registration = new ConsulRegistration(); var reg = new ConsulServiceRegistrar(regMoq.Object, options, registration); reg.Start(); Assert.Equal(0, reg._running); }
public void Deregister_DoesNotCallRegistry() { var regMoq = new Mock <IConsulServiceRegistry>(); var options = new ConsulDiscoveryOptions() { Deregister = false }; var registration = new ConsulRegistration(); var reg = new ConsulServiceRegistrar(regMoq.Object, options, registration); reg.Deregister(); regMoq.Verify(a => a.Deregister(registration), Times.Never); }
private static void AddConsulServices(IServiceCollection services, IConfiguration config, IDiscoveryLifecycle lifecycle) { services.AddSingleton <IConsulClient>((p) => { var consulOptions = p.GetRequiredService <IOptions <ConsulOptions> >(); return(ConsulClientFactory.CreateClient(consulOptions.Value)); }); services.AddSingleton <IScheduler, TtlScheduler>(); services.AddSingleton <IConsulServiceRegistry, ConsulServiceRegistry>(); services.AddSingleton <IConsulRegistration>((p) => { var opts = p.GetRequiredService <IOptions <ConsulDiscoveryOptions> >(); return(ConsulRegistration.CreateRegistration(config, opts.Value)); }); services.AddSingleton <IConsulServiceRegistrar, ConsulServiceRegistrar>(); services.AddSingleton <IDiscoveryClient, ConsulDiscoveryClient>(); services.AddSingleton <IHealthContributor, ConsulHealthContributor>(); }
public async void GetStatusAsync_ReturnsExpected() { var opts = new ConsulDiscoveryOptions(); var builder = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }); var config = builder.Build(); var registration = ConsulRegistration.CreateRegistration(config, opts); var queryResult = new QueryResult <HealthCheck[]>() { Response = new HealthCheck[] { new HealthCheck() { ServiceID = registration.InstanceId, Name = "Service Maintenance Mode" }, new HealthCheck() { ServiceID = "foobar", Name = "Service Maintenance Mode" } } }; var result = Task.FromResult(queryResult); var clientMoq = new Mock <IConsulClient>(); var healthMoq = new Mock <IHealthEndpoint>(); clientMoq.Setup(c => c.Health).Returns(healthMoq.Object); healthMoq.Setup(h => h.Checks(registration.ServiceId, QueryOptions.Default, default(CancellationToken))).Returns(result); var sch = new TtlScheduler(opts, clientMoq.Object); var reg = new ConsulServiceRegistry(clientMoq.Object, opts, sch); var ret = await reg.GetStatusAsync(registration); Assert.Equal("OUT_OF_SERVICE", ret); }
public void CreateTags_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions() { Tags = new List <string>() { "foo=bar" }, InstanceZone = "instancezone", InstanceGroup = "instancegroup", Scheme = "https" }; var result = ConsulRegistration.CreateTags(options); Assert.Equal(4, result.Length); Assert.Contains("foo=bar", result); Assert.Contains("zone=instancezone", result); Assert.Contains("group=instancegroup", result); Assert.Contains("secure=true", result); }
private static void AddConsulServices(IServiceCollection services) { services.AddSingleton((p) => { var consulOptions = p.GetRequiredService <IOptions <ConsulOptions> >(); return(ConsulClientFactory.CreateClient(consulOptions.Value)); }); services.AddSingleton <IScheduler, TtlScheduler>(); services.AddSingleton <IConsulServiceRegistry, ConsulServiceRegistry>(); services.AddSingleton <IConsulRegistration>((p) => { var opts = p.GetRequiredService <IOptions <ConsulDiscoveryOptions> >(); var appInfo = services.GetApplicationInstanceInfo(); return(ConsulRegistration.CreateRegistration(opts.Value, appInfo)); }); services.AddSingleton <IConsulServiceRegistrar, ConsulServiceRegistrar>(); services.AddSingleton <IDiscoveryClient, ConsulDiscoveryClient>(); services.AddSingleton <IHealthContributor, ConsulHealthContributor>(); }
private static void AddConsulServices(ContainerBuilder container, IConfiguration config, IDiscoveryLifecycle lifecycle) { container.Register(c => { var opts = c.Resolve <IOptions <ConsulOptions> >(); return(ConsulClientFactory.CreateClient(opts.Value)); }).As <IConsulClient>().SingleInstance(); container.RegisterType <TtlScheduler>().As <IScheduler>().SingleInstance(); container.RegisterType <ConsulServiceRegistry>().As <IConsulServiceRegistry>().SingleInstance(); container.Register(c => { var opts = c.Resolve <IOptions <ConsulDiscoveryOptions> >(); return(ConsulRegistration.CreateRegistration(config, opts.Value)); }).As <IConsulRegistration>().SingleInstance(); container.RegisterType <ConsulServiceRegistrar>().As <IConsulServiceRegistrar>().SingleInstance(); container.RegisterType <ConsulDiscoveryClient>().As <IDiscoveryClient>().SingleInstance(); container.RegisterType <ConsulHealthContributor>().As <IHealthContributor>().SingleInstance(); }
public void AppName_SetAsExpected() { var options = new ConsulDiscoveryOptions(); var appsettings = new Dictionary <string, string>(); var config = TestHelpers.GetConfigurationFromDictionary(appsettings); var appInstanceInfo = new ApplicationInstanceInfo(config); // default value is assembly name var result = ConsulRegistration.CreateRegistration(options, appInstanceInfo); Assert.Equal(TestHelpers.EntryAssemblyName.Replace(".", "-"), result.Service.Name); // followed by spring:application:name appsettings.Add("spring:application:name", "SpringApplicationName"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); appInstanceInfo = new ApplicationInstanceInfo(config); result = ConsulRegistration.CreateRegistration(options, appInstanceInfo); Assert.Equal("SpringApplicationName", result.Service.Name); // Platform app name overrides spring name appsettings.Add("application:name", "PlatformName"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); appInstanceInfo = new ApplicationInstanceInfo(config); result = ConsulRegistration.CreateRegistration(options, appInstanceInfo); Assert.Equal("PlatformName", result.Service.Name); // Consul-specific value beats generic value appsettings.Add("consul:serviceName", "ConsulServiceName"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); appInstanceInfo = new ApplicationInstanceInfo(config); result = ConsulRegistration.CreateRegistration(options, appInstanceInfo); Assert.Equal("ConsulServiceName", result.Service.Name); // Consul-discovery is highest priority appsettings.Add("consul:discovery:serviceName", "ConsulDiscoveryServiceName"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); appInstanceInfo = new ApplicationInstanceInfo(config); result = ConsulRegistration.CreateRegistration(options, appInstanceInfo); Assert.Equal("ConsulDiscoveryServiceName", result.Service.Name); }
public void GetDefaultInstanceId_ReturnsExpected() { var options = new ConsulDiscoveryOptions(); var appsettings = new Dictionary <string, string>() { { "consul:discovery:serviceName", "serviceName" } }; var config = TestHelpers.GetConfigurationFromDictionary(appsettings); var result = ConsulRegistration.GetDefaultInstanceId(new ApplicationInstanceInfo(config)); Assert.StartsWith("serviceName:", result); appsettings.Add("spring:application:instance_id", "springid"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); result = ConsulRegistration.GetDefaultInstanceId(new ApplicationInstanceInfo(config)); Assert.Equal("serviceName:springid", result); appsettings.Add("vcap:application:instance_id", "vcapid"); config = TestHelpers.GetConfigurationFromDictionary(appsettings); result = ConsulRegistration.GetDefaultInstanceId(new CloudFoundryApplicationOptions(config)); Assert.Equal("serviceName:vcapid", result); }
public void SetStatusAsync_ThrowsInvalidStatus() { var clientMoq = new Mock <IConsulClient>(); var agentMoq = new Mock <IAgentEndpoint>(); clientMoq.Setup(c => c.Agent).Returns(agentMoq.Object); var opts = new ConsulDiscoveryOptions(); var sch = new TtlScheduler(opts, clientMoq.Object); var builder = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }); var config = builder.Build(); var registration = ConsulRegistration.CreateRegistration(config, opts); var reg = new ConsulServiceRegistry(clientMoq.Object, opts, sch); Assert.ThrowsAsync <ArgumentException>(() => reg.SetStatusAsync(registration, string.Empty)); }
public void CreateCheck_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions(); var result = ConsulRegistration.CreateCheck(1234, options); Assert.NotNull(result); Assert.Equal(DateTimeConversions.ToTimeSpan(options.Heartbeat.Ttl), result.TTL); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout), result.DeregisterCriticalServiceAfter); options.Heartbeat = null; Assert.Throws <ArgumentException>(() => ConsulRegistration.CreateCheck(0, options)); int port = 1234; result = ConsulRegistration.CreateCheck(port, options); var uri = new Uri($"{options.Scheme}://{options.HostName}:{port}{options.HealthCheckPath}"); Assert.Equal(uri.ToString(), result.HTTP); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckInterval), result.Interval); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckTimeout), result.Timeout); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout), result.DeregisterCriticalServiceAfter); Assert.Equal(options.HealthCheckTlsSkipVerify, result.TLSSkipVerify); }
public void Constructor_Initializes() { AgentServiceRegistration serviceRegistration = new AgentServiceRegistration() { ID = "ID", Name = "foobar", Address = "test.foo.bar", Port = 1234, Tags = new string[] { "foo=bar" } }; ConsulDiscoveryOptions opts = new ConsulDiscoveryOptions(); ConsulRegistration registration = new ConsulRegistration(serviceRegistration, opts); ThisServiceInstance thiz = new ThisServiceInstance(registration); Assert.Equal("test.foo.bar", thiz.Host); Assert.Equal("foobar", thiz.ServiceId); Assert.False(thiz.IsSecure); Assert.Equal(1234, thiz.Port); Assert.Single(thiz.Metadata); Assert.Contains("foo", thiz.Metadata.Keys); Assert.Contains("bar", thiz.Metadata.Values); Assert.Equal(new Uri("http://test.foo.bar:1234"), thiz.Uri); }
public void GetInstanceId_ReturnsExpected() { var options = new ConsulDiscoveryOptions() { InstanceId = "instanceId" }; var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string>() { { "spring:application:name", "foobar" } }) .Build(); var result = ConsulRegistration.GetInstanceId(options, new ApplicationInstanceInfo(config)); Assert.Equal("instanceId", result); options.InstanceId = null; result = ConsulRegistration.GetInstanceId(options, new ApplicationInstanceInfo(config)); Assert.StartsWith("foobar-", result); }
public void Constructor_SetsProperties() { AgentServiceRegistration areg = new AgentServiceRegistration() { ID = "id", Name = "name", Address = "address", Port = 1234, Tags = new string[] { "foo=bar" } }; ConsulDiscoveryOptions options = new ConsulDiscoveryOptions(); var reg = new ConsulRegistration(areg, options); Assert.Equal("id", reg.InstanceId); Assert.Equal("name", reg.ServiceId); Assert.Equal("address", reg.Host); Assert.Equal(1234, reg.Port); Assert.Single(reg.Metadata); Assert.Contains("foo", reg.Metadata.Keys); Assert.Contains("bar", reg.Metadata.Values); Assert.False(reg.IsSecure); Assert.Equal(new Uri("http://address:1234"), reg.Uri); }
public IConsulRegistration CreateServiceRegistration(string serviceName, int port) { var registration = new ConsulRegistration(this._client, serviceName, port); return(registration); }
public static void RegisterToConsul(this IApplicationBuilder app) { ConsulRegistration.Register(app); }
public static Uri GetServiceAddress(this IApplicationBuilder app, ConsulConfig config) { return(ConsulRegistration.GetServiceAddress(app, config)); }