♻️ Remix things up
This commit is contained in:
@ -4,6 +4,7 @@ using DysonNetwork.Shared.Auth;
|
|||||||
using DysonNetwork.Shared.Http;
|
using DysonNetwork.Shared.Http;
|
||||||
using DysonNetwork.Shared.Registry;
|
using DysonNetwork.Shared.Registry;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using tusdotnet.Stores;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ builder.Services.AddAppAuthentication();
|
|||||||
builder.Services.AddAppSwagger();
|
builder.Services.AddAppSwagger();
|
||||||
builder.Services.AddDysonAuth(builder.Configuration);
|
builder.Services.AddDysonAuth(builder.Configuration);
|
||||||
|
|
||||||
|
builder.Services.AddAppFileStorage(builder.Configuration);
|
||||||
|
|
||||||
// Add flush handlers and websocket handlers
|
// Add flush handlers and websocket handlers
|
||||||
builder.Services.AddAppFlushHandlers();
|
builder.Services.AddAppFlushHandlers();
|
||||||
|
|
||||||
@ -36,8 +39,10 @@ using (var scope = app.Services.CreateScope())
|
|||||||
await db.Database.MigrateAsync();
|
await db.Database.MigrateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tusDiskStore = app.Services.GetRequiredService<TusDiskStore>();
|
||||||
|
|
||||||
// Configure application middleware pipeline
|
// Configure application middleware pipeline
|
||||||
app.ConfigureAppMiddleware(builder.Configuration);
|
app.ConfigureAppMiddleware(tusDiskStore);
|
||||||
|
|
||||||
// Configure gRPC
|
// Configure gRPC
|
||||||
app.ConfigureGrpcServices();
|
app.ConfigureGrpcServices();
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
using DysonNetwork.Drive.Storage;
|
||||||
|
using tusdotnet;
|
||||||
|
using tusdotnet.Interfaces;
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Startup;
|
namespace DysonNetwork.Drive.Startup;
|
||||||
|
|
||||||
public static class ApplicationBuilderExtensions
|
public static class ApplicationBuilderExtensions
|
||||||
{
|
{
|
||||||
public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration)
|
public static WebApplication ConfigureAppMiddleware(this WebApplication app, ITusStore tusStore)
|
||||||
{
|
{
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
@ -14,6 +18,8 @@ public static class ApplicationBuilderExtensions
|
|||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.MapTus("/tus", _ => Task.FromResult(TusService.BuildConfiguration(tusStore)));
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
@ -21,7 +27,8 @@ public static class ApplicationBuilderExtensions
|
|||||||
public static WebApplication ConfigureGrpcServices(this WebApplication app)
|
public static WebApplication ConfigureGrpcServices(this WebApplication app)
|
||||||
{
|
{
|
||||||
// Map your gRPC services here
|
// Map your gRPC services here
|
||||||
// Example: app.MapGrpcService<MyGrpcService>();
|
app.MapGrpcService<FileServiceGrpc>();
|
||||||
|
app.MapGrpcService<FileReferenceServiceGrpc>();
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.RateLimiting;
|
using System.Threading.RateLimiting;
|
||||||
using dotnet_etcd.interfaces;
|
|
||||||
using DysonNetwork.Shared.Cache;
|
using DysonNetwork.Shared.Cache;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
@ -8,6 +7,7 @@ using NodaTime;
|
|||||||
using NodaTime.Serialization.SystemTextJson;
|
using NodaTime.Serialization.SystemTextJson;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
|
using tusdotnet.Stores;
|
||||||
|
|
||||||
namespace DysonNetwork.Drive.Startup;
|
namespace DysonNetwork.Drive.Startup;
|
||||||
|
|
||||||
@ -122,10 +122,23 @@ public static class ServiceCollectionExtensions
|
|||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddAppFileStorage(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var tusStorePath = configuration.GetSection("Tus").GetValue<string>("StorePath")!;
|
||||||
|
Directory.CreateDirectory(tusStorePath);
|
||||||
|
var tusDiskStore = new TusDiskStore(tusStorePath);
|
||||||
|
|
||||||
|
services.AddSingleton(tusDiskStore);
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddAppBusinessServices(this IServiceCollection services)
|
public static IServiceCollection AddAppBusinessServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
// Add your business services here
|
services.AddScoped<Storage.FileService>();
|
||||||
|
services.AddScoped<Storage.FileReferenceService>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,4 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
using Duration = NodaTime.Duration;
|
using Duration = NodaTime.Duration;
|
||||||
@ -13,13 +11,9 @@ namespace DysonNetwork.Drive.Storage
|
|||||||
{
|
{
|
||||||
Instant? expiredAt = null;
|
Instant? expiredAt = null;
|
||||||
if (request.ExpiredAt != null)
|
if (request.ExpiredAt != null)
|
||||||
{
|
|
||||||
expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds);
|
expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds);
|
||||||
}
|
|
||||||
else if (request.Duration != null)
|
else if (request.Duration != null)
|
||||||
{
|
|
||||||
expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan());
|
expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan());
|
||||||
}
|
|
||||||
|
|
||||||
var reference = await fileReferenceService.CreateReferenceAsync(
|
var reference = await fileReferenceService.CreateReferenceAsync(
|
||||||
request.FileId,
|
request.FileId,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using DysonNetwork.Pass.Wallet;
|
using DysonNetwork.Pass.Wallet;
|
||||||
using DysonNetwork.Shared.Cache;
|
using DysonNetwork.Shared.Cache;
|
||||||
|
using DysonNetwork.Shared.Proto;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
@ -11,11 +12,20 @@ public class AccountEventService(
|
|||||||
AppDatabase db,
|
AppDatabase db,
|
||||||
PaymentService payment,
|
PaymentService payment,
|
||||||
ICacheService cache,
|
ICacheService cache,
|
||||||
IStringLocalizer<Localization.AccountEventResource> localizer
|
IStringLocalizer<Localization.AccountEventResource> localizer,
|
||||||
|
PusherService.PusherServiceClient pusher
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
private static readonly Random Random = new();
|
private static readonly Random Random = new();
|
||||||
private const string StatusCacheKey = "AccountStatus_";
|
private const string StatusCacheKey = "account:status:";
|
||||||
|
|
||||||
|
private async Task<bool> GetAccountIsConnected(Guid userId)
|
||||||
|
{
|
||||||
|
var resp = await pusher.GetWebsocketConnectionStatusAsync(
|
||||||
|
new GetWebsocketConnectionStatusRequest { UserId = userId.ToString() }
|
||||||
|
);
|
||||||
|
return resp.IsConnected;
|
||||||
|
}
|
||||||
|
|
||||||
public void PurgeStatusCache(Guid userId)
|
public void PurgeStatusCache(Guid userId)
|
||||||
{
|
{
|
||||||
@ -29,7 +39,7 @@ public class AccountEventService(
|
|||||||
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
|
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
|
||||||
if (cachedStatus is not null)
|
if (cachedStatus is not null)
|
||||||
{
|
{
|
||||||
cachedStatus!.IsOnline = !cachedStatus.IsInvisible; // && ws.GetAccountIsConnected(userId);
|
cachedStatus!.IsOnline = !cachedStatus.IsInvisible && await GetAccountIsConnected(userId);
|
||||||
return cachedStatus;
|
return cachedStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +91,7 @@ public class AccountEventService(
|
|||||||
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
|
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
|
||||||
if (cachedStatus != null)
|
if (cachedStatus != null)
|
||||||
{
|
{
|
||||||
cachedStatus.IsOnline = !cachedStatus.IsInvisible /* && ws.GetAccountIsConnected(userId) */;
|
cachedStatus.IsOnline = !cachedStatus.IsInvisible && await GetAccountIsConnected(userId);
|
||||||
results[userId] = cachedStatus;
|
results[userId] = cachedStatus;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -104,7 +114,7 @@ public class AccountEventService(
|
|||||||
|
|
||||||
foreach (var status in statusesFromDb)
|
foreach (var status in statusesFromDb)
|
||||||
{
|
{
|
||||||
var isOnline = false; // ws.GetAccountIsConnected(status.AccountId);
|
var isOnline = await GetAccountIsConnected(status.AccountId);
|
||||||
status.IsOnline = !status.IsInvisible && isOnline;
|
status.IsOnline = !status.IsInvisible && isOnline;
|
||||||
results[status.AccountId] = status;
|
results[status.AccountId] = status;
|
||||||
var cacheKey = $"{StatusCacheKey}{status.AccountId}";
|
var cacheKey = $"{StatusCacheKey}{status.AccountId}";
|
||||||
@ -117,7 +127,7 @@ public class AccountEventService(
|
|||||||
{
|
{
|
||||||
foreach (var userId in usersWithoutStatus)
|
foreach (var userId in usersWithoutStatus)
|
||||||
{
|
{
|
||||||
var isOnline = false; // ws.GetAccountIsConnected(userId);
|
var isOnline = await GetAccountIsConnected(userId);
|
||||||
var defaultStatus = new Status
|
var defaultStatus = new Status
|
||||||
{
|
{
|
||||||
Attitude = StatusAttitude.Neutral,
|
Attitude = StatusAttitude.Neutral,
|
||||||
|
@ -15,6 +15,7 @@ builder.Services.AddAppMetrics();
|
|||||||
|
|
||||||
// Add application services
|
// Add application services
|
||||||
builder.Services.AddRegistryService(builder.Configuration);
|
builder.Services.AddRegistryService(builder.Configuration);
|
||||||
|
builder.Services.AddPusherService();
|
||||||
builder.Services.AddAppServices(builder.Configuration);
|
builder.Services.AddAppServices(builder.Configuration);
|
||||||
builder.Services.AddAppRateLimiting();
|
builder.Services.AddAppRateLimiting();
|
||||||
builder.Services.AddAppAuthentication();
|
builder.Services.AddAppAuthentication();
|
||||||
|
@ -15,34 +15,34 @@ import "google/protobuf/duration.proto";
|
|||||||
message CloudFile {
|
message CloudFile {
|
||||||
// Unique identifier for the file
|
// Unique identifier for the file
|
||||||
string id = 1;
|
string id = 1;
|
||||||
|
|
||||||
// Original name of the file
|
// Original name of the file
|
||||||
string name = 2;
|
string name = 2;
|
||||||
|
|
||||||
// File metadata (e.g., dimensions, duration, etc.)
|
// File metadata (e.g., dimensions, duration, etc.)
|
||||||
map<string, google.protobuf.Value> file_meta = 3;
|
map<string, google.protobuf.Value> file_meta = 3;
|
||||||
|
|
||||||
// User-defined metadata
|
// User-defined metadata
|
||||||
map<string, google.protobuf.Value> user_meta = 4;
|
map<string, google.protobuf.Value> user_meta = 4;
|
||||||
|
|
||||||
// MIME type of the file
|
// MIME type of the file
|
||||||
string mime_type = 5;
|
string mime_type = 5;
|
||||||
|
|
||||||
// File content hash (e.g., MD5, SHA-256)
|
// File content hash (e.g., MD5, SHA-256)
|
||||||
string hash = 6;
|
string hash = 6;
|
||||||
|
|
||||||
// File size in bytes
|
// File size in bytes
|
||||||
int64 size = 7;
|
int64 size = 7;
|
||||||
|
|
||||||
// Indicates if the file is stored with compression
|
// Indicates if the file is stored with compression
|
||||||
bool has_compression = 8;
|
bool has_compression = 8;
|
||||||
|
|
||||||
// URL to access the file
|
// URL to access the file
|
||||||
string url = 9;
|
string url = 9;
|
||||||
|
|
||||||
// Content type of the file
|
// Content type of the file
|
||||||
string content_type = 10;
|
string content_type = 10;
|
||||||
|
|
||||||
// When the file was uploaded
|
// When the file was uploaded
|
||||||
google.protobuf.Timestamp uploaded_at = 11;
|
google.protobuf.Timestamp uploaded_at = 11;
|
||||||
}
|
}
|
||||||
@ -51,28 +51,28 @@ message CloudFile {
|
|||||||
service FileService {
|
service FileService {
|
||||||
// Get file reference by ID
|
// Get file reference by ID
|
||||||
rpc GetFile(GetFileRequest) returns (CloudFile);
|
rpc GetFile(GetFileRequest) returns (CloudFile);
|
||||||
|
|
||||||
// Update an existing file reference
|
// Update an existing file reference
|
||||||
rpc UpdateFile(UpdateFileRequest) returns (CloudFile);
|
rpc UpdateFile(UpdateFileRequest) returns (CloudFile);
|
||||||
|
|
||||||
// Delete a file reference
|
// Delete a file reference
|
||||||
rpc DeleteFile(DeleteFileRequest) returns (google.protobuf.Empty);
|
rpc DeleteFile(DeleteFileRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
// Process and upload a new file
|
// Process and upload a new file
|
||||||
rpc ProcessNewFile(stream ProcessNewFileRequest) returns (CloudFile);
|
rpc ProcessNewFile(stream ProcessNewFileRequest) returns (CloudFile);
|
||||||
|
|
||||||
// Upload a file to remote storage
|
// Upload a file to remote storage
|
||||||
rpc UploadFileToRemote(stream UploadFileToRemoteRequest) returns (CloudFile);
|
rpc UploadFileToRemote(stream UploadFileToRemoteRequest) returns (CloudFile);
|
||||||
|
|
||||||
// Delete file data from storage
|
// Delete file data from storage
|
||||||
rpc DeleteFileData(DeleteFileDataRequest) returns (google.protobuf.Empty);
|
rpc DeleteFileData(DeleteFileDataRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
// Load files from references
|
// Load files from references
|
||||||
rpc LoadFromReference(LoadFromReferenceRequest) returns (LoadFromReferenceResponse);
|
rpc LoadFromReference(LoadFromReferenceRequest) returns (LoadFromReferenceResponse);
|
||||||
|
|
||||||
// Check if a file is referenced by any resource
|
// Check if a file is referenced by any resource
|
||||||
rpc IsReferenced(IsReferencedRequest) returns (IsReferencedResponse);
|
rpc IsReferenced(IsReferencedRequest) returns (IsReferencedResponse);
|
||||||
|
|
||||||
// Purge cache for a file
|
// Purge cache for a file
|
||||||
rpc PurgeCache(PurgeCacheRequest) returns (google.protobuf.Empty);
|
rpc PurgeCache(PurgeCacheRequest) returns (google.protobuf.Empty);
|
||||||
}
|
}
|
||||||
@ -160,19 +160,19 @@ message PurgeCacheRequest {
|
|||||||
message CloudFileReference {
|
message CloudFileReference {
|
||||||
// Unique identifier for the reference
|
// Unique identifier for the reference
|
||||||
string id = 1;
|
string id = 1;
|
||||||
|
|
||||||
// Reference to the actual file
|
// Reference to the actual file
|
||||||
string file_id = 2;
|
string file_id = 2;
|
||||||
|
|
||||||
// The actual file data (optional, can be populated when needed)
|
// The actual file data (optional, can be populated when needed)
|
||||||
CloudFile file = 3;
|
CloudFile file = 3;
|
||||||
|
|
||||||
// Description of how this file is being used
|
// Description of how this file is being used
|
||||||
string usage = 4;
|
string usage = 4;
|
||||||
|
|
||||||
// ID of the resource that this file is associated with
|
// ID of the resource that this file is associated with
|
||||||
string resource_id = 5;
|
string resource_id = 5;
|
||||||
|
|
||||||
// Optional expiration timestamp for the reference
|
// Optional expiration timestamp for the reference
|
||||||
google.protobuf.Timestamp expired_at = 6;
|
google.protobuf.Timestamp expired_at = 6;
|
||||||
}
|
}
|
||||||
@ -182,8 +182,8 @@ message CreateReferenceRequest {
|
|||||||
string file_id = 1;
|
string file_id = 1;
|
||||||
string usage = 2;
|
string usage = 2;
|
||||||
string resource_id = 3;
|
string resource_id = 3;
|
||||||
google.protobuf.Timestamp expired_at = 4;
|
optional google.protobuf.Timestamp expired_at = 4;
|
||||||
google.protobuf.Duration duration = 5; // Alternative to expired_at
|
optional google.protobuf.Duration duration = 5; // Alternative to expired_at
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetReferencesRequest {
|
message GetReferencesRequest {
|
||||||
@ -268,34 +268,34 @@ message HasFileReferencesResponse {
|
|||||||
service FileReferenceService {
|
service FileReferenceService {
|
||||||
// Creates a new reference to a file for a specific resource
|
// Creates a new reference to a file for a specific resource
|
||||||
rpc CreateReference(CreateReferenceRequest) returns (CloudFileReference);
|
rpc CreateReference(CreateReferenceRequest) returns (CloudFileReference);
|
||||||
|
|
||||||
// Gets all references to a file
|
// Gets all references to a file
|
||||||
rpc GetReferences(GetReferencesRequest) returns (GetReferencesResponse);
|
rpc GetReferences(GetReferencesRequest) returns (GetReferencesResponse);
|
||||||
|
|
||||||
// Gets the number of references to a file
|
// Gets the number of references to a file
|
||||||
rpc GetReferenceCount(GetReferenceCountRequest) returns (GetReferenceCountResponse);
|
rpc GetReferenceCount(GetReferenceCountRequest) returns (GetReferenceCountResponse);
|
||||||
|
|
||||||
// Gets all references for a specific resource and optional usage
|
// Gets all references for a specific resource and optional usage
|
||||||
rpc GetResourceReferences(GetResourceReferencesRequest) returns (GetReferencesResponse);
|
rpc GetResourceReferences(GetResourceReferencesRequest) returns (GetReferencesResponse);
|
||||||
|
|
||||||
// Gets all files referenced by a resource with optional usage filter
|
// Gets all files referenced by a resource with optional usage filter
|
||||||
rpc GetResourceFiles(GetResourceFilesRequest) returns (GetResourceFilesResponse);
|
rpc GetResourceFiles(GetResourceFilesRequest) returns (GetResourceFilesResponse);
|
||||||
|
|
||||||
// Deletes references for a specific resource and optional usage
|
// Deletes references for a specific resource and optional usage
|
||||||
rpc DeleteResourceReferences(DeleteResourceReferencesRequest) returns (DeleteResourceReferencesResponse);
|
rpc DeleteResourceReferences(DeleteResourceReferencesRequest) returns (DeleteResourceReferencesResponse);
|
||||||
|
|
||||||
// Deletes a specific file reference
|
// Deletes a specific file reference
|
||||||
rpc DeleteReference(DeleteReferenceRequest) returns (DeleteReferenceResponse);
|
rpc DeleteReference(DeleteReferenceRequest) returns (DeleteReferenceResponse);
|
||||||
|
|
||||||
// Updates the files referenced by a resource
|
// Updates the files referenced by a resource
|
||||||
rpc UpdateResourceFiles(UpdateResourceFilesRequest) returns (UpdateResourceFilesResponse);
|
rpc UpdateResourceFiles(UpdateResourceFilesRequest) returns (UpdateResourceFilesResponse);
|
||||||
|
|
||||||
// Updates the expiration time for a file reference
|
// Updates the expiration time for a file reference
|
||||||
rpc SetReferenceExpiration(SetReferenceExpirationRequest) returns (SetReferenceExpirationResponse);
|
rpc SetReferenceExpiration(SetReferenceExpirationRequest) returns (SetReferenceExpirationResponse);
|
||||||
|
|
||||||
// Updates the expiration time for all references to a file
|
// Updates the expiration time for all references to a file
|
||||||
rpc SetFileReferencesExpiration(SetFileReferencesExpirationRequest) returns (SetFileReferencesExpirationResponse);
|
rpc SetFileReferencesExpiration(SetFileReferencesExpirationRequest) returns (SetFileReferencesExpirationResponse);
|
||||||
|
|
||||||
// Checks if a file has any references
|
// Checks if a file has any references
|
||||||
rpc HasFileReferences(HasFileReferencesRequest) returns (HasFileReferencesResponse);
|
rpc HasFileReferences(HasFileReferencesRequest) returns (HasFileReferencesResponse);
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ public static class ServiceHelper
|
|||||||
{
|
{
|
||||||
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
||||||
var config = sp.GetRequiredService<IConfiguration>();
|
var config = sp.GetRequiredService<IConfiguration>();
|
||||||
var clientCertPath = config["Service:ClientCert"];
|
var clientCertPath = config["Service:ClientCert"]!;
|
||||||
var clientKeyPath = config["Service:ClientKey"];
|
var clientKeyPath = config["Service:ClientKey"]!;
|
||||||
var clientCertPassword = config["Service:CertPassword"];
|
var clientCertPassword = config["Service:CertPassword"];
|
||||||
|
|
||||||
return GrpcClientHelper
|
return GrpcClientHelper
|
||||||
@ -32,8 +32,8 @@ public static class ServiceHelper
|
|||||||
{
|
{
|
||||||
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
||||||
var config = sp.GetRequiredService<IConfiguration>();
|
var config = sp.GetRequiredService<IConfiguration>();
|
||||||
var clientCertPath = config["Service:ClientCert"];
|
var clientCertPath = config["Service:ClientCert"]!;
|
||||||
var clientKeyPath = config["Service:ClientKey"];
|
var clientKeyPath = config["Service:ClientKey"]!;
|
||||||
var clientCertPassword = config["Service:CertPassword"];
|
var clientCertPassword = config["Service:CertPassword"];
|
||||||
|
|
||||||
return GrpcClientHelper
|
return GrpcClientHelper
|
||||||
|
Reference in New Issue
Block a user