예제 #1
0
        public void ServiceEndpointBuildingCanBeCustomized()
        {
            var source = new ConsulConfigurationSource()
                         .UseCache(new InMemoryEmergencyCache())
                         .MapService("myservice1", "serviceEndpoints:v1:myservice", EndpointFormatters.Http, NodeSelectors.First);

            var consulState = new ConsulState();

            consulState = consulState.UpdateService(new Service
            {
                Name  = "myservice1",
                Nodes = new[]
                {
                    new ServiceNode
                    {
                        Address = "myaddress",
                        Port    = 80
                    },
                }
            });

            var configProvider = _consul.LoadConfigProvider(source, consulState);

            string serviceEndpoint;

            configProvider.TryGet("serviceEndpoints:v1:myservice", out serviceEndpoint).Should().BeTrue();
            serviceEndpoint.Should().Be("http://myaddress:80");
        }
예제 #2
0
        public void Render(string templatePath, TextWriter writer, ConsulState model, PropertyBag properties = null)
        {
            var metadata = GetTemplateMetadata(templatePath);
            var instance = CreateTemplateInstance(metadata.FullTypeName, templatePath);

            instance.Render(writer, model, this, properties);
        }
예제 #3
0
 public void Render(TextWriter writer, ConsulState model, ITemplateRenderer renderer, PropertyBag properties)
 {
     Writer     = writer;
     Model      = model;
     Renderer   = renderer;
     Properties = properties ?? new PropertyBag();
     ExecuteAsync().GetAwaiter().GetResult();
 }
예제 #4
0
        public void IndividualKeyBeRetrievedViaMappedConfigKey()
        {
            var source = new ConsulConfigurationSource()
                         .UseCache(new InMemoryEmergencyCache())
                         .MapKey("apps/myapp/myfeature", "consul:afeature");

            var consulState = new ConsulState();

            consulState = consulState.UpdateKVNode(new KeyValueNode("apps/myapp/myfeature", "myvalue"));

            var configProvider = _consul.LoadConfigProvider(source, consulState);

            VerifyConfigKey(configProvider, "consul:afeature", "myvalue");
        }
예제 #5
0
        public async Task LoadAsync()
        {
            var eventContext = new EventContext("ConsulRx.Configuration", "Load");

            try
            {
                _consulState = await _consulClient.GetDependenciesAsync(_dependencies).ConfigureAwait(false);

                UpdateData();
                eventContext["LoadedFrom"] = "Consul";
            }
            catch (Exception exception)
            {
                eventContext.IncludeException(exception);
                if (_emergencyCache.TryLoad(out var cachedData))
                {
                    eventContext["LoadedFrom"] = "EmergencyCache";
                    Data = cachedData;
                }
                else
                {
                    eventContext["LoadedFrom"] = "UnableToLoad";
                    throw new ConsulRxConfigurationException("Unable to load configuration from consul. It is likely down or the endpoint is misconfigured. Please check the InnerException for details.", exception);
                }
            }
            finally
            {
                eventContext.Dispose();
            }

            if (_autoUpdate)
            {
                _consulClient.ObserveDependencies(_dependencies).DelayedRetry(_consulClient.Configuration.RetryDelay ?? TimeSpan.Zero).Subscribe(updatedState =>
                {
                    using (var reloadEventContext = new EventContext("ConsulRx.Configuration", "Reload"))
                    {
                        try
                        {
                            _consulState = updatedState;
                            UpdateData();
                            OnReload();
                        }
                        catch (Exception ex)
                        {
                            reloadEventContext.IncludeException(ex);
                        }
                    }
                });
            }
        }
예제 #6
0
        public ConsulDependencies AnalyzeDependencies(PropertyBag properties, ITemplateRenderer renderer)
        {
            AnalysisMode = true;
            try
            {
                Dependencies = new ConsulDependencies();
                Model        = new ConsulState();
                Properties   = properties ?? new PropertyBag();
                Renderer     = renderer;
                ExecuteAsync().GetAwaiter().GetResult();

                return(Dependencies);
            }
            finally
            {
                AnalysisMode = false;
            }
        }
예제 #7
0
        public void NoRegisteredNodesThrowsWhenUsingFirstNodeSelector()
        {
            Assert.Throws <ConsulRxConfigurationException>(() =>
            {
                var source = new ConsulConfigurationSource()
                             .UseCache(new InMemoryEmergencyCache())
                             .MapService("missingservice", "serviceEndpoints:v1:myservice", EndpointFormatters.Http, NodeSelectors.First);

                var consulState = new ConsulState();
                consulState     = consulState.UpdateService(new Service
                {
                    Name  = "missingservice",
                    Nodes = new ServiceNode[0]
                });

                var configProvider = _consul.LoadConfigProvider(source, consulState);
            });
        }
예제 #8
0
        public Task Start(CancellationToken cancellationToken = default(CancellationToken))
        {
            var completionSource   = new TaskCompletionSource <object>();
            var consulDependencies = _renderer.AnalyzeDependencies(TemplatePath, Properties);
            var subscription       = _client.ObserveDependencies(consulDependencies).Subscribe(consulState =>
            {
                ConsulState = consulState;
                RenderTemplate();
            }, onError: exception =>
            {
                completionSource.SetException(exception);
            }, onCompleted: () =>
            {
                completionSource.SetResult(null);
            });

            cancellationToken.Register(() => subscription.Dispose());

            return(completionSource.Task);
        }
예제 #9
0
        public void TreeOfKeysBeRetrievedViaMappedConfigPrefix()
        {
            var source = new ConsulConfigurationSource()
                         .UseCache(new InMemoryEmergencyCache())
                         .MapKeyPrefix("apps/myapp", "consul");

            var consulState = new ConsulState();

            consulState = consulState.UpdateKVNodes(new[]
            {
                new KeyValueNode("apps/myapp/folder1/item1", "value1"),
                new KeyValueNode("apps/myapp/folder1/item2", "value2"),
                new KeyValueNode("apps/myapp/folder2/item1", "value3")
            });

            var configProvider = _consul.LoadConfigProvider(source, consulState);

            VerifyConfigKey(configProvider, "consul:folder1:item1", "value1");
            VerifyConfigKey(configProvider, "consul:folder1:item2", "value2");
            VerifyConfigKey(configProvider, "consul:folder2:item1", "value3");
        }
예제 #10
0
        public void ConfigurationKeysBeRetrievedViaMappedConfigPrefix()
        {
            var source = new ConsulConfigurationSource()
                         .UseCache(new InMemoryEmergencyCache())
                         .MapConfigurationKey("apps/myapp/myconfig", "consulConf");

            var json = @"{""key1"":""value1"",""key2"": {
        ""key3"": {
            ""key4"": ""val4"",
            ""key5"": ""val5""
        }
    },}";

            var consulState = new ConsulState();

            consulState = consulState.UpdateKVNode(new KeyValueNode("apps/myapp/myconfig", json));

            var configProvider = _consul.LoadConfigProvider(source, consulState);

            VerifyConfigKey(configProvider, "consulConf", json);
        }
예제 #11
0
        public void ServiceEndpointsCanBeACollection()
        {
            var source = new ConsulConfigurationSource()
                         .UseCache(new InMemoryEmergencyCache())
                         .MapService("myservice1", "serviceEndpoints:v1:myservice", EndpointFormatters.AddressAndPort, NodeSelectors.All);

            var consulState = new ConsulState();

            consulState = consulState.UpdateService(new Service
            {
                Name  = "myservice1",
                Nodes = new[]
                {
                    new ServiceNode
                    {
                        Address = "myaddress",
                        Port    = 80
                    },
                    new ServiceNode
                    {
                        Address = "anotheraddress",
                        Port    = 8080
                    }
                }
            });

            var configProvider = _consul.LoadConfigProvider(source, consulState);

            string serviceEndpoint;

            configProvider.TryGet("serviceEndpoints:v1:myservice:0", out serviceEndpoint).Should().BeTrue();
            serviceEndpoint.Should().Be("myaddress:80");

            configProvider.TryGet("serviceEndpoints:v1:myservice:1", out serviceEndpoint).Should().BeTrue();
            serviceEndpoint.Should().Be("anotheraddress:8080");
        }
        public static IConfigurationProvider LoadConfigProvider(this FakeObservableConsul consul, ConsulConfigurationSource configSource, ConsulState consulState = null)
        {
            var configProvider = (ConsulConfigurationProvider)configSource.Build(consul);

            if (consulState != null)
            {
                consul.CurrentState = consulState;
            }
            Task.WhenAll(configProvider.LoadAsync(), Task.Run(() =>
            {
                consul.DependencyObservations.OnNext(consulState);
            })).GetAwaiter().GetResult();

            return(configProvider);
        }
예제 #13
0
        public void RenderPartial(string name, string parentTemplatePath, TextWriter writer, ConsulState model, PropertyBag properties)
        {
            var templatePath = ResolvePartial(name, parentTemplatePath);

            Render(templatePath, writer, model, properties);
        }