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" });
}
}
}
}