Add WebAPI middleware for multi-instance Roslyn Bridge routing
Add RoslynBridge.WebApi - ASP.NET Core 8.0 middleware that: - Provides a centralized REST API for accessing multiple VS instances - Manages instance registry with discovery by port, solution, or PID - Proxies requests to the appropriate VS instance - Tracks request/response history for debugging - Auto-cleanup of stale instances via background service Features: - Health endpoints: /api/health, /api/health/ping - Roslyn endpoints: /api/roslyn/projects, /api/roslyn/diagnostics, etc. - Instance management: /api/instances (register, heartbeat, unregister) - History tracking: /api/history, /api/history/stats - Swagger UI at root (/) for API documentation - CORS enabled for web applications Services: - InstanceRegistryService: Thread-safe registry of VS instances - HistoryService: In-memory request/response history (max 1000 entries) - InstanceCleanupService: Background service to remove stale instances - RoslynBridgeClient: HTTP client for proxying to VS instances Update RoslynBridge.sln to include RoslynBridge.WebApi project. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
72
RoslynBridge.WebApi/Controllers/HealthController.cs
Normal file
72
RoslynBridge.WebApi/Controllers/HealthController.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RoslynBridge.WebApi.Models;
|
||||
using RoslynBridge.WebApi.Services;
|
||||
|
||||
namespace RoslynBridge.WebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Health check and status controller
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[Produces("application/json")]
|
||||
public class HealthController : ControllerBase
|
||||
{
|
||||
private readonly IRoslynBridgeClient _bridgeClient;
|
||||
private readonly ILogger<HealthController> _logger;
|
||||
|
||||
public HealthController(IRoslynBridgeClient bridgeClient, ILogger<HealthController> logger)
|
||||
{
|
||||
_bridgeClient = bridgeClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the health status of the middleware and Visual Studio plugin
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns>Health status information</returns>
|
||||
/// <response code="200">Service is healthy</response>
|
||||
/// <response code="503">Service is unhealthy</response>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(HealthCheckResponse), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(HealthCheckResponse), StatusCodes.Status503ServiceUnavailable)]
|
||||
public async Task<ActionResult<HealthCheckResponse>> GetHealth(CancellationToken cancellationToken)
|
||||
{
|
||||
var response = new HealthCheckResponse();
|
||||
|
||||
try
|
||||
{
|
||||
var isVsPluginHealthy = await _bridgeClient.IsHealthyAsync(null, cancellationToken);
|
||||
response.VsPluginStatus = isVsPluginHealthy ? "Connected" : "Disconnected";
|
||||
|
||||
if (!isVsPluginHealthy)
|
||||
{
|
||||
response.Status = "Degraded";
|
||||
_logger.LogWarning("Visual Studio plugin is not accessible");
|
||||
return StatusCode(StatusCodes.Status503ServiceUnavailable, response);
|
||||
}
|
||||
|
||||
_logger.LogInformation("Health check passed");
|
||||
return Ok(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Health check failed");
|
||||
response.Status = "Unhealthy";
|
||||
response.VsPluginStatus = "Error";
|
||||
return StatusCode(StatusCodes.Status503ServiceUnavailable, response);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple ping endpoint
|
||||
/// </summary>
|
||||
/// <returns>Pong response</returns>
|
||||
[HttpGet("ping")]
|
||||
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
|
||||
public IActionResult Ping()
|
||||
{
|
||||
return Ok(new { message = "pong", timestamp = DateTime.UtcNow });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user