using Microsoft.AspNetCore.Mvc; using WIDESEAWCS_S7Simulator.Core.Entities; using WIDESEAWCS_S7Simulator.Core.Interfaces; namespace WIDESEAWCS_S7Simulator.Server.Controllers { /// /// 仿真器实例管理控制器 /// [ApiController] [Route("api/[controller]")] public class SimulatorInstancesController : ControllerBase { private readonly ISimulatorInstanceManager _instanceManager; private readonly ILogger _logger; public SimulatorInstancesController( ISimulatorInstanceManager instanceManager, ILogger logger) { _instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// /// 获取所有实例列表 /// [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] public ActionResult> GetAllInstances() { try { var instances = _instanceManager.GetAllInstances(); var states = instances.Select(i => i.GetState()).ToList(); return Ok(states); } catch (Exception ex) { _logger.LogError(ex, "Failed to get all instances"); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to retrieve instances" }); } } /// /// 创建新实例 /// [HttpPost] [ProducesResponseType(typeof(InstanceState), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> CreateInstance([FromBody] InstanceConfig config) { try { if (config == null) { return BadRequest(new { error = "Instance configuration is required" }); } if (string.IsNullOrWhiteSpace(config.Id)) { return BadRequest(new { error = "Instance ID is required" }); } if (string.IsNullOrWhiteSpace(config.Name)) { return BadRequest(new { error = "Instance name is required" }); } if (_instanceManager.InstanceExists(config.Id)) { return Conflict(new { error = $"Instance with ID '{config.Id}' already exists" }); } if (config.Port <= 0 || config.Port > 65535) { return BadRequest(new { error = "Port must be between 1 and 65535" }); } var instance = await _instanceManager.CreateInstanceAsync(config); var state = instance.GetState(); return CreatedAtAction( nameof(GetInstance), new { id = config.Id }, state); } catch (ArgumentException ex) { _logger.LogWarning(ex, "Invalid instance configuration"); return BadRequest(new { error = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Failed to create instance"); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to create instance" }); } } /// /// 获取指定实例详情 /// [HttpGet("{id}")] [ProducesResponseType(typeof(InstanceState), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult GetInstance(string id) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } var instance = _instanceManager.GetInstance(id); if (instance == null) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } var state = instance.GetState(); return Ok(state); } catch (Exception ex) { _logger.LogError(ex, "Failed to get instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to retrieve instance" }); } } /// /// 更新实例配置 /// [HttpPut("{id}")] [ProducesResponseType(typeof(InstanceState), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> UpdateInstance(string id, [FromBody] InstanceConfig config) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } if (config == null) { return BadRequest(new { error = "Instance configuration is required" }); } var instance = _instanceManager.GetInstance(id); if (instance == null) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } // Validate port if changed if (config.Port <= 0 || config.Port > 65535) { return BadRequest(new { error = "Port must be between 1 and 65535" }); } // Delete existing instance and recreate with new config // Note: This is a simplified approach. In production, you might want to support hot-reload bool wasRunning = instance.GetState().Status == Core.Enums.InstanceStatus.Running; await _instanceManager.DeleteInstanceAsync(id, deleteConfig: false); config.Id = id; // Ensure ID matches route parameter var newInstance = await _instanceManager.CreateInstanceAsync(config); if (wasRunning) { await _instanceManager.StartInstanceAsync(id); } var state = newInstance.GetState(); return Ok(state); } catch (ArgumentException ex) { _logger.LogWarning(ex, "Invalid instance configuration"); return BadRequest(new { error = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Failed to update instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to update instance" }); } } /// /// 删除实例 /// [HttpDelete("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteInstance(string id, [FromQuery] bool deleteConfig = true) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } if (!_instanceManager.InstanceExists(id)) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } await _instanceManager.DeleteInstanceAsync(id, deleteConfig); return NoContent(); } catch (Exception ex) { _logger.LogError(ex, "Failed to delete instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to delete instance" }); } } /// /// 启动实例 /// [HttpPost("{id}/start")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> StartInstance(string id) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } if (!_instanceManager.InstanceExists(id)) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } bool success = await _instanceManager.StartInstanceAsync(id); if (!success) { return BadRequest(new { error = "Failed to start instance" }); } var instance = _instanceManager.GetInstance(id); var state = instance?.GetState(); return Ok(state); } catch (Exception ex) { _logger.LogError(ex, "Failed to start instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to start instance" }); } } /// /// 停止实例 /// [HttpPost("{id}/stop")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> StopInstance(string id) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } if (!_instanceManager.InstanceExists(id)) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } await _instanceManager.StopInstanceAsync(id); var instance = _instanceManager.GetInstance(id); var state = instance?.GetState(); return Ok(state); } catch (Exception ex) { _logger.LogError(ex, "Failed to stop instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to stop instance" }); } } /// /// 重启实例 /// [HttpPost("{id}/restart")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> RestartInstance(string id) { try { if (string.IsNullOrWhiteSpace(id)) { return BadRequest(new { error = "Instance ID is required" }); } if (!_instanceManager.InstanceExists(id)) { return NotFound(new { error = $"Instance with ID '{id}' not found" }); } bool success = await _instanceManager.RestartInstanceAsync(id); if (!success) { return BadRequest(new { error = "Failed to restart instance" }); } var instance = _instanceManager.GetInstance(id); var state = instance?.GetState(); return Ok(state); } catch (Exception ex) { _logger.LogError(ex, "Failed to restart instance {InstanceId}", id); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to restart instance" }); } } /// /// 启动所有自动启动实例 /// [HttpPost("start-all")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task StartAllAutoStartInstances() { try { await _instanceManager.LoadSavedInstancesAsync(autoStart: true); return Ok(new { message = "Started all auto-start instances", runningCount = _instanceManager.GetRunningInstanceCount() }); } catch (Exception ex) { _logger.LogError(ex, "Failed to start all instances"); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to start instances" }); } } /// /// 停止所有实例 /// [HttpPost("stop-all")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task StopAllInstances() { try { await _instanceManager.StopAllInstancesAsync(); return Ok(new { message = "Stopped all instances", runningCount = _instanceManager.GetRunningInstanceCount() }); } catch (Exception ex) { _logger.LogError(ex, "Failed to stop all instances"); return StatusCode(StatusCodes.Status500InternalServerError, new { error = "Failed to stop instances" }); } } } }