Skip to content

Commit

Permalink
Add possibility of customizing how discovery metadata are created (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kralizek authored Dec 17, 2019
1 parent ef75b12 commit cc040ac
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 22 deletions.
62 changes: 62 additions & 0 deletions src/ServiceModel.ECS/ECSMetadataExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Description;
using System.ServiceModel.Discovery;
using EMG.Extensions.Configuration.Model;
using EMG.Utilities.ServiceModel.Configuration;
using EMG.Utilities.ServiceModel.Discovery;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace EMG.Utilities
{
public static class ECSMetadataExtensions
{
[Obsolete("Use AddECSContainerSupport instead.")]
public static HttpEndpointAddress UseECS(this HttpEndpointAddress endpointAddress, IConfiguration configuration, Action<ECSContainerMetadataOptions> configureOptions = null)
{
if (Environment.GetEnvironmentVariable(EMG.Extensions.Configuration.ECSMetadataExtensions.ECSContainerMetadataFileKey) == null)
Expand Down Expand Up @@ -34,6 +41,7 @@ public static HttpEndpointAddress UseECS(this HttpEndpointAddress endpointAddres
return EndpointAddress.ForHttp(containerMetadata.HostPrivateIPv4Address, endpointAddress.Path, portMapping.HostPort, endpointAddress.IsSecure);
}

[Obsolete("Use AddECSContainerSupport instead.")]
public static NetTcpEndpointAddress UseECS(this NetTcpEndpointAddress endpointAddress, IConfiguration configuration, Action<ECSContainerMetadataOptions> configureOptions = null)
{
if (Environment.GetEnvironmentVariable(EMG.Extensions.Configuration.ECSMetadataExtensions.ECSContainerMetadataFileKey) == null)
Expand Down Expand Up @@ -61,5 +69,59 @@ public static NetTcpEndpointAddress UseECS(this NetTcpEndpointAddress endpointAd
return EndpointAddress.ForNetTcp(portMapping.HostPort, containerMetadata.HostPrivateIPv4Address, endpointAddress.Path);

}

public static IServiceCollection AddECSContainerSupport(this IServiceCollection services, IConfiguration configuration)
{
if (Environment.GetEnvironmentVariable(EMG.Extensions.Configuration.ECSMetadataExtensions.ECSContainerMetadataFileKey) != null)
{
services.Configure<AnnouncementServiceOptions>(o => o.EndpointDiscoveryMetadata = GetEndpointMetadataFromECS);
}

return services;

EndpointDiscoveryMetadata GetEndpointMetadataFromECS(ServiceEndpoint endpoint)
{
if (endpoint.Address is null)
{
throw new ArgumentNullException(nameof(endpoint),"endpoint address should not be null");
}

var containerMetadata = configuration.Get<ECSContainerMetadata>();

var endpointMetadata = EndpointDiscoveryMetadata.FromServiceEndpoint(endpoint);

if (endpointMetadata is null)
{
return null;
}

if (containerMetadata?.HostPrivateIPv4Address is null)
{
return endpointMetadata;
}

var uriBuilder = new UriBuilder(endpointMetadata.Address.Uri)
{
Host = containerMetadata.HostPrivateIPv4Address,
Port = GetMappedPortOrDefault(containerMetadata.PortMappings, endpointMetadata.Address.Uri.Port)
};

endpointMetadata.Address = new System.ServiceModel.EndpointAddress(uriBuilder.Uri.ToString());

return endpointMetadata;
}

int GetMappedPortOrDefault(IEnumerable<PortMapping> mappings, int port)
{
var hostPortByContainerPort = mappings.ToDictionary(k => k.ContainerPort, v => v.HostPort);

if (hostPortByContainerPort.TryGetValue(port, out var mappedPort))
{
return mappedPort;
}

return port;
}
}
}
}
5 changes: 5 additions & 0 deletions src/ServiceModel.ECS/ServiceModel.ECS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@
<ProjectReference Include="..\ServiceModel\ServiceModel.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Discovery" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class AnnouncementServiceOptions
public TimeSpan Interval { get; set; }

public Binding Binding { get; set; }

public Func<ServiceEndpoint, EndpointDiscoveryMetadata> EndpointDiscoveryMetadata { get; set; } = System.ServiceModel.Discovery.EndpointDiscoveryMetadata.FromServiceEndpoint;
}

public class AnnouncementService : IAnnouncementService
Expand Down Expand Up @@ -54,7 +56,7 @@ from endpoint in endpointsToAnnounce
{
using (var client = CreateClient())
{
var metadata = EndpointDiscoveryMetadata.FromServiceEndpoint(endpoint);
var metadata = _options.EndpointDiscoveryMetadata(endpoint);

if (metadata != null)
{
Expand All @@ -73,7 +75,7 @@ private void UnannounceService(IReadOnlyList<ServiceEndpoint> endpoints)
{
foreach (var endpoint in endpoints)
{
var metadata = EndpointDiscoveryMetadata.FromServiceEndpoint(endpoint);
var metadata = _options.EndpointDiscoveryMetadata(endpoint);

if (metadata != null)
{
Expand Down
18 changes: 18 additions & 0 deletions tests/Tests.ServiceModel.ECS/CustomAutoDataAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Description;
using AutoFixture;
using AutoFixture.AutoMoq;
using AutoFixture.NUnit3;
using EMG.Extensions.Configuration.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Tests
{
Expand Down Expand Up @@ -33,13 +36,28 @@ public static IFixture CreateFixture()
GenerateDelegates = true
});

fixture.Customize<ECSContainerMetadata>(o => o
.With(p => p.PortMappings, (Generator<PortMapping> g) => g.Take(1).ToArray())
);

fixture.Customize<IConfiguration>(o => o.FromFactory((ConfigurationBuilder builder, ECSContainerMetadata metadata) =>
{
builder.AddObject(metadata);

return builder.Build();
}));

fixture.Customize<ServiceCollection>(o => o.FromFactory(() =>
{
var services = new ServiceCollection();

services.AddOptions();

return services;
}));

fixture.Customize<ServiceEndpoint>(o => o.Without(p => p.Address));

return fixture;
}
}
Expand Down
Loading

0 comments on commit cc040ac

Please sign in to comment.