using System;
using System.Collections.Generic;
using System.Fabric;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
using Microsoft.ServiceFabric.Data;
namespace ApiGw_Base
{
///
/// The FabricRuntime creates an instance of this class for each service type instance.
///
internal sealed class ApiGw_Base : StatelessService
{
public ApiGw_Base(StatelessServiceContext context)
: base(context)
{ }
///
/// Optional override to create listeners (like tcp, http) for this service instance.
///
/// The collection of listeners.
protected override IEnumerable CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel(opt =>
{
int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpoint").Port;
opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
{
listenOptions.UseHttps(GetCertificateFromStore());
listenOptions.NoDelay = true;
});
})
.ConfigureServices(
services => services
.AddSingleton(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
///
/// Finds the ASP .NET Core HTTPS development certificate in development environment. Update this method to use the appropriate certificate for production environment.
///
/// Returns the ASP .NET Core HTTPS development certificate
private static X509Certificate2 GetCertificateFromStore()
{
string aspNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
if (string.Equals(aspNetCoreEnvironment, "Development", StringComparison.OrdinalIgnoreCase))
{
const string aspNetHttpsOid = "1.3.6.1.4.1.311.84.1.1";
const string CNName = "CN=localhost";
using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindByExtension, aspNetHttpsOid, true);
currentCerts = currentCerts.Find(X509FindType.FindByIssuerDistinguishedName, CNName, true);
return currentCerts.Count == 0 ? null : currentCerts[0];
}
}
else
{
throw new NotImplementedException("GetCertificateFromStore should be updated to retrieve the certificate for non Development environment");
}
}
}
}