コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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>();
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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>();
        }
コード例 #7
0
        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();
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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));
        }