Skip to content

Commit

Permalink
renaming IDiscovery to IServiceDiscovery and refactoring out model de…
Browse files Browse the repository at this point in the history
…pendencies to generic params (#17)

* Adding DeregisterIfCriticalAfter to healthchecks introduced in Consul 0.7 onwards and defaulting heartbeat to deregister service if failing after 90 minutes.
  • Loading branch information
wwwlicious committed Oct 3, 2016
1 parent 9a6dbbd commit a203e73
Show file tree
Hide file tree
Showing 15 changed files with 52 additions and 54 deletions.
18 changes: 5 additions & 13 deletions README.md
Expand Up @@ -195,27 +195,19 @@ public class MyInternalDto { ... }
The default discovery mechanism uses the ServiceStack request types to resolve
all of the services capable of processing the request. This means that you should
**always use unique request names** across all your services for each of your RequestDTO's
To override the default behaviour, you can implement your own
`IDiscoveryRequestTypeResolver`
To override the default which uses Consul, you can implement your own
`IServiceDiscovery<TServiceModel, TServiceRegistration>` client to use whatever backing store you want.

```csharp
new ConsulFeature(settings =>
{
settings.AddDiscoveryTypeResolver(new CustomDiscoveryRequestTypeResolver());
settings.AddServiceDiscovery(new CustomServiceDiscovery());
});
```
```csharp
public class CustomDiscoveryRequestTypeResolver : IDiscoveryRequestTypeResolver
public class CustomServiceDiscovery : IServiceDiscovery<TServiceModel, TServiceRegistration>
{
public string[] GetRequestTypes(IAppHost host)
{
// register dto's for reverse lookup below ...
}

public string ResolveBaseUri(object dto)
{
// reverse lookup service base uri from dto ...
}
...
}
```

Expand Down
2 changes: 1 addition & 1 deletion src/Servicestack.Discovery.Consul/Consul/ConsulClient.cs
Expand Up @@ -171,7 +171,7 @@ public static void RegisterHealthChecks(params ServiceHealthCheck[] healthChecks
}
else
{
logger.Info($"Registered health check with Consul `{check}`");
logger.Info($"Registered health check with Consul `{check.Id}`");
}
});
}
Expand Down
12 changes: 6 additions & 6 deletions src/Servicestack.Discovery.Consul/ConsulFeature.cs
Expand Up @@ -14,7 +14,7 @@ namespace ServiceStack.Discovery.Consul
/// </summary>
public class ConsulFeature : IPlugin
{
private IDiscovery Discovery { get; set; }
private IServiceDiscovery<ConsulService, ServiceRegistration> ServiceDiscovery { get; set; }

public ConsulFeatureSettings Settings { get; }

Expand Down Expand Up @@ -47,19 +47,19 @@ public void Register(IAppHost appHost)

private void RegisterService(IAppHost host)
{
Discovery = Settings.GetDiscoveryClient() ?? new ConsulDiscovery();
Discovery.Register(host);
ServiceDiscovery = Settings.GetDiscoveryClient() ?? new ConsulDiscovery();
ServiceDiscovery.Register(host);

// register servicestack discovery services
host.Register(Discovery);
host.Register(ServiceDiscovery);
host.GetContainer()
.Register<IServiceGatewayFactory>(x => new ConsulServiceGatewayFactory(Settings.GetGateway(), Discovery))
.Register<IServiceGatewayFactory>(x => new ConsulServiceGatewayFactory(Settings.GetGateway(), ServiceDiscovery))
.ReusedWithin(ReuseScope.None);
}

private void UnRegisterService(IAppHost host = null)
{
Discovery.Unregister(host);
ServiceDiscovery.Unregister(host);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Servicestack.Discovery.Consul/ConsulFeatureSettings.cs
Expand Up @@ -20,7 +20,7 @@ public class ConsulFeatureSettings

private readonly List<ConsulRegisterCheck> serviceChecks = new List<ConsulRegisterCheck>();

private IDiscovery discoveryClient;
private IServiceDiscovery<ConsulService, ServiceRegistration> discoveryClient;

private HostHealthCheck healthCheck;

Expand Down Expand Up @@ -71,7 +71,7 @@ public void AddServiceCheck(HealthCheckDelegate check, int intervalInSeconds = 6
/// Override the default discovery consul client
/// </summary>
/// <param name="discoveryClient">the IDiscovery client</param>
public void AddDiscoveryTypeResolver(IDiscovery discoveryClient)
public void AddServiceDiscovery(IServiceDiscovery<ConsulService, ServiceRegistration> discoveryClient)
{
this.discoveryClient = discoveryClient;
}
Expand Down Expand Up @@ -125,7 +125,7 @@ public ConsulRegisterCheck[] GetServiceChecks()
/// Gets the type resolver used for service discovery
/// </summary>
/// <returns></returns>
public IDiscovery GetDiscoveryClient()
public IServiceDiscovery<ConsulService, ServiceRegistration> GetDiscoveryClient()
{
return discoveryClient;
}
Expand Down
Expand Up @@ -12,7 +12,7 @@ namespace ServiceStack.Discovery.Consul
/// <summary>
/// Manages register, unregister, holds registration state
/// </summary>
public class ConsulDiscovery : IDiscovery
public class ConsulDiscovery : IServiceDiscovery<ConsulService, ServiceRegistration>
{
/// <summary>
/// Contains the service registration information
Expand Down
Expand Up @@ -6,12 +6,17 @@ namespace ServiceStack.Discovery.Consul
using System;
using System.Collections.Generic;

public interface IDiscovery
/// <summary>
/// Interface used for service discovery
/// </summary>
/// <typeparam name="TServiceModel">The DTO for service information</typeparam>
/// <typeparam name="TServiceRegistration">The DTO for the AppHost registration</typeparam>
public interface IServiceDiscovery<out TServiceModel, out TServiceRegistration> where TServiceModel : class where TServiceRegistration : class
{
/// <summary>
/// Holds the current service registration
/// </summary>
ServiceRegistration Registration { get; }
TServiceRegistration Registration { get; }

/// <summary>
/// Registers the service for discovery
Expand All @@ -22,23 +27,23 @@ public interface IDiscovery
/// <summary>
/// Unregisters the service from discovery
/// </summary>
/// <param name="host"></param>
/// <param name="host">the apphost</param>
void Unregister(IAppHost host);

/// <summary>
/// Returns a list of available services
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
ConsulService[] GetServices(string serviceName);
/// <param name="serviceName">the service name</param>
/// <returns>the matching services</returns>
TServiceModel[] GetServices(string serviceName);

/// <summary>
/// Returns a single service for a dto
/// </summary>
/// <param name="serviceName"></param>
/// <param name="dtoName"></param>
/// <returns></returns>
ConsulService GetService(string serviceName, string dtoName);
/// <param name="serviceName">the service name</param>
/// <param name="dtoName">the request dto name</param>
/// <returns>the service dto</returns>
TServiceModel GetService(string serviceName, string dtoName);

/// <summary>
/// Inspects the IAppHost and returns a list of strings that will represent the RequestDTO types
Expand Down
Expand Up @@ -11,13 +11,13 @@ public class ConsulServiceGatewayFactory : ServiceGatewayFactoryBase
{
private readonly DefaultGatewayDelegate defaultGateway;

private readonly IDiscovery discoveryClient;
private readonly IServiceDiscovery<ConsulService, ServiceRegistration> discoveryClient;

private readonly ConcurrentDictionary<string, HttpCacheEntry> sharedCache = new ConcurrentDictionary<string, HttpCacheEntry>();

public HashSet<Type> LocalTypes { get; set; }

public ConsulServiceGatewayFactory(DefaultGatewayDelegate defaultGateway, IDiscovery discoveryClient)
public ConsulServiceGatewayFactory(DefaultGatewayDelegate defaultGateway, IServiceDiscovery<ConsulService, ServiceRegistration> discoveryClient)
{
defaultGateway.ThrowIfNull(nameof(defaultGateway));
discoveryClient.ThrowIfNull(nameof(discoveryClient));
Expand Down
Expand Up @@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ServiceStack.Discovery.Consul</RootNamespace>
<AssemblyName>ServiceStack.Discovery.Consul</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
Expand All @@ -23,6 +23,7 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
<RunCodeAnalysis>true</RunCodeAnalysis>
<DocumentationFile>bin\Debug\ServiceStack.Discovery.Consul.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand Down Expand Up @@ -98,7 +99,7 @@
<Compile Include="Exceptions\GatewayServiceDiscoveryException.cs" />
<Compile Include="TypeExtensions.cs" />
<Compile Include="HostHealthCheck.cs" />
<Compile Include="Discovery\IDiscovery.cs" />
<Compile Include="Discovery\IServiceDiscovery.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Consul\ConsulClient.cs" />
<Compile Include="Dtos\ServiceRegistration.cs" />
Expand Down
Expand Up @@ -10,7 +10,7 @@ public class DiscoveryService : Service
private GetServiceValidator GetServiceValidator { get; set; } = new GetServiceValidator();

// return current registration and health info
public IDiscovery Discovery { get; set; }
public IServiceDiscovery<ConsulService, ServiceRegistration> Discovery { get; set; }

public object Any(ServiceRegistration registration)
{
Expand Down
Expand Up @@ -54,8 +54,8 @@ public void CanTurnOffDefaultHealthChecks()
[Fact]
public void CanOverrideDiscoveryClient()
{
var client = new TestDiscovery();
settings.AddDiscoveryTypeResolver(client);
var client = new TestServiceDiscovery();
settings.AddServiceDiscovery(client);

settings.GetDiscoveryClient().Should().Be(client);
}
Expand Down
Expand Up @@ -16,7 +16,7 @@ public class ConsulServiceGatewayFactoryTests
[Fact]
public void Ctor_Requires_DefaultGatewayDelegate()
{
Action action = () => new ConsulServiceGatewayFactory(null, new TestDiscovery());
Action action = () => new ConsulServiceGatewayFactory(null, new TestServiceDiscovery());
action.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("defaultGateway");
}

Expand All @@ -30,7 +30,7 @@ public void Ctor_Requires_DefaultDiscovery()
[Fact]
public void Gateway_Ignores_LocalTypes()
{
var gateway = new ConsulServiceGatewayFactory(uri => new CsvServiceClient(uri), new TestDiscovery());
var gateway = new ConsulServiceGatewayFactory(uri => new CsvServiceClient(uri), new TestServiceDiscovery());
gateway.LocalTypes.Add(typeof(ConsulServiceGatewayFactoryTests));

var serviceGateway = gateway.GetGateway(typeof(ConsulServiceGatewayFactoryTests));
Expand All @@ -41,7 +41,7 @@ public void Gateway_Ignores_LocalTypes()
[Fact]
public void Gateway_ReturnsCorrectly_ForNonLocalTypes()
{
var resolver = new TestDiscovery(new KeyValuePair<Type, string>(typeof(ConsulServiceGatewayFactoryTests), "http://banana"));
var resolver = new TestServiceDiscovery(new KeyValuePair<Type, string>(typeof(ConsulServiceGatewayFactoryTests), "http://banana"));
var gateway = new ConsulServiceGatewayFactory(uri => new CsvServiceClient(uri) { Version = 123 }, resolver);
gateway.LocalTypes.Clear();

Expand Down
12 changes: 6 additions & 6 deletions test/ServiceStack.Discovery.Consul.Tests/ConsulTests.cs
Expand Up @@ -26,9 +26,9 @@ public void Resolver_ReturnsDefaultRoute_ByDTOTypeName()
var remoteuri = "http://remoteuri:1234/api/";
var expected = remoteuri.CombineWith("/json/reply/ConsulTests.TestDTO");

var discovery = new TestDiscovery();
var discovery = new TestServiceDiscovery();
discovery.DtoTypes.Add(typeof(TestDTO), remoteuri);
plugin.Settings.AddDiscoveryTypeResolver(discovery);
plugin.Settings.AddServiceDiscovery(discovery);

Consul.ResolveTypedUrl(new JsonServiceClient("http://localhost/"), "GET", new TestDTO()).Should().Be(expected);
}
Expand All @@ -38,15 +38,15 @@ public void Resolver_ReturnsBaseUri_ForUnregisteredType()
{
var baseUri = "http://testuri/";
var expected = baseUri.CombineWith("/json/reply/ConsulTests.TestDTO");
plugin.Settings.AddDiscoveryTypeResolver(new TestDiscovery());
plugin.Settings.AddServiceDiscovery(new TestServiceDiscovery());

Consul.ResolveTypedUrl(new JsonServiceClient(baseUri), null, new TestDTO()).Should().Be(expected);
}

[Fact]
public void Resolver_ReturnsNull_ForUnregisteredType()
{
plugin.Settings.AddDiscoveryTypeResolver(new TestDiscovery());
plugin.Settings.AddServiceDiscovery(new TestServiceDiscovery());

Consul.ResolveTypedUrl(null, null, new TestDTO()).Should().BeNull();
}
Expand All @@ -59,10 +59,10 @@ public void Resolver_ReturnsNull_ForUnregisteredType()
[InlineData("PATCH", "/patch/dto2")]
public void Resolver_ReturnsRegisteredType_ByName(string method, string expected)
{
var discovery = new TestDiscovery();
var discovery = new TestServiceDiscovery();
var remoteuri = "http://remoteUri:1234/";
discovery.DtoTypes.Add(typeof(TestDTO2), remoteuri);
plugin.Settings.AddDiscoveryTypeResolver(discovery);
plugin.Settings.AddServiceDiscovery(discovery);

Consul.ResolveTypedUrl(new JsonServiceClient("http://localhost"), method, new TestDTO2()).Should().Be(remoteuri.CombineWith(expected));
}
Expand Down
Expand Up @@ -23,7 +23,7 @@ public AppHostFixture()
plugins.Add(new NativeTypesFeature());
plugins.Add(new ConsulFeature(settings =>
{
settings.AddDiscoveryTypeResolver(new TestDiscovery(TestTypes));
settings.AddServiceDiscovery(new TestServiceDiscovery(TestTypes));
}));

Host = new BasicAppHost
Expand Down
Expand Up @@ -7,9 +7,9 @@ namespace ServiceStack.Discovery.Consul.Tests
using System.Collections.Generic;
using System.Linq;

public class TestDiscovery : IDiscovery
public class TestServiceDiscovery : IServiceDiscovery<ConsulService, ServiceRegistration>
{
public TestDiscovery(params KeyValuePair<Type, string>[] dtoTypes)
public TestServiceDiscovery(params KeyValuePair<Type, string>[] dtoTypes)
{
DtoTypes = dtoTypes.ToDictionary(x => x.Key, y => y.Value);
}
Expand Down
Expand Up @@ -109,7 +109,7 @@
<Compile Include="ConsulServiceRegistrationTests.cs" />
<Compile Include="ConsulTests.cs" />
<Compile Include="HealthCheckServiceTests.cs" />
<Compile Include="Helpers\TestDiscovery.cs" />
<Compile Include="Helpers\TestServiceDiscovery.cs" />
<Compile Include="HostHealthCheckTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TagExtensionsTests.cs" />
Expand Down

0 comments on commit a203e73

Please sign in to comment.