diff --git a/.EditorConfig b/.EditorConfig index 67c3a81..a351235 100644 --- a/.EditorConfig +++ b/.EditorConfig @@ -1,4 +1,4 @@ -# ASP.NET Core EditorConfig file +# ASP.NET Core EditorConfig file # NOTE: This file focuses on settings Visual Studio 2017 supports natively. For example, VS does not support insert_final_newline. # We do use it, but it's harder to enforce without a separate VS extension or an editor that supports it. @@ -26,7 +26,7 @@ indent_size = 2 # .NET Code Style Settings # See https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference # REVIEW: Should these be errors? warnings? suggestions? -[*.cs,*.vb] +[{*.cs,*.vb}] dotnet_sort_system_directives_first = true # Don't use 'this.'/'Me.' prefix for anything diff --git a/CondenserDotNet.sln b/CondenserDotNet.sln index bc255c1..16a2b4d 100644 --- a/CondenserDotNet.sln +++ b/CondenserDotNet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26228.9 +VisualStudioVersion = 15.0.26403.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CB18CD55-85E2-46FC-A55B-7DE23EABFAE5}" EndProject @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{35C5 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{32AEF73B-E6B6-48DF-BF84-16FFB8A9DF04}" ProjectSection(SolutionItems) = preProject + .EditorConfig = .EditorConfig .travis.yml = .travis.yml appveyor.yml = appveyor.yml common.props = common.props @@ -67,9 +68,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Release Notes", "Release No releasenotes\2.1.2.props = releasenotes\2.1.2.props releasenotes\2.1.3.props = releasenotes\2.1.3.props releasenotes\2.2.0.props = releasenotes\2.2.0.props + releasenotes\2.3.0.props = releasenotes\2.3.0.props + releasenotes\2.4.0.props = releasenotes\2.4.0.props EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Condenser.FullFramework", "test\Condenser.FullFramework\Condenser.FullFramework.csproj", "{6E7DD120-4D6A-4BB0-B78C-AA5D5D4CFB78}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Condenser.FullFramework", "test\Condenser.FullFramework\Condenser.FullFramework.csproj", "{6E7DD120-4D6A-4BB0-B78C-AA5D5D4CFB78}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/releasenotes/2.4.0.props b/releasenotes/2.4.0.props new file mode 100644 index 0000000..3836420 --- /dev/null +++ b/releasenotes/2.4.0.props @@ -0,0 +1,12 @@ + + + +* Added a callback on the leadership to give current leader +* Added maint mode enable/disable on the service manager +* Added middleware + * Puts it in maint mode + * Performs the cleanshutdown + * Takes it out of maint mode after startup + + + \ No newline at end of file diff --git a/src/CondenserDotNet.Client/GlobalSuppressions.cs b/src/CondenserDotNet.Client/GlobalSuppressions.cs new file mode 100644 index 0000000..74ae9dc --- /dev/null +++ b/src/CondenserDotNet.Client/GlobalSuppressions.cs @@ -0,0 +1,8 @@ + +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~P:CondenserDotNet.Client.DataContracts.HealthCheck.tls_skip_verify")] + diff --git a/src/CondenserDotNet.Client/HealthConfiguration.cs b/src/CondenserDotNet.Client/HealthConfiguration.cs index 10e5044..688ecbc 100644 --- a/src/CondenserDotNet.Client/HealthConfiguration.cs +++ b/src/CondenserDotNet.Client/HealthConfiguration.cs @@ -15,7 +15,7 @@ public HealthCheck Build(IServiceManager manager) if (Url == null) return null; if (!Uri.TryCreate(Url, UriKind.Absolute, out Uri uri)) { - string scheme = manager.ProtocolSchemeTag ?? "http"; + var scheme = manager.ProtocolSchemeTag ?? "http"; var builder = new UriBuilder(scheme, manager.ServiceAddress, manager.ServicePort, Url); uri = builder.Uri; } diff --git a/src/CondenserDotNet.Client/Leadership/LeaderWatcher.cs b/src/CondenserDotNet.Client/Leadership/LeaderWatcher.cs index 19d8ea6..d0d462d 100644 --- a/src/CondenserDotNet.Client/Leadership/LeaderWatcher.cs +++ b/src/CondenserDotNet.Client/Leadership/LeaderWatcher.cs @@ -63,7 +63,7 @@ private async Task TryForElection() { _electedLeaderEvent.Set(true); } - for (int i = 0; i < 2; i++) + for (var i = 0; i < 2; i++) { leaderResult = await _serviceManager.Client.GetAsync($"{KeyPath}{_keyToWatch}?index={consulIndex}"); if (!leaderResult.IsSuccessStatusCode) @@ -93,9 +93,8 @@ private async Task TryForElection() } } - private StringContent GetServiceInformation() - { - return HttpUtils.GetStringContent(new InformationService() + private StringContent GetServiceInformation() => + HttpUtils.GetStringContent(new InformationService() { Address = _serviceManager.ServiceAddress, ID = _serviceManager.ServiceId, @@ -103,12 +102,11 @@ private StringContent GetServiceInformation() Service = _serviceManager.ServiceName, Tags = _serviceManager.RegisteredService.Tags.ToArray() }); - } private StringContent GetCreateSession() { - string[] checks = new string[_serviceManager.RegisteredService.Checks.Count + 1]; - for (int i = 0; i < _serviceManager.RegisteredService.Checks.Count; i++) + var checks = new string[_serviceManager.RegisteredService.Checks.Count + 1]; + for (var i = 0; i < _serviceManager.RegisteredService.Checks.Count; i++) { checks[i] = _serviceManager.RegisteredService.Checks[i].Name; } diff --git a/src/CondenserDotNet.Client/MaintenanceExtensions.cs b/src/CondenserDotNet.Client/MaintenanceExtensions.cs new file mode 100644 index 0000000..18aa78c --- /dev/null +++ b/src/CondenserDotNet.Client/MaintenanceExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace CondenserDotNet.Client +{ + public static class MaintenanceExtensions + { + private const string _url = "/v1/agent/service/maintenance/"; + + public static Task EnableMaintenanceModeAsync(this IServiceManager manager, string reason) + { + var url = _url + $"{manager.ServiceId}?enable=true&reason={Uri.EscapeDataString(reason)}"; + return manager.Client.PutAsync(url, null); + } + + public static Task DisableMaintenanceModeAsync(this IServiceManager manager) + { + var url = _url + $"{manager.ServiceId}?enable=false"; + return manager.Client.PutAsync(url, new StringContent(string.Empty)); + } + } +} diff --git a/src/CondenserDotNet.Client/RegistrationExtensions.cs b/src/CondenserDotNet.Client/RegistrationExtensions.cs index 27d59d9..b608fda 100644 --- a/src/CondenserDotNet.Client/RegistrationExtensions.cs +++ b/src/CondenserDotNet.Client/RegistrationExtensions.cs @@ -19,7 +19,6 @@ public static IServiceManager AddHttpHealthCheck(this IServiceManager serviceMan { serviceManager.HealthConfig.Url = url; serviceManager.HealthConfig.IntervalInSeconds = intervalInSeconds; - return serviceManager; } @@ -82,7 +81,7 @@ public static async Task RegisterServiceAsync(this IServiceManager service } if (s.Checks.Count > 1) { - for (int i = 0; i < s.Checks.Count; i++) + for (var i = 0; i < s.Checks.Count; i++) { s.Checks[i].Name = $"service:{s.ID}:{i + 1}"; if (serviceManager.DeregisterIfCriticalAfter != default(TimeSpan)) diff --git a/src/CondenserDotNet.Client/ServiceManager.cs b/src/CondenserDotNet.Client/ServiceManager.cs index 7294b3b..bf366e6 100644 --- a/src/CondenserDotNet.Client/ServiceManager.cs +++ b/src/CondenserDotNet.Client/ServiceManager.cs @@ -67,7 +67,7 @@ protected void Dispose(bool disposing) _disposed = true; } } - + ~ServiceManager() => Dispose(false); } } diff --git a/src/CondenserDotNet.Client/ServiceManagerConfig.cs b/src/CondenserDotNet.Client/ServiceManagerConfig.cs index 9a522cd..43f6bfe 100644 --- a/src/CondenserDotNet.Client/ServiceManagerConfig.cs +++ b/src/CondenserDotNet.Client/ServiceManagerConfig.cs @@ -22,7 +22,7 @@ public class ServiceManagerConfig public static int GetNextAvailablePort() { var l = new TcpListener(IPAddress.Loopback, 0); - int port = 0; + var port = 0; try { l.Start(); diff --git a/src/CondenserDotNet.Client/Services/NoServiceInstanceFoundException.cs b/src/CondenserDotNet.Client/Services/NoServiceInstanceFoundException.cs index 8e0b79e..08f8919 100644 --- a/src/CondenserDotNet.Client/Services/NoServiceInstanceFoundException.cs +++ b/src/CondenserDotNet.Client/Services/NoServiceInstanceFoundException.cs @@ -5,10 +5,7 @@ namespace CondenserDotNet.Client.Services public class NoServiceInstanceFoundException : Exception { public NoServiceInstanceFoundException(string serviceName, Exception innerException) - : base($"Unable to find an instance of the service {serviceName}", innerException) - { - ServiceName = serviceName; - } + : base($"Unable to find an instance of the service {serviceName}", innerException) => ServiceName = serviceName; public string ServiceName { get; } public override string ToString() => Message; diff --git a/src/CondenserDotNet.Client/Services/ServiceWatcher.cs b/src/CondenserDotNet.Client/Services/ServiceWatcher.cs index 86db21b..72f0ab6 100644 --- a/src/CondenserDotNet.Client/Services/ServiceWatcher.cs +++ b/src/CondenserDotNet.Client/Services/ServiceWatcher.cs @@ -25,8 +25,7 @@ internal class ServiceWatcher : IDisposable private static int s_getServiceDelay = 3000; private Action> _listCallback; - internal ServiceWatcher(string serviceName, HttpClient client, - IRoutingStrategy routingStrategy, ILogger logger) + internal ServiceWatcher(string serviceName, HttpClient client, IRoutingStrategy routingStrategy, ILogger logger) { _serviceName = serviceName; _logger = logger; @@ -69,7 +68,7 @@ private async Task WatcherLoop(HttpClient client) { try { - string consulIndex = "0"; + var consulIndex = "0"; while (!_cancelationToken.Token.IsCancellationRequested) { var result = await client.GetAsync(_url + consulIndex, _cancelationToken.Token); diff --git a/src/CondenserDotNet.Configuration/ConfigurationRegistryExtensions.cs b/src/CondenserDotNet.Configuration/ConfigurationRegistryExtensions.cs index 6346fa9..1e27fea 100644 --- a/src/CondenserDotNet.Configuration/ConfigurationRegistryExtensions.cs +++ b/src/CondenserDotNet.Configuration/ConfigurationRegistryExtensions.cs @@ -5,9 +5,6 @@ namespace CondenserDotNet.Configuration { public static class ConfigurationRegistryExtensions { - public static Task SetKeyJsonAsync(this IConfigurationRegistry self, string key, T value) - { - return self.SetKeyAsync(key, JsonConvert.SerializeObject(value)); - } + public static Task SetKeyJsonAsync(this IConfigurationRegistry self, string key, T value) => self.SetKeyAsync(key, JsonConvert.SerializeObject(value)); } } \ No newline at end of file diff --git a/src/CondenserDotNet.Configuration/ConfigurationRegistrySource.cs b/src/CondenserDotNet.Configuration/ConfigurationRegistrySource.cs index 39e7cff..22c9cbd 100644 --- a/src/CondenserDotNet.Configuration/ConfigurationRegistrySource.cs +++ b/src/CondenserDotNet.Configuration/ConfigurationRegistrySource.cs @@ -6,14 +6,8 @@ public class ConfigurationRegistrySource : IConfigurationSource { private readonly IConfigurationRegistry _configurationRegistry; - public ConfigurationRegistrySource(IConfigurationRegistry configurationRegistry) - { - _configurationRegistry = configurationRegistry; - } + public ConfigurationRegistrySource(IConfigurationRegistry configurationRegistry) => _configurationRegistry = configurationRegistry; - public IConfigurationProvider Build(IConfigurationBuilder builder) - { - return new ConfigurationRegistryProvider(_configurationRegistry); - } + public IConfigurationProvider Build(IConfigurationBuilder builder) => new ConfigurationRegistryProvider(_configurationRegistry); } } \ No newline at end of file diff --git a/src/CondenserDotNet.Configuration/Consul/ConsulRegistry.cs b/src/CondenserDotNet.Configuration/Consul/ConsulRegistry.cs index 6a0d6b4..bec1002 100644 --- a/src/CondenserDotNet.Configuration/Consul/ConsulRegistry.cs +++ b/src/CondenserDotNet.Configuration/Consul/ConsulRegistry.cs @@ -43,10 +43,7 @@ public ConsulRegistry(IOptions agentConfig) /// This returns a flattened list of all the loaded keys /// public IEnumerable AllKeys => _configKeys.SelectMany(x => x.Keys); - public void UpdateKeyParser(IKeyParser parser) - { - _parser = parser; - } + public void UpdateKeyParser(IKeyParser parser) => _parser = parser; /// /// This loads the keys from a path. They are not updated. @@ -95,7 +92,7 @@ private async Task WatchingLoop(int indexOfDictionary, string keyPath) try { var consulIndex = "0"; - string url = $"{ConsulKeyPath}{keyPath}?recurse&wait=300s&index="; + var url = $"{ConsulKeyPath}{keyPath}?recurse&wait=300s&index="; while (true) { var response = await _httpClient.GetAsync(url + consulIndex, _disposed.Token); @@ -184,7 +181,7 @@ public bool TryGetValue(string key, out string value) { lock (_configKeys) { - for (int i = _configKeys.Count - 1; i >= 0; i--) + for (var i = _configKeys.Count - 1; i >= 0; i--) { if (_configKeys[i].TryGetValue(key, out value)) { @@ -244,7 +241,7 @@ public static string GetConsulIndex(HttpResponseMessage response) public static string StripFrontAndBackSlashes(string inputString) { - int startIndex = inputString.StartsWith("/") ? 1 : 0; + var startIndex = inputString.StartsWith("/") ? 1 : 0; return inputString.Substring(startIndex, (inputString.Length - startIndex) - (inputString.EndsWith("/") ? 1 : 0)); } diff --git a/src/CondenserDotNet.Configuration/Consul/JsonKeyValueParser.cs b/src/CondenserDotNet.Configuration/Consul/JsonKeyValueParser.cs index 3b8c9ba..ec03d72 100644 --- a/src/CondenserDotNet.Configuration/Consul/JsonKeyValueParser.cs +++ b/src/CondenserDotNet.Configuration/Consul/JsonKeyValueParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -52,10 +52,7 @@ private void VisitJObject(JObject jObject) } } - private void VisitProperty(JProperty property) - { - VisitToken(property.Value); - } + private void VisitProperty(JProperty property) => VisitToken(property.Value); private void VisitToken(JToken token) { diff --git a/src/CondenserDotNet.Configuration/ServiceCollectionExtensions.cs b/src/CondenserDotNet.Configuration/ServiceCollectionExtensions.cs index ec7b434..b174fd2 100644 --- a/src/CondenserDotNet.Configuration/ServiceCollectionExtensions.cs +++ b/src/CondenserDotNet.Configuration/ServiceCollectionExtensions.cs @@ -7,16 +7,11 @@ namespace CondenserDotNet.Configuration public static class ServiceCollectionExtensions { - public static IServiceCollection ConfigureReloadable(this IServiceCollection self, - IConfiguration configuration, IConfigurationRegistry registry) - where TConfig : class - { - return self.ConfigureReloadable(configuration, registry, typeof(TConfig).Name); - } + public static IServiceCollection ConfigureReloadable(this IServiceCollection self, IConfiguration configuration, IConfigurationRegistry registry) + where TConfig : class => + self.ConfigureReloadable(configuration, registry, typeof(TConfig).Name); - public static IServiceCollection ConfigureReloadable(this IServiceCollection self, - IConfiguration configuration, IConfigurationRegistry registry, - string sectionName) + public static IServiceCollection ConfigureReloadable(this IServiceCollection self, IConfiguration configuration, IConfigurationRegistry registry, string sectionName) where TConfig : class { var initialised = false; @@ -28,13 +23,11 @@ public static IServiceCollection ConfigureReloadable(this IServiceColle var section = configuration.GetSection(sectionName); section.Bind(config); }; - if (!initialised) { registry.AddWatchOnEntireConfig(bind); initialised = true; } - bind(); }); diff --git a/src/CondenserDotNet.Core/DataContracts/InformationService.cs b/src/CondenserDotNet.Core/DataContracts/InformationService.cs index 6b32e70..1ee5848 100644 --- a/src/CondenserDotNet.Core/DataContracts/InformationService.cs +++ b/src/CondenserDotNet.Core/DataContracts/InformationService.cs @@ -12,22 +12,10 @@ public class InformationService : IEquatable public bool Equals(InformationService other) { - if (Address != other.Address) - { - return false; - } - if (Port != other.Port) - { - return false; - } - if (Service != other.Service) - { - return false; - } - if (ID != other.ID) - { - return false; - } + if (Address != other.Address) return false; + if (Port != other.Port) return false; + if (Service != other.Service) return false; + if (ID != other.ID) return false; return true; } } diff --git a/src/CondenserDotNet.Core/HttpUtils.cs b/src/CondenserDotNet.Core/HttpUtils.cs index 1f78fa6..ced9122 100644 --- a/src/CondenserDotNet.Core/HttpUtils.cs +++ b/src/CondenserDotNet.Core/HttpUtils.cs @@ -63,7 +63,7 @@ public static string GetConsulIndex(this HttpResponseMessage response) public static string StripFrontAndBackSlashes(string inputString) { - int startIndex = inputString.StartsWith("/") ? 1 : 0; + var startIndex = inputString.StartsWith("/") ? 1 : 0; return inputString.Substring(startIndex, (inputString.Length - startIndex) - (inputString.EndsWith("/") ? 1 : 0)); } } diff --git a/src/CondenserDotNet.Core/ServiceUtils.cs b/src/CondenserDotNet.Core/ServiceUtils.cs index f65c020..93a1026 100644 --- a/src/CondenserDotNet.Core/ServiceUtils.cs +++ b/src/CondenserDotNet.Core/ServiceUtils.cs @@ -6,8 +6,8 @@ public static class ServiceUtils public static string[] RoutesFromTags(string[] tags) { - int returnCount = 0; - for (int i = 0; i < tags.Length; i++) + var returnCount = 0; + for (var i = 0; i < tags.Length; i++) { if (!tags[i].StartsWith(UrlPrefix)) { @@ -17,7 +17,7 @@ public static string[] RoutesFromTags(string[] tags) } var returnValues = new string[returnCount]; returnCount = 0; - for (int i = 0; i < tags.Length; i++) + for (var i = 0; i < tags.Length; i++) { if (!tags[i].StartsWith(UrlPrefix)) { diff --git a/src/CondenserDotNet.Middleware.Pipelines/HttpRequestHelper.cs b/src/CondenserDotNet.Middleware.Pipelines/HttpRequestHelper.cs index 1a8f562..0fb251a 100644 --- a/src/CondenserDotNet.Middleware.Pipelines/HttpRequestHelper.cs +++ b/src/CondenserDotNet.Middleware.Pipelines/HttpRequestHelper.cs @@ -48,7 +48,7 @@ public static Task WriteBodyAsync(this IPipeConnection connection, HttpContext c private static async Task WriteBody(this IPipeConnection connection, HttpContext context) { - long bytesToWrite = context.Request.ContentLength.Value; + var bytesToWrite = context.Request.ContentLength.Value; while (bytesToWrite > 0) { var buffer = connection.Output.Alloc(1024); diff --git a/src/CondenserDotNet.Middleware.Pipelines/ServiceWithCustomClient.cs b/src/CondenserDotNet.Middleware.Pipelines/ServiceWithCustomClient.cs index 5f8feab..1fd4219 100644 --- a/src/CondenserDotNet.Middleware.Pipelines/ServiceWithCustomClient.cs +++ b/src/CondenserDotNet.Middleware.Pipelines/ServiceWithCustomClient.cs @@ -79,11 +79,8 @@ public async Task CallService(HttpContext context) System.Threading.Interlocked.Add(ref _totalRequestTime, sw.ElapsedMilliseconds); } - public override int GetHashCode() - { - return ServiceId.GetHashCode(); - } - + public override int GetHashCode() => ServiceId.GetHashCode(); + public override bool Equals(object obj) { if (obj is ServiceWithCustomClient otherService) @@ -101,10 +98,7 @@ public override bool Equals(object obj) return false; } - public void UpdateRoutes(string[] routes) - { - Routes = routes; - } + public void UpdateRoutes(string[] routes) => Routes = routes; public async Task Initialise(string serviceId, string nodeId, string[] tags, string address, int port) { @@ -136,10 +130,6 @@ public void Dispose() _waitUntilRequestsAreFinished.Dispose(); } - public StatsSummary GetSummary() - { - return _stats.GetSummary(); - } - + public StatsSummary GetSummary() => _stats.GetSummary(); } } diff --git a/src/CondenserDotNet.Middleware/CleanShutdown/CleanShutdownService.cs b/src/CondenserDotNet.Middleware/CleanShutdown/CleanShutdownService.cs index cabe622..80edce1 100644 --- a/src/CondenserDotNet.Middleware/CleanShutdown/CleanShutdownService.cs +++ b/src/CondenserDotNet.Middleware/CleanShutdown/CleanShutdownService.cs @@ -9,20 +9,9 @@ public class CleanShutdownService private int _shutdownTimeout = 2000; private ILogger _logger; - public CleanShutdownService(ILoggerFactory loggerFactory) - { - _logger = loggerFactory.CreateLogger(); - } - - public void StartRequest() - { - _requestsOutstanding.AddCount(); - } - - public void FinishRequest() - { - _requestsOutstanding.Signal(); - } + public CleanShutdownService(ILoggerFactory loggerFactory) => _logger = loggerFactory.CreateLogger(); + public void StartRequest() => _requestsOutstanding.AddCount(); + public void FinishRequest() => _requestsOutstanding.Signal(); public void Shutdown() { diff --git a/src/CondenserDotNet.Middleware/CondenserDotNet.Middleware.csproj b/src/CondenserDotNet.Middleware/CondenserDotNet.Middleware.csproj index 77145df..c213992 100644 --- a/src/CondenserDotNet.Middleware/CondenserDotNet.Middleware.csproj +++ b/src/CondenserDotNet.Middleware/CondenserDotNet.Middleware.csproj @@ -19,4 +19,7 @@ + + + \ No newline at end of file diff --git a/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownExtensions.cs b/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownExtensions.cs new file mode 100644 index 0000000..60ab815 --- /dev/null +++ b/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CondenserDotNet.Middleware.CleanShutdown; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; + +namespace CondenserDotNet.Middleware.ConsulCleanShutdown +{ + public static class ConsulShutdownExtensions + { + public static IServiceCollection AddConsulShutdown(this IServiceCollection serviceCollection) + { + serviceCollection.AddSingleton(); + return serviceCollection.AddCleanShutdown(); + } + + public static IApplicationBuilder UseConsulShutdown(this IApplicationBuilder appBuilder) + { + var appLifetime = appBuilder.ApplicationServices.GetService(); + var shutdownService = appBuilder.ApplicationServices.GetService(); + appLifetime.ApplicationStopping.Register(shutdownService.Stopping); + appLifetime.ApplicationStarted.Register(shutdownService.Started); + return appBuilder.UseCleanShutdown(); + } + } +} diff --git a/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownService.cs b/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownService.cs new file mode 100644 index 0000000..204d369 --- /dev/null +++ b/src/CondenserDotNet.Middleware/ConsulCleanShutdown/ConsulShutdownService.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CondenserDotNet.Client; + +namespace CondenserDotNet.Middleware.ConsulCleanShutdown +{ + public class ConsulShutdownService + { + private IServiceManager _serviceManager; + + public ConsulShutdownService(IServiceManager serviceManager) => _serviceManager = serviceManager; + + public void Stopping() => _serviceManager.EnableMaintenanceModeAsync(string.Empty).Wait(); + + public void Started() => _serviceManager.DisableMaintenanceModeAsync().Wait(); + } +} diff --git a/src/CondenserDotNet.Middleware/ProtocolSwitcher/BackToBackStream.cs b/src/CondenserDotNet.Middleware/ProtocolSwitcher/BackToBackStream.cs index 8388290..a207276 100644 --- a/src/CondenserDotNet.Middleware/ProtocolSwitcher/BackToBackStream.cs +++ b/src/CondenserDotNet.Middleware/ProtocolSwitcher/BackToBackStream.cs @@ -6,15 +6,12 @@ namespace CondenserDotNet.Middleware.ProtocolSwitcher { - public class BackToBackStream:Stream + public class BackToBackStream : Stream { private bool _usedFirstByte; private readonly Stream _innerStream; - public BackToBackStream(Stream innerStream) - { - _innerStream = innerStream; - } + public BackToBackStream(Stream innerStream) => _innerStream = innerStream; public byte FirstByte { get; set; } public override bool CanRead => _innerStream.CanRead; @@ -27,7 +24,7 @@ public BackToBackStream(Stream innerStream) public override int Read(byte[] buffer, int offset, int count) { - int returnCount = 0; + var returnCount = 0; if (!_usedFirstByte) { buffer[offset] = FirstByte; @@ -58,19 +55,10 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel return _innerStream.ReadAsync(buffer, offset, count, cancellationToken); } - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return _innerStream.WriteAsync(buffer, offset, count, cancellationToken); - } + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + _innerStream.WriteAsync(buffer, offset, count, cancellationToken); - public override void WriteByte(byte value) - { - _innerStream.WriteByte(value); - } - - protected override void Dispose(bool disposing) - { - _innerStream.Dispose(); - } + public override void WriteByte(byte value) => _innerStream.WriteByte(value); + protected override void Dispose(bool disposing) => _innerStream.Dispose(); } } diff --git a/src/CondenserDotNet.Middleware/TrailingHeaders/ChunkingStream.cs b/src/CondenserDotNet.Middleware/TrailingHeaders/ChunkingStream.cs index 899c947..8f6071b 100644 --- a/src/CondenserDotNet.Middleware/TrailingHeaders/ChunkingStream.cs +++ b/src/CondenserDotNet.Middleware/TrailingHeaders/ChunkingStream.cs @@ -20,25 +20,10 @@ public class ChunkingStream : Stream public Stream InnerStream { get => _innerStream; set => _innerStream = value; } public override void Flush() => _innerStream.Flush(); - public override Task FlushAsync(CancellationToken cancellationToken) - { - return _innerStream.FlushAsync(cancellationToken); - } - - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } - - public override void SetLength(long value) - { - throw new NotImplementedException(); - } + public override Task FlushAsync(CancellationToken cancellationToken) => _innerStream.FlushAsync(cancellationToken); + public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + public override void SetLength(long value) => throw new NotSupportedException(); public override void Write(byte[] buffer, int offset, int count) { diff --git a/src/CondenserDotNet.Middleware/WindowsAuthentication/AuthenticationConnectionFilter.cs b/src/CondenserDotNet.Middleware/WindowsAuthentication/AuthenticationConnectionFilter.cs index 6a83199..dcdccf4 100644 --- a/src/CondenserDotNet.Middleware/WindowsAuthentication/AuthenticationConnectionFilter.cs +++ b/src/CondenserDotNet.Middleware/WindowsAuthentication/AuthenticationConnectionFilter.cs @@ -8,15 +8,12 @@ public class AuthenticationConnectionFilter : IConnectionFilter { private IConnectionFilter _previous; - public AuthenticationConnectionFilter(IConnectionFilter previous) - { + public AuthenticationConnectionFilter(IConnectionFilter previous) => _previous = previous ?? throw new ArgumentNullException(); - } public async Task OnConnectionAsync(ConnectionFilterContext context) { await _previous.OnConnectionAsync(context); - var previousRequest = context.PrepareRequest; var feature = new WindowsAuthFeature(); var wrapper = new WindowsAuthStreamWrapper(context.Connection, feature); diff --git a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthFeature.cs b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthFeature.cs index eb8e877..f350af6 100644 --- a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthFeature.cs +++ b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthFeature.cs @@ -19,10 +19,7 @@ static WindowsAuthFeature() } } - public WindowsAuthFeature() - { - _handshake = new WindowsHandshake(_credentialsHandle); - } + public WindowsAuthFeature() => _handshake = new WindowsHandshake(_credentialsHandle); public WindowsIdentity Identity { get; set; } @@ -33,10 +30,7 @@ public void Dispose() Identity = null; } - public string ProcessHandshake(string tokenName, byte[] token) - { - return _handshake.AcceptSecurityToken(tokenName, token); - } + public string ProcessHandshake(string tokenName, byte[] token) => _handshake.AcceptSecurityToken(tokenName, token); public WindowsIdentity GetUser() { diff --git a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthStreamWrapper.cs b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthStreamWrapper.cs index 1e12c7e..553295a 100644 --- a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthStreamWrapper.cs +++ b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsAuthStreamWrapper.cs @@ -20,53 +20,27 @@ public WindowsAuthStreamWrapper(Stream inStream, WindowsAuthFeature authFeature) public override bool CanSeek => _innerStream.CanSeek; public override bool CanWrite => _innerStream.CanWrite; public override long Length => _innerStream.Length; - public override long Position { get { return _innerStream.Position; } set { _innerStream.Position = value; } } + public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; } public IWindowsAuthFeature AuthFeature => _authFeature; - public override void Flush() - { - _innerStream.Flush(); - } + public override void Flush() => _innerStream.Flush(); + public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count); + public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin); + public override void SetLength(long value) => _innerStream.SetLength(value); - public override int Read(byte[] buffer, int offset, int count) - { - return _innerStream.Read(buffer, offset, count); - } + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + _innerStream.ReadAsync(buffer, offset, count, cancellationToken); - public override long Seek(long offset, SeekOrigin origin) - { - return _innerStream.Seek(offset, origin); - } + public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => + _innerStream.CopyToAsync(destination, bufferSize, cancellationToken); - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return _innerStream.ReadAsync(buffer, offset, count, cancellationToken); - } + public override Task FlushAsync(CancellationToken cancellationToken) => + _innerStream.FlushAsync(cancellationToken); - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) - { - return _innerStream.CopyToAsync(destination, bufferSize, cancellationToken); - } + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + _innerStream.WriteAsync(buffer, offset, count, cancellationToken); - public override Task FlushAsync(CancellationToken cancellationToken) - { - return _innerStream.FlushAsync(cancellationToken); - } - - public override void SetLength(long value) - { - _innerStream.SetLength(value); - } - - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return _innerStream.WriteAsync(buffer, offset, count, cancellationToken); - } - - public override void Write(byte[] buffer, int offset, int count) - { - _innerStream.Write(buffer, offset, count); - } + public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count); protected override void Dispose(bool disposing) { diff --git a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsHandshake.cs b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsHandshake.cs index ab7d9f9..67fdd06 100644 --- a/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsHandshake.cs +++ b/src/CondenserDotNet.Middleware/WindowsAuthentication/WindowsHandshake.cs @@ -14,10 +14,7 @@ public sealed class WindowsHandshake : IDisposable private static readonly ASC_REQ _requestType = ASC_REQ.ASC_REQ_CONFIDENTIALITY | ASC_REQ.ASC_REQ_REPLAY_DETECT | ASC_REQ.ASC_REQ_SEQUENCE_DETECT | ASC_REQ.ASC_REQ_CONNECTION; - internal WindowsHandshake(SecurityHandle ntlmHandle) - { - _ntlmHandle = ntlmHandle; - } + internal WindowsHandshake(SecurityHandle ntlmHandle) => _ntlmHandle = ntlmHandle; public WindowsIdentity User => _identity; public DateTime DateStarted => _dateStarted; diff --git a/src/CondenserDotNet.Server.Extensions/ConfigurationBuilder.cs b/src/CondenserDotNet.Server.Extensions/ConfigurationBuilder.cs index e08b591..138c350 100644 --- a/src/CondenserDotNet.Server.Extensions/ConfigurationBuilder.cs +++ b/src/CondenserDotNet.Server.Extensions/ConfigurationBuilder.cs @@ -18,10 +18,7 @@ public class ConfigurationBuilder : IHealthConfig, IConfigurationBuilder, IRouti private int _agentPort = 8500; private Func _clientFactory; - public ConfigurationBuilder(IServiceCollection collection) - { - _collection = collection; - } + public ConfigurationBuilder(IServiceCollection collection) => _collection = collection; public List>> Checks { get; } = new List>>(); public string Route { get; private set; } = CondenserRoutes.HealthStats; diff --git a/src/CondenserDotNet.Server.Extensions/ServiceCollectionExtensions.cs b/src/CondenserDotNet.Server.Extensions/ServiceCollectionExtensions.cs index c7beaab..abf48d9 100644 --- a/src/CondenserDotNet.Server.Extensions/ServiceCollectionExtensions.cs +++ b/src/CondenserDotNet.Server.Extensions/ServiceCollectionExtensions.cs @@ -13,14 +13,12 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddCondenser(this IServiceCollection self) => AddCondenser(self, "localhost", 8500); - private static IServiceCollection AddCondenser(this IServiceCollection self, string agentAddress, int agentPort) - { - return self.AddCondenserWithBuilder() + private static IServiceCollection AddCondenser(this IServiceCollection self, string agentAddress, int agentPort) => + self.AddCondenserWithBuilder() .WithAgentAddress(agentAddress) .WithAgentPort(agentPort) .WithHttpClient(s => new HttpClient()) .Build(); - } public static IServiceCollection AddCondenser(this IServiceCollection self, string agentAddress, int agentPort, IHealthConfig health, IRoutingConfig routingConfig, IHttpClientConfig httpClientConfig) diff --git a/src/CondenserDotNet.Server/ConsulRouteSource.cs b/src/CondenserDotNet.Server/ConsulRouteSource.cs index 72faf11..5c6319b 100644 --- a/src/CondenserDotNet.Server/ConsulRouteSource.cs +++ b/src/CondenserDotNet.Server/ConsulRouteSource.cs @@ -29,10 +29,7 @@ public ConsulRouteSource(CondenserConfiguration config, _logger = logger?.CreateLogger(); } - public bool CanRequestRoute() - { - return !_cancel.IsCancellationRequested; - } + public bool CanRequestRoute() => !_cancel.IsCancellationRequested; public async Task<(bool success, HealthCheck[] checks)> TryGetHealthChecksAsync() { @@ -50,9 +47,6 @@ public bool CanRequestRoute() return (true, checks); } - public Task GetServiceInstancesAsync(string serviceName) - { - return _client.GetAsync(_serviceLookupUri + serviceName); - } + public Task GetServiceInstancesAsync(string serviceName) => _client.GetAsync(_serviceLookupUri + serviceName); } } diff --git a/src/CondenserDotNet.Server/CurrentState.cs b/src/CondenserDotNet.Server/CurrentState.cs index ab5c9dc..971ee3b 100644 --- a/src/CondenserDotNet.Server/CurrentState.cs +++ b/src/CondenserDotNet.Server/CurrentState.cs @@ -10,10 +10,7 @@ public class CurrentState : ICurrentState { private DateTime _startedTime; - public CurrentState() - { - _startedTime = DateTime.UtcNow; - } + public CurrentState() => _startedTime = DateTime.UtcNow; public StatsSummary GetSummary() { @@ -74,9 +71,6 @@ public void RecordResponse(int responseCode) } - public void ResetUptime() - { - _startedTime = DateTime.UtcNow; - } + public void ResetUptime() => _startedTime = DateTime.UtcNow; } } diff --git a/src/CondenserDotNet.Server/CustomRouter.cs b/src/CondenserDotNet.Server/CustomRouter.cs index c352013..da352dc 100644 --- a/src/CondenserDotNet.Server/CustomRouter.cs +++ b/src/CondenserDotNet.Server/CustomRouter.cs @@ -27,11 +27,8 @@ public IService GetServiceFromRoute(PathString path, out string matchedPath) return service; } - public void AddServiceToRoute(string route, IService serviceToAdd) - { - _routingData.Tree.AddServiceToRoute(route, serviceToAdd); - } - + public void AddServiceToRoute(string route, IService serviceToAdd) => _routingData.Tree.AddServiceToRoute(route, serviceToAdd); + public void AddNewService(IService serviceToAdd) { foreach (var r in serviceToAdd.Routes) diff --git a/src/CondenserDotNet.Server/DataContracts/Node.cs b/src/CondenserDotNet.Server/DataContracts/Node.cs index 517c8a2..a3ca2a7 100644 --- a/src/CondenserDotNet.Server/DataContracts/Node.cs +++ b/src/CondenserDotNet.Server/DataContracts/Node.cs @@ -4,7 +4,6 @@ namespace CondenserDotNet.Server.DataContracts { public class Node { - public string Path { get; set; } public string Services { get; set; } public string[] Prefix { get; set; } diff --git a/src/CondenserDotNet.Server/Extensions/HttpResponseExtensions.cs b/src/CondenserDotNet.Server/Extensions/HttpResponseExtensions.cs index c20100f..c2c314f 100644 --- a/src/CondenserDotNet.Server/Extensions/HttpResponseExtensions.cs +++ b/src/CondenserDotNet.Server/Extensions/HttpResponseExtensions.cs @@ -6,9 +6,6 @@ namespace CondenserDotNet.Server.Extensions { public static class HttpResponseExtensions { - public static Task WriteJsonAsync(this HttpResponse self, T item) - { - return self.WriteAsync(JsonConvert.SerializeObject(item)); - } + public static Task WriteJsonAsync(this HttpResponse self, T item) => self.WriteAsync(JsonConvert.SerializeObject(item)); } } diff --git a/src/CondenserDotNet.Server/RouteStore.cs b/src/CondenserDotNet.Server/RouteStore.cs index 2809254..1139887 100644 --- a/src/CondenserDotNet.Server/RouteStore.cs +++ b/src/CondenserDotNet.Server/RouteStore.cs @@ -22,52 +22,28 @@ public RouteStore(RoutingData routingData, Func serviceFactory, _statsFactory = statsFactory; } - public Dictionary> GetServices() - { - return _routingData.ServicesWithHealthChecks; - } + public void RemoveService(string serviceName) => _routingData.ServicesWithHealthChecks.Remove(serviceName); + public bool HasService(string serviceName) => _routingData.ServicesWithHealthChecks.ContainsKey(serviceName); + public void AddService(string serviceName) => _routingData.ServicesWithHealthChecks[serviceName] = new List(); + public Dictionary> GetServices() => _routingData.ServicesWithHealthChecks; + public ICurrentState[] GetStats() => _routingData.GetAllStats(); + public RadixTree GetTree() => _routingData.Tree; public List GetServiceInstances(string serviceName) { - if(!_routingData.ServicesWithHealthChecks.TryGetValue(serviceName, out List services)) + if (!_routingData.ServicesWithHealthChecks.TryGetValue(serviceName, out List services)) { services = Empty; } return services; } - - public void RemoveService(string serviceName) - { - _routingData.ServicesWithHealthChecks.Remove(serviceName); - } - - public bool HasService(string serviceName) - { - return _routingData.ServicesWithHealthChecks.ContainsKey(serviceName); - } - - public void AddService(string serviceName) - { - _routingData.ServicesWithHealthChecks[serviceName] = new List(); - } - + public Task CreateServiceInstanceAsync(ServiceInstance info) { var instance = _serviceFactory(); - return instance.Initialise(info.ServiceID, info.Node, info.ServiceTags, info.ServiceAddress, info.ServicePort) .ContinueWith(t => (IService)instance); } - - public ICurrentState[] GetStats() - { - return _routingData.GetAllStats(); - } - - public RadixTree GetTree() - { - return _routingData.Tree; - } } } diff --git a/src/CondenserDotNet.Server/Routes/HealthRouter.cs b/src/CondenserDotNet.Server/Routes/HealthRouter.cs index 2d50c88..787abcc 100644 --- a/src/CondenserDotNet.Server/Routes/HealthRouter.cs +++ b/src/CondenserDotNet.Server/Routes/HealthRouter.cs @@ -11,10 +11,7 @@ namespace CondenserDotNet.Server.Routes public sealed class HealthRouter : ServiceBase { - public HealthRouter() - { - Routes = new[] { CondenserRoutes.Health }; - } + public HealthRouter() => Routes = new[] { CondenserRoutes.Health }; public override string[] Routes { get; } public override IPEndPoint IpEndPoint => throw new NotImplementedException(); diff --git a/src/CondenserDotNet.Server/Routes/ServerStatisticsRoute.cs b/src/CondenserDotNet.Server/Routes/ServerStatisticsRoute.cs index 184c8dc..5918003 100644 --- a/src/CondenserDotNet.Server/Routes/ServerStatisticsRoute.cs +++ b/src/CondenserDotNet.Server/Routes/ServerStatisticsRoute.cs @@ -13,10 +13,7 @@ public class ServerStatsRoute : ServiceBase { private readonly IRouteStore _store; - public ServerStatsRoute(IRouteStore store) - { - _store = store; - } + public ServerStatsRoute(IRouteStore store) => _store = store; public override string[] Routes { get; } = { CondenserRoutes.Statistics }; public override bool RequiresAuthentication => true; @@ -52,20 +49,20 @@ public override async Task CallService(HttpContext context) Calls = usage.Calls, AverageRequestTime = averageRequestTime, LastRequest = usage.LastRequest, - LastRequestTime = usage.LastRequestTime, + LastRequestTime = usage.LastRequestTime, Summary = service.GetSummary() }; } context.Response.StatusCode = (int)HttpStatusCode.OK; await context.Response.WriteJsonAsync(response); - + } else { context.Response.StatusCode = (int)HttpStatusCode.NotFound; await context.Response.WriteAsync("Unknown server " + serviceName); - + } } else diff --git a/src/CondenserDotNet.Server/Routes/TreeRouter.cs b/src/CondenserDotNet.Server/Routes/TreeRouter.cs index 611ddf2..5ca2de9 100644 --- a/src/CondenserDotNet.Server/Routes/TreeRouter.cs +++ b/src/CondenserDotNet.Server/Routes/TreeRouter.cs @@ -17,7 +17,6 @@ public sealed class TreeRouter : ServiceBase public TreeRouter(RoutingData routingData) { _routingData = routingData; - Routes = new[] { CondenserRoutes.Tree }; } @@ -46,7 +45,7 @@ private void MapTo(Node node, Node dto) for (var i = 0; i < node.ChildrenNodes.Count; i++) { var nodeDto = new Node(); - string key = string.Join(",", node.ChildrenNodes.ElementAt(i).Item1); + var key = string.Join(",", node.ChildrenNodes.ElementAt(i).Item1); children.Add(key, nodeDto); MapTo(node.ChildrenNodes.ElementAt(i).Item2, nodeDto); } diff --git a/src/CondenserDotNet.Server/RoutingHost.cs b/src/CondenserDotNet.Server/RoutingHost.cs index 7584489..49211b3 100644 --- a/src/CondenserDotNet.Server/RoutingHost.cs +++ b/src/CondenserDotNet.Server/RoutingHost.cs @@ -61,7 +61,7 @@ private async Task WatchLoop() private async Task ProcessHealthChecksAsync(HealthCheck[] healthChecks) { _logger?.LogInformation("Total number of health checks returned was {healthCheckCount}", healthChecks.Length); - List infoList = BuildListOfHealthyServiceInstances(healthChecks); + var infoList = BuildListOfHealthyServiceInstances(healthChecks); RemoveDeadInstances(infoList); var services = _store.GetServices(); foreach (var service in services) @@ -112,7 +112,7 @@ private void UpdateExistingRoutes(IService instance, ServiceInstance info) private IService GetInstance(ServiceInstance service, List instanceList) { - for (int i = 0; i < instanceList.Count; i++) + for (var i = 0; i < instanceList.Count; i++) { if (instanceList[i].ServiceId == service.ServiceID) { @@ -154,7 +154,7 @@ private void RemoveDeadInstances(List infoList) private List BuildListOfHealthyServiceInstances(HealthCheck[] healthChecks) { - HashSet downNodes = new HashSet(); + var downNodes = new HashSet(); //Now we get all service instances that are working var infoList = new List(); foreach (var check in healthChecks) @@ -182,7 +182,7 @@ private List BuildListOfHealthyServiceInstances(HealthCheck[ private bool HasInstance(string serviceID, List infoList) { - for (int i = 0; i < infoList.Count; i++) + for (var i = 0; i < infoList.Count; i++) { if (infoList[i].ID == serviceID) { diff --git a/src/CondenserDotNet.Server/RoutingTrie/Node.cs b/src/CondenserDotNet.Server/RoutingTrie/Node.cs index 3b44e06..4c04c0b 100644 --- a/src/CondenserDotNet.Server/RoutingTrie/Node.cs +++ b/src/CondenserDotNet.Server/RoutingTrie/Node.cs @@ -50,7 +50,7 @@ public void AddRoute(string[] route, T service) } var children = System.Threading.Volatile.Read(ref _childrenNodes); - for (int i = Math.Min(children.KeyLength, route.Length); i > 0; i--) + for (var i = Math.Min(children.KeyLength, route.Length); i > 0; i--) { //We need to first see if the first part of the route matches any of the current nodes var matche = children.FindFirstNodeThatMatches(route, i); @@ -75,7 +75,7 @@ public void AddRoute(string[] route, T service) if (route.Length >= children.KeyLength) { //Create a new node and add it - Node n = new Node(route.Take(children.KeyLength).ToArray(), Path, _factory); + var n = new Node(route.Take(children.KeyLength).ToArray(), Path, _factory); n.AddRoute(route.Skip(children.KeyLength).ToArray(), service); var newChildren = children.Clone(); @@ -87,7 +87,7 @@ public void AddRoute(string[] route, T service) { //The key is smaller than the current key length so we are going to have to split before we add var newChildren = ChildrenNodes.SplitContainer(route.Length, Path); - Node n = new Node(route, Path, _factory); + var n = new Node(route, Path, _factory); n.AddRoute(new string[0], service); newChildren.Add(n.Prefix, n); @@ -100,7 +100,7 @@ public void AddRoute(string[] route, T service) internal bool RemoveServiceFromRoute(string[] route, T service) { - NodeContainer container = System.Threading.Volatile.Read(ref _childrenNodes); + var container = System.Threading.Volatile.Read(ref _childrenNodes); if (route.Length == 0) { return Services.RemoveService(service); @@ -158,7 +158,7 @@ public void Compress() { var children = System.Threading.Volatile.Read(ref _childrenNodes); if (children.Count == 0) return; - bool canCompress = CanCompress(children); + var canCompress = CanCompress(children); if (!canCompress) { foreach (var kv in children) diff --git a/src/CondenserDotNet.Server/RoutingTrie/NodeComparer.cs b/src/CondenserDotNet.Server/RoutingTrie/NodeComparer.cs index 12f0e53..8cac159 100644 --- a/src/CondenserDotNet.Server/RoutingTrie/NodeComparer.cs +++ b/src/CondenserDotNet.Server/RoutingTrie/NodeComparer.cs @@ -7,10 +7,7 @@ public class NodeComparer : IEqualityComparer { private readonly int _compareLength; - public NodeComparer(int compareLength) - { - _compareLength = compareLength; - } + public NodeComparer(int compareLength) => _compareLength = compareLength; public int CompareLength => _compareLength; @@ -21,7 +18,7 @@ public bool Equals(string[] x, string[] y) return false; } - for (int i = 0; i < _compareLength; i++) + for (var i = 0; i < _compareLength; i++) { if (x[i] != y[i]) return false; } @@ -33,7 +30,7 @@ public int GetHashCode(string[] obj) unchecked // Overflow is fine, just wrap { var hash = 17; - for (int i = 0; i < Math.Min(_compareLength, obj.Length); i++) + for (var i = 0; i < Math.Min(_compareLength, obj.Length); i++) { hash = hash * 23 + obj[i].GetHashCode(); } diff --git a/src/CondenserDotNet.Server/RoutingTrie/NodeContainer.cs b/src/CondenserDotNet.Server/RoutingTrie/NodeContainer.cs index 76fd398..b2466e0 100644 --- a/src/CondenserDotNet.Server/RoutingTrie/NodeContainer.cs +++ b/src/CondenserDotNet.Server/RoutingTrie/NodeContainer.cs @@ -94,7 +94,7 @@ public Node this[string[] key] public int MaxNodeDepth() { - int nodeDepth = 0; + var nodeDepth = 0; foreach (var n in _children) { nodeDepth = Math.Max(n.Item2.MaxDepth(), nodeDepth); diff --git a/src/CondenserDotNet.Server/Service.cs b/src/CondenserDotNet.Server/Service.cs index 0840afc..58f1756 100644 --- a/src/CondenserDotNet.Server/Service.cs +++ b/src/CondenserDotNet.Server/Service.cs @@ -53,7 +53,7 @@ public Service(Func clientFactory, ILoggerFactory logger, Ro public async Task CallService(HttpContext context) { - Stopwatch sw = new Stopwatch(); + var sw = new Stopwatch(); _waitUntilRequestsAreFinished.AddCount(); try { @@ -178,9 +178,6 @@ public void Dispose() _waitUntilRequestsAreFinished.Dispose(); } - public StatsSummary GetSummary() - { - return _stats.GetSummary(); - } + public StatsSummary GetSummary() => _stats.GetSummary(); } } diff --git a/src/CondenserDotNet.Server/ServiceBase.cs b/src/CondenserDotNet.Server/ServiceBase.cs index cab9558..81e0ef5 100644 --- a/src/CondenserDotNet.Server/ServiceBase.cs +++ b/src/CondenserDotNet.Server/ServiceBase.cs @@ -21,9 +21,6 @@ public virtual void UpdateRoutes(string[] routes) { } - public StatsSummary GetSummary() - { - return default(StatsSummary); - } + public StatsSummary GetSummary() => default(StatsSummary); } } diff --git a/test/Condenser.FullFramework/SwitcherRooFacts.cs b/test/Condenser.FullFramework/SwitcherRooFacts.cs index 9344770..af05e17 100644 --- a/test/Condenser.FullFramework/SwitcherRooFacts.cs +++ b/test/Condenser.FullFramework/SwitcherRooFacts.cs @@ -14,7 +14,7 @@ namespace Condenser.FullFramework public class SwitcherRooFacts { public static X509Certificate2 Certificate = new X509Certificate2(@"TestCert.pfx", "Test123t"); - + [Fact(Skip = "Full framework is broken on the switcher")] public async Task SwitcherooSeesHttpsFact() { @@ -39,7 +39,7 @@ public async Task SwitcherooSeesHttpsFact() return false; } }); - + var result = await client.GetAsync($"https://localhost:{port}"); var isHttp = await result.Content.ReadAsStringAsync(); Assert.True(bool.Parse(isHttp)); @@ -52,14 +52,12 @@ public async Task SwitcherooSeesHttpsFact() public class Startup { - public void Configure(IApplicationBuilder app) - { + public void Configure(IApplicationBuilder app) => app.Use(async (context, next) => { - await context.Response.WriteAsync(string.Join(",",Enumerable.Repeat("testingtesting", 100))); + await context.Response.WriteAsync(string.Join(",", Enumerable.Repeat("testingtesting", 100))); return; }); - } } } } diff --git a/test/Condenser.Tests.Integration/ConfigFacts.cs b/test/Condenser.Tests.Integration/ConfigFacts.cs index a5779ba..11a47d1 100644 --- a/test/Condenser.Tests.Integration/ConfigFacts.cs +++ b/test/Condenser.Tests.Integration/ConfigFacts.cs @@ -56,7 +56,7 @@ public async Task DontPickUpChangesFact() [Fact] public async Task PickUpChangesFact() { - string keyid = Guid.NewGuid().ToString(); + var keyid = Guid.NewGuid().ToString(); using (var configRegistry = new ConsulRegistry(null)) { await configRegistry.SetKeyAsync($"org/{keyid}/test2", _value1); @@ -76,7 +76,7 @@ public async Task PickUpChangesFact() public async Task GetCallbackForSpecificKey() { Console.WriteLine(nameof(GetCallbackForSpecificKey)); - string keyid = Guid.NewGuid().ToString(); + var keyid = Guid.NewGuid().ToString(); using (var configRegistry = new ConsulRegistry(null)) { var e = new ManualResetEvent(false); @@ -97,7 +97,7 @@ public async Task GetCallbackForSpecificKey() [Fact] public async Task GetCallbackForKeyThatIsAdded() { - string keyid = Guid.NewGuid().ToString(); + var keyid = Guid.NewGuid().ToString(); using (var configRegistry = new ConsulRegistry(null)) { var e = new ManualResetEvent(false); @@ -119,7 +119,7 @@ public async Task GetCallbackForKeyThatIsAdded() public async Task GetCallbackForAnyKey() { Console.WriteLine(nameof(GetCallbackForAnyKey)); - string keyid = Guid.NewGuid().ToString(); + var keyid = Guid.NewGuid().ToString(); using (var configRegistry = new ConsulRegistry(null)) { await configRegistry.SetKeyAsync($"org/{keyid}/test1", _value1); diff --git a/test/Condenser.Tests.Integration/LeadershipFacts.cs b/test/Condenser.Tests.Integration/LeadershipFacts.cs index 246b977..78558fb 100644 --- a/test/Condenser.Tests.Integration/LeadershipFacts.cs +++ b/test/Condenser.Tests.Integration/LeadershipFacts.cs @@ -49,7 +49,7 @@ public async Task TestLeadershipFailOver() var watcher1 = (new LeaderRegistry(manager)).GetLeaderWatcher(leadershipKey); await watcher1.GetLeadershipAsync(); - bool shouldNotBeLeader = true; + var shouldNotBeLeader = true; var resetEvent = new ManualResetEvent(false); //Now that 1 is the leader lets try to join 2 into the party diff --git a/test/Condenser.Tests.Integration/MaintenanceFacts.cs b/test/Condenser.Tests.Integration/MaintenanceFacts.cs new file mode 100644 index 0000000..5b27954 --- /dev/null +++ b/test/Condenser.Tests.Integration/MaintenanceFacts.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using CondenserDotNet.Client; +using CondenserDotNet.Client.Services; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Condenser.Tests.Integration +{ + public class MaintenanceFacts + { + [Fact] + public async Task TestIntoAndOutOfMaintenance() + { + var config = Options.Create(new ServiceManagerConfig()); + config.Value.ServiceAddress = "127.0.0.1"; + config.Value.ServicePort = 777; + config.Value.ServiceName = Guid.NewGuid().ToString(); + var manager = new ServiceManager(config); + await manager.RegisterServiceAsync(); + var registry = new ServiceRegistry(); + var instance = await registry.GetServiceInstanceAsync(config.Value.ServiceName); + + Assert.NotNull(instance); + await manager.EnableMaintenanceModeAsync("down"); + instance = await registry.GetServiceInstanceAsync(config.Value.ServiceName); + await Task.Delay(200); + + Assert.Null(instance); + await manager.DisableMaintenanceModeAsync(); + await Task.Delay(200); + instance = await registry.GetServiceInstanceAsync(config.Value.ServiceName); + Assert.NotNull(instance); + } + } +} diff --git a/test/Condenser.Tests.Integration/ProtocolSwitcherFacts.cs b/test/Condenser.Tests.Integration/ProtocolSwitcherFacts.cs index bb8dea5..2f62374 100644 --- a/test/Condenser.Tests.Integration/ProtocolSwitcherFacts.cs +++ b/test/Condenser.Tests.Integration/ProtocolSwitcherFacts.cs @@ -40,7 +40,7 @@ public async Task SwitcherooSeesHttpsFact() return true; } }); - + var result = await client.GetAsync($"https://localhost:{port}"); var isHttp = await result.Content.ReadAsStringAsync(); Assert.True(bool.Parse(isHttp)); @@ -88,14 +88,12 @@ public async Task SwitcherooSeesHttpFact() public class Startup { - public void Configure(IApplicationBuilder app) - { + public void Configure(IApplicationBuilder app) => app.Use(async (context, next) => { await context.Response.WriteAsync(context.Request.IsHttps.ToString()); return; }); - } } } } diff --git a/test/Condenser.Tests.Integration/Routing/RouterApiFacts.cs b/test/Condenser.Tests.Integration/Routing/RouterApiFacts.cs index a6f3abb..ba63f90 100644 --- a/test/Condenser.Tests.Integration/Routing/RouterApiFacts.cs +++ b/test/Condenser.Tests.Integration/Routing/RouterApiFacts.cs @@ -13,7 +13,7 @@ public class RouterApiFacts [Fact] public async Task CanCallRouterHealthCheck() { - using (RoutingFixture fixture = new RoutingFixture()) + using (var fixture = new RoutingFixture()) { var serviceName1 = fixture.GetNewServiceName(); var route1 = "/myservice3"; diff --git a/test/Condenser.Tests.Integration/Routing/RoutingFixture.cs b/test/Condenser.Tests.Integration/Routing/RoutingFixture.cs index 3d38d0b..1f3ad29 100644 --- a/test/Condenser.Tests.Integration/Routing/RoutingFixture.cs +++ b/test/Condenser.Tests.Integration/Routing/RoutingFixture.cs @@ -28,25 +28,12 @@ public class RoutingFixture : IDisposable private IWebHost _routerHost; private HttpClient _client = new HttpClient(); - public RoutingFixture() - { - Console.WriteLine("Created Routing Fixture"); - } - - public void SetServiceHealth(string name, bool isHealthy) - { - _hosts[name].IsHealthy = isHealthy; - } - - public string GetNewServiceName() - { - return Guid.NewGuid().ToString("N").Substring(0, 10); - } - - public Task CallRouterAsync(string route) - { - return _client.GetAsync($"http://localhost:{routerPort}" + route); - } + public RoutingFixture() => Console.WriteLine("Created Routing Fixture"); + public void SetServiceHealth(string name, bool isHealthy) => _hosts[name].IsHealthy = isHealthy; + public string GetNewServiceName() => Guid.NewGuid().ToString("N").Substring(0, 10); + public Task CallRouterAsync(string route) => _client.GetAsync($"http://localhost:{routerPort}" + route); + public Task WaitForRegistrationAsync() => Task.WhenAny(new[] { _wait.WaitAsync(), Task.Delay(30 * 1000) }); + private bool AllRegistered(string[] data) => _hosts.All(h => data.Contains(h.Key, StringComparer.OrdinalIgnoreCase)); private void RegisterService(string name, int port, string route) { @@ -131,9 +118,9 @@ public void AddRouter() .ConfigureServices(x => { x.AddCondenserWithBuilder() - .WithRoutesBuiltCallback(SignalWhenAllRegistered) + .WithRoutesBuiltCallback(SignalWhenAllRegistered) .Build(); - + }) .Configure(app => { @@ -143,24 +130,11 @@ public void AddRouter() app.UseCondenser(); }) .Build(); - - - } - - public Task WaitForRegistrationAsync() - { - return Task.WhenAny(new[] { _wait.WaitAsync(), Task.Delay(30 * 1000) }); } - - private bool AllRegistered(string[] data) - { - return _hosts.All(h => data.Contains(h.Key, StringComparer.OrdinalIgnoreCase)); - } - + public bool AreAllRegistered() { - if (_currentRegistrations == null) - return false; + if (_currentRegistrations == null) return false; return AllRegistered(_currentRegistrations); } @@ -172,7 +146,7 @@ private void SignalWhenAllRegistered(string[] data) if (AllRegistered(data)) { _wait.Set(true); - } + } } public void StartAll() diff --git a/test/CondenserTests/CustomRouterFacts.cs b/test/CondenserTests/CustomRouterFacts.cs index 9499b63..601c015 100644 --- a/test/CondenserTests/CustomRouterFacts.cs +++ b/test/CondenserTests/CustomRouterFacts.cs @@ -47,9 +47,6 @@ public async void SetupCustomRouterAndLookForbadRoute() Assert.Null(routeContext.Handler); } - private CustomRouter BuildRouter() - { - return new CustomRouter(null, RoutingData.BuildDefault(), new IService[0]); - } + private CustomRouter BuildRouter() => new CustomRouter(null, RoutingData.BuildDefault(), new IService[0]); } } diff --git a/test/CondenserTests/HealthConfigurationFacts.cs b/test/CondenserTests/HealthConfigurationFacts.cs index a12c675..174146b 100644 --- a/test/CondenserTests/HealthConfigurationFacts.cs +++ b/test/CondenserTests/HealthConfigurationFacts.cs @@ -16,7 +16,7 @@ public class HealthConfigurationFacts public void ShouldBuildHttpsExpectedUrl(string url, bool ignoreForCheck, string expectedUrl) { var id = "myservice"; - int interval = 50; + var interval = 50; var manager = new FakeServiceManager { @@ -41,7 +41,7 @@ public void ShouldBuildHttpsExpectedUrl(string url, bool ignoreForCheck, string public void ShouldBuildExpectedUrl(string url, string expectedUrl) { var id = "myservice"; - int interval = 50; + var interval = 50; var manager = new FakeServiceManager { diff --git a/test/CondenserTests/RadixTests.cs b/test/CondenserTests/RadixTests.cs index 81a4237..025dc7b 100644 --- a/test/CondenserTests/RadixTests.cs +++ b/test/CondenserTests/RadixTests.cs @@ -96,15 +96,13 @@ public void TestRemovingAService() } - public static RadixTree CreateDefault() - { - return new RadixTree(() => + public static RadixTree CreateDefault() => + new RadixTree(() => { var randomRoutingStrategy = new RandomRoutingStrategy(); return new ChildContainer(new DefaultRouting (new[] { randomRoutingStrategy }, new FakeRouteConfig())); }); - } } public class FakeRouteConfig : IRoutingConfig