♻️ Extract the Storage service to DysonNetwork.Drive microservice

This commit is contained in:
2025-07-06 17:29:26 +08:00
parent 6a3d04af3d
commit 14b79f16f4
71 changed files with 2629 additions and 346 deletions

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using DysonNetwork.Common.Interfaces;
using DysonNetwork.Common.Models;
using Microsoft.Extensions.Logging;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
namespace DysonNetwork.Drive.Clients
{
public class FileReferenceServiceClient : IFileReferenceServiceClient, IDisposable
{
private readonly HttpClient _httpClient;
private readonly ILogger<FileReferenceServiceClient> _logger;
private readonly JsonSerializerOptions _jsonOptions;
public FileReferenceServiceClient(HttpClient httpClient, ILogger<FileReferenceServiceClient> logger)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_jsonOptions = new JsonSerializerOptions()
.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
_jsonOptions.PropertyNameCaseInsensitive = true;
}
public async Task<CloudFileReference> CreateReferenceAsync(
string fileId,
string usage,
string resourceId,
Instant? expiredAt = null,
Duration? duration = null)
{
var request = new
{
FileId = fileId,
Usage = usage,
ResourceId = resourceId,
ExpiredAt = expiredAt,
Duration = duration
};
var content = new StringContent(
JsonSerializer.Serialize(request, _jsonOptions),
Encoding.UTF8,
"application/json");
var response = await _httpClient.PostAsync("api/filereferences", content);
response.EnsureSuccessStatusCode();
await using var responseStream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<CloudFileReference>(responseStream, _jsonOptions)
?? throw new InvalidOperationException("Failed to deserialize reference response");
}
public async Task DeleteReferenceAsync(string referenceId)
{
var response = await _httpClient.DeleteAsync($"api/filereferences/{referenceId}");
response.EnsureSuccessStatusCode();
}
public async Task DeleteResourceReferencesAsync(string resourceId, string? usage = null)
{
var url = $"api/filereferences/resource/{Uri.EscapeDataString(resourceId)}";
if (!string.IsNullOrEmpty(usage))
{
url += $"?usage={Uri.EscapeDataString(usage)}";
}
var response = await _httpClient.DeleteAsync(url);
response.EnsureSuccessStatusCode();
}
public async Task<List<CloudFileReference>> GetFileReferencesAsync(string fileId)
{
var response = await _httpClient.GetAsync($"api/filereferences/file/{fileId}");
response.EnsureSuccessStatusCode();
await using var responseStream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<List<CloudFileReference>>(responseStream, _jsonOptions)
?? new List<CloudFileReference>();
}
public async Task<List<CloudFileReference>> GetResourceReferencesAsync(string resourceId, string? usage = null)
{
var url = $"api/filereferences/resource/{Uri.EscapeDataString(resourceId)}";
if (!string.IsNullOrEmpty(usage))
{
url += $"?usage={Uri.EscapeDataString(usage)}";
}
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
await using var responseStream = await response.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<List<CloudFileReference>>(responseStream, _jsonOptions)
?? new List<CloudFileReference>();
}
public async Task<bool> HasReferencesAsync(string fileId)
{
var response = await _httpClient.GetAsync($"api/filereferences/file/{fileId}/has-references");
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<bool>(result, _jsonOptions);
}
public async Task UpdateReferenceExpirationAsync(string referenceId, Instant? expiredAt)
{
var request = new { ExpiredAt = expiredAt };
var content = new StringContent(
JsonSerializer.Serialize(request, _jsonOptions),
Encoding.UTF8,
"application/json");
var response = await _httpClient.PatchAsync($"api/filereferences/{referenceId}", content);
response.EnsureSuccessStatusCode();
}
public void Dispose()
{
_httpClient?.Dispose();
GC.SuppressFinalize(this);
}
}
}