233 lines
8.7 KiB
C#
233 lines
8.7 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Text;
|
|
using RobotNet10.CustomConfigurationEditor.Models;
|
|
|
|
namespace RobotNet10.CustomConfigurationEditor.Services.API;
|
|
|
|
/// <summary>
|
|
/// Service cho giao tiếp với Config REST API
|
|
/// </summary>
|
|
public class ConfigApiService(HttpClient httpClient)
|
|
{
|
|
private readonly HttpClient _httpClient = httpClient;
|
|
private readonly string? _baseUrl = httpClient.BaseAddress?.AbsoluteUri;
|
|
private const string ApiPath = "api/configs";
|
|
|
|
// ==========================================
|
|
// CONFIG FILE MANAGEMENT
|
|
// ==========================================
|
|
|
|
/// <summary>
|
|
/// Lấy tất cả configs (metadata only)
|
|
/// </summary>
|
|
public async Task<List<ConfigFileMetadataModel>> GetAllConfigsAsync(string? search = null)
|
|
{
|
|
var url = $"{_baseUrl}{ApiPath}";
|
|
if (!string.IsNullOrEmpty(search))
|
|
url += $"?search={Uri.EscapeDataString(search)}";
|
|
|
|
return await _httpClient.GetFromJsonAsync<List<ConfigFileMetadataModel>>(url) ?? [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lấy config theo ID
|
|
/// </summary>
|
|
public async Task<ConfigFileModel?> GetConfigByIdAsync(Guid id)
|
|
{
|
|
return await _httpClient.GetFromJsonAsync<ConfigFileModel>($"{_baseUrl}{ApiPath}/{id}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lấy config theo ConfigType
|
|
/// </summary>
|
|
public async Task<ConfigFileModel?> GetConfigByTypeAsync(string configType)
|
|
{
|
|
return await _httpClient.GetFromJsonAsync<ConfigFileModel>($"{_baseUrl}{ApiPath}/by-type/{Uri.EscapeDataString(configType)}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kiểm tra ConfigType có tồn tại không
|
|
/// </summary>
|
|
public async Task<bool> ConfigTypeExistsAsync(string configType)
|
|
{
|
|
return await _httpClient.GetFromJsonAsync<bool>($"{_baseUrl}{ApiPath}/exists/{Uri.EscapeDataString(configType)}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tạo config mới
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> CreateConfigAsync(string configType, List<ConfigVariableModel> variables, string? description = null)
|
|
{
|
|
var request = new
|
|
{
|
|
ConfigType = configType,
|
|
Variables = variables,
|
|
Description = description
|
|
};
|
|
|
|
var response = await _httpClient.PostAsJsonAsync($"{_baseUrl}{ApiPath}", request);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to create config. Invalid response from server.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cập nhật config
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> UpdateConfigAsync(Guid id, List<ConfigVariableModel>? variables = null, string? description = null)
|
|
{
|
|
var request = new
|
|
{
|
|
Variables = variables,
|
|
Description = description
|
|
};
|
|
|
|
var response = await _httpClient.PutAsJsonAsync($"{_baseUrl}{ApiPath}/{id}", request);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to update config. Invalid response from server.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Xóa config
|
|
/// </summary>
|
|
public async Task DeleteConfigAsync(Guid id)
|
|
{
|
|
var response = await _httpClient.DeleteAsync($"{_baseUrl}{ApiPath}/{id}");
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// IMPORT/EXPORT
|
|
// ==========================================
|
|
|
|
/// <summary>
|
|
/// Import config từ JSON file
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> ImportConfigAsync(Stream fileStream, string fileName, string configType, string? description = null)
|
|
{
|
|
using var content = new MultipartFormDataContent();
|
|
var streamContent = new StreamContent(fileStream);
|
|
streamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
|
|
content.Add(streamContent, "file", fileName);
|
|
content.Add(new StringContent(configType), "configType");
|
|
if (!string.IsNullOrWhiteSpace(description))
|
|
{
|
|
content.Add(new StringContent(description), "description");
|
|
}
|
|
|
|
var response = await _httpClient.PostAsync($"{_baseUrl}{ApiPath}/import", content);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to import config. Invalid response from server.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Export config ra JSON file
|
|
/// </summary>
|
|
public async Task<Stream> ExportConfigAsync(Guid id)
|
|
{
|
|
var response = await _httpClient.GetAsync($"{_baseUrl}{ApiPath}/{id}/export");
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
try
|
|
{
|
|
// Read content as byte array first, then create memory stream
|
|
var bytes = await response.Content.ReadAsByteArrayAsync();
|
|
var memoryStream = new MemoryStream(bytes);
|
|
memoryStream.Position = 0; // Reset position to beginning
|
|
return memoryStream;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new HttpRequestException($"Failed to read export data: {HttpErrorHelper.GetErrorMessage(ex)}", ex);
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// VARIABLE MANAGEMENT
|
|
// ==========================================
|
|
|
|
/// <summary>
|
|
/// Cập nhật giá trị của một variable
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> UpdateVariableAsync(Guid configId, string variableName, object? value)
|
|
{
|
|
var request = new { Value = value };
|
|
|
|
var response = await _httpClient.PutAsJsonAsync($"{_baseUrl}{ApiPath}/{configId}/variables/{Uri.EscapeDataString(variableName)}", request);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to update variable. Invalid response from server.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Thêm variable mới vào config
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> AddVariableAsync(Guid configId, ConfigVariableModel variable)
|
|
{
|
|
var response = await _httpClient.PostAsJsonAsync($"{_baseUrl}{ApiPath}/{configId}/variables", variable);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to add variable. Invalid response from server.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Xóa variable khỏi config
|
|
/// </summary>
|
|
public async Task<ConfigFileModel> RemoveVariableAsync(Guid configId, string variableName)
|
|
{
|
|
var response = await _httpClient.DeleteAsync($"{_baseUrl}{ApiPath}/{configId}/variables/{Uri.EscapeDataString(variableName)}");
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorMessage = await HttpErrorHelper.GetErrorMessageAsync(response);
|
|
throw new HttpRequestException(errorMessage);
|
|
}
|
|
|
|
return await response.Content.ReadFromJsonAsync<ConfigFileModel>()
|
|
?? throw new Exception("Failed to remove variable. Invalid response from server.");
|
|
}
|
|
}
|