Files
dbserver/opcUaManager/Controllers/CrawlerController.cs

76 lines
2.5 KiB
C#

using Microsoft.AspNetCore.Mvc;
using OpcUaManager.Models;
using OpcUaManager.Services;
namespace OpcUaManager.Controllers;
[ApiController]
[Route("api/crawler")]
[Produces("application/json")]
public class CrawlerController : ControllerBase
{
private readonly OpcCrawlerService _crawlerSvc;
private readonly OpcSessionService _sessionSvc;
private readonly ILogger<CrawlerController> _logger;
public CrawlerController(
OpcCrawlerService crawlerSvc,
OpcSessionService sessionSvc,
ILogger<CrawlerController> logger)
{
_crawlerSvc = crawlerSvc;
_sessionSvc = sessionSvc;
_logger = logger;
}
/// <summary>
/// 지정한 시작 노드부터 OPC UA 노드 트리를 재귀 탐색합니다.
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /api/crawler/start
/// {
/// "startNodeId": "ns=1;s=$assetmodel",
/// "maxDepth": 5
/// }
///
/// 탐색 결과는 응답 JSON 과 함께 서버 로컬에 Honeywell_FullMap.csv 로 저장됩니다.
/// </remarks>
[HttpPost("start")]
[ProducesResponseType(typeof(CrawlResult), 200)]
[ProducesResponseType(typeof(ApiError), 400)]
public async Task<IActionResult> Start([FromBody] CrawlRequest req)
{
if (!_sessionSvc.IsConnected)
return BadRequest(new ApiError
{
Error = "세션 없음",
Detail = "먼저 /api/session/connect 로 OPC 서버에 연결하세요."
});
_logger.LogInformation("Crawler 시작: {NodeId} (depth={Depth})",
req.StartNodeId, req.MaxDepth);
// 대규모 탐사는 시간이 오래 걸릴 수 있으므로 타임아웃을 늘려줍니다
HttpContext.RequestAborted.ThrowIfCancellationRequested();
var result = await _crawlerSvc.CrawlAsync(req);
return result.Success ? Ok(result)
: BadRequest(new ApiError { Error = "탐사 실패", Detail = result.Message });
}
/// <summary>마지막 탐사로 생성된 CSV 파일을 다운로드합니다.</summary>
[HttpGet("csv")]
public IActionResult DownloadCsv()
{
string path = Path.GetFullPath("Honeywell_FullMap.csv");
if (!System.IO.File.Exists(path))
return NotFound(new ApiError { Error = "CSV 없음", Detail = "탐사를 먼저 실행하세요." });
byte[] bytes = System.IO.File.ReadAllBytes(path);
return File(bytes, "text/csv", "Honeywell_FullMap.csv");
}
}