Samples
Samples copied to clipboard
Create a sample for a Custom Endpoint
Add a sample that shows how to add a custom endpoint using the management endpoints library.
One way to do it would be below. I just noodled in a scratch file but haven't actually tested this.
public static class TestExtensions
{
public static IEndpointConventionBuilder MapCustomActuatorEndpoint(this IEndpointRouteBuilder endpoints, Type typeEndpoint, EndpointCollectionConventionBuilder conventionBuilder = null)
{
if (endpoints == null)
{
throw new ArgumentNullException(nameof(endpoints));
}
var serviceProvider = endpoints.ServiceProvider;
var options = serviceProvider.GetService<CustomEndpointOptions>() as IEndpointOptions;
var mgmtOptionsCollection = endpoints.ServiceProvider.GetServices<IManagementOptions>();
var builder = conventionBuilder ?? new EndpointCollectionConventionBuilder();
foreach (var mgmtOptions in mgmtOptionsCollection)
{
var fullPath = options.GetContextPath(mgmtOptions);
var pattern = RoutePatternFactory.Parse(fullPath);
// only add middleware if the route hasn't already been mapped
if (!endpoints.DataSources.Any(d => d.Endpoints.Any(ep => ((RouteEndpoint)ep).RoutePattern.RawText == pattern.RawText)))
{
var pipeline = endpoints.CreateApplicationBuilder()
.UseMiddleware(typeof(CustomEndpointMiddleware), mgmtOptions)
.Build();
var allowedVerbs = options.AllowedVerbs ?? new List<string> { "Get" };
builder.AddConventionBuilder(endpoints.MapMethods(fullPath, allowedVerbs, pipeline));
}
}
return builder;
}
public static void AddCustomActuator( this IServiceCollection services, IConfiguration config = null)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
config ??= services.BuildServiceProvider().GetService<IConfiguration>();
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
services.AddActuatorEndpointMapping<CustomEndpoint>();
}
}
public class CustomEndpointOptions : AbstractEndpointOptions
{
private const string MANAGEMENT_INFO_PREFIX = "management:endpoints:custom";
public CustomEndpointOptions()
: base()
{
Id = "custom";
RequiredPermissions = Permissions.RESTRICTED;
}
public CustomEndpointOptions(IConfiguration config)
: base(MANAGEMENT_INFO_PREFIX, config)
{
if (string.IsNullOrEmpty(Id))
{
Id = "custom";
}
}
}
public class CustomEndpointMiddleware : EndpointMiddleware<string, string>
{
private readonly RequestDelegate _next;
public CustomEndpointMiddleware(RequestDelegate next, CustomEndpoint endpoint, IManagementOptions mgmtOptions, ILogger<CustomEndpointMiddleware> logger = null)
: base(endpoint, mgmtOptions, logger: logger)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
_logger.LogDebug("Info middleware Invoke({0})", context.Request.Path.Value);
if (_endpoint.ShouldInvoke(_mgmtOptions, _logger))
{
return HandleInfoRequestAsync(context);
}
return Task.CompletedTask;
}
protected internal Task HandleInfoRequestAsync(HttpContext context)
{
var serialInfo = HandleRequest();
_logger?.LogDebug("Returning: {0}", serialInfo);
context.HandleContentNegotiation(_logger);
return context.Response.WriteAsync(serialInfo);
}
}
public class CustomEndpoint : AbstractEndpoint<string, string>
{
public CustomEndpoint(IEndpointOptions options)
: base(options)
{
}
public override string Invoke(string arg)
{
return "stuff";
}
}
Then to use this ...
...
.UseEndpoints(endpoints =>
{
endpoints.MapActuatorEndpoint(type).RequireAuthorization("TestAuth");
endpoints.MapCustomActuatorEndpoint(typeof(CustomEndpoint)).RequireAuthorization("TestAuth");
}))