Skip to content

Commit

Permalink
增加推送到Redis功能。
Browse files Browse the repository at this point in the history
  • Loading branch information
Codespilot committed Jan 27, 2024
1 parent 201a209 commit 4bd9ac9
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 112 deletions.
6 changes: 5 additions & 1 deletion Source/Starfish.Client/Starfish.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
</ItemGroup>

<ItemGroup>
<None Include="README.md" Pack="True" PackagePath="" />
<None Include="README.md" Pack="True" PackagePath="" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Starfish.Common\Starfish.Common.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
28 changes: 2 additions & 26 deletions Source/Starfish.Client/StarfishConfigurationProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IO.Compression;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Nerosoft.Starfish.Common;

namespace Nerosoft.Starfish.Client;

Expand Down Expand Up @@ -66,7 +67,7 @@ private async void OnHostChanged(object sender, HostChangedEventArgs args)
{
await client.GetConfigurationAsync((data, length) =>
{
var json = Decompress(data, length);
var json = GzipHelper.Decompress(data, length);
File.WriteAllText(_cacheFile, json, Encoding.UTF8);
if (_waitHandle.IsSet)
{
Expand All @@ -85,31 +86,6 @@ await client.GetConfigurationAsync((data, length) =>
}
}

private static string Decompress(byte[] data, int count)
{
var stream = new MemoryStream(data, 0, count);
var zip = new GZipStream(stream, CompressionMode.Decompress, true);
var destStream = new MemoryStream();
var buffer = new byte[0x1000];
while (true)
{
var reader = zip.Read(buffer, 0, buffer.Length);
if (reader <= 0)
{
break;
}

destStream.Write(buffer, 0, reader);
}

zip.Close();
stream.Close();
destStream.Position = 0;
buffer = destStream.ToArray();
destStream.Close();
return Encoding.UTF8.GetString(buffer);
}

public void Dispose()
{
_waitHandle.Dispose();
Expand Down
64 changes: 64 additions & 0 deletions Source/Starfish.Common/GzipHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.IO.Compression;

namespace Nerosoft.Starfish.Common;
public static class GzipHelper
{
public static string CompressToBase64(string source)
{
var buffer = Compress(source);

return Convert.ToBase64String(buffer);
}

public static byte[] Compress(string source)
{
var data = Encoding.UTF8.GetBytes(source);

var stream = new MemoryStream();
var zip = new GZipStream(stream, CompressionMode.Compress, true);
zip.Write(data, 0, data.Length);
zip.Close();
var buffer = new byte[stream.Length];
stream.Position = 0;
_ = stream.Read(buffer, 0, buffer.Length);
stream.Close();

return buffer;
}

public static string DecompressFromBase64(string base64Data)
{
var data = Convert.FromBase64String(base64Data);
return Decompress(data);
}

public static string Decompress(byte[] data)
{
return Decompress(data, data.Length);
}

public static string Decompress(byte[] data, int count)
{
var stream = new MemoryStream(data, 0, count);
var zip = new GZipStream(stream, CompressionMode.Decompress, true);
var destStream = new MemoryStream();
var buffer = new byte[0x1000];
while (true)
{
var reader = zip.Read(buffer, 0, buffer.Length);
if (reader <= 0)
{
break;
}

destStream.Write(buffer, 0, reader);
}

zip.Close();
stream.Close();
destStream.Position = 0;
buffer = destStream.ToArray();
destStream.Close();
return Encoding.UTF8.GetString(buffer);
}
}
3 changes: 3 additions & 0 deletions Source/Starfish.Common/Starfish.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="System.Text.Json" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,6 @@ public interface ISettingApplicationService : IApplicationService
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<string> GetItemsInTextAsync(long appId, string environment, string format, CancellationToken cancellationToken = default);

Task PushRedisAsync(long appId, string environment, PushRedisRequestDto data, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public Task PublishAsync(long appId, string environment, SettingPublishDto data,
public Task<string> GetSettingRawAsync(long appId, string environment, CancellationToken cancellationToken = default)
{
var useCase = LazyServiceProvider.GetRequiredService<IGetSettingRawUseCase>();
var input = new GetSettingRawUseCaseInput(appId, environment);
var input = new GetSettingRawInput(appId, environment);
return useCase.ExecuteAsync(input, cancellationToken)
.ContinueWith(t => t.Result.Result, cancellationToken);
}
Expand All @@ -101,4 +101,11 @@ public Task<string> GetItemsInTextAsync(long appId, string environment, string f
return Cryptography.Base64.Encrypt(text);
}, cancellationToken);
}

public Task PushRedisAsync(long appId, string environment, PushRedisRequestDto data, CancellationToken cancellationToken = default)
{
var useCase = LazyServiceProvider.GetRequiredService<IPushRedisUseCase>();
var input = new PushRedisInput(appId, environment, data);
return useCase.ExecuteAsync(input, cancellationToken);
}
}
22 changes: 3 additions & 19 deletions Source/Starfish.Service/Domain/Business/SettingArchiveBusiness.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.IO.Compression;
using Nerosoft.Euonia.Business;
using Nerosoft.Euonia.Business;
using Nerosoft.Euonia.Domain;
using Nerosoft.Starfish.Common;
using Newtonsoft.Json;

namespace Nerosoft.Starfish.Domain;
Expand Down Expand Up @@ -30,7 +30,7 @@ protected async Task ExecuteAsync(long appId, string environment, string userNam

archive ??= SettingArchive.Create(appId, environment);

archive.Update(Compress(json), userName);
archive.Update(GzipHelper.CompressToBase64(json), userName);

if (archive.Id > 0)
{
Expand All @@ -41,20 +41,4 @@ protected async Task ExecuteAsync(long appId, string environment, string userNam
await ArchiveRepository.InsertAsync(archive, true, cancellationToken);
}
}

private static string Compress(string source)
{
var data = Encoding.UTF8.GetBytes(source);

var stream = new MemoryStream();
var zip = new GZipStream(stream, CompressionMode.Compress, true);
zip.Write(data, 0, data.Length);
zip.Close();
var buffer = new byte[stream.Length];
stream.Position = 0;
_ = stream.Read(buffer, 0, buffer.Length);
stream.Close();

return Convert.ToBase64String(buffer);
}
}
18 changes: 4 additions & 14 deletions Source/Starfish.Service/UseCases/Setting/GetSettingRawUseCase.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using Nerosoft.Euonia.Application;
using Nerosoft.Euonia.Linq;
using Nerosoft.Starfish.Domain;
using Nerosoft.Starfish.Repository;

namespace Nerosoft.Starfish.UseCases;

public interface IGetSettingRawUseCase : IUseCase<GetSettingRawUseCaseInput, GetSettingRawUseCaseOutput>;
public interface IGetSettingRawUseCase : IUseCase<GetSettingRawInput, GetSettingRawUseCaseOutput>;

public record GetSettingRawUseCaseOutput(string Result) : IUseCaseOutput;

public record GetSettingRawUseCaseInput(long AppId, string Environment) : IUseCaseInput;
public record GetSettingRawInput(long AppId, string Environment) : IUseCaseInput;

public class GetSettingRawUseCase : IGetSettingRawUseCase
{
Expand All @@ -20,17 +18,9 @@ public GetSettingRawUseCase(ISettingArchiveRepository repository)
_repository = repository;
}

public Task<GetSettingRawUseCaseOutput> ExecuteAsync(GetSettingRawUseCaseInput input, CancellationToken cancellationToken = default)
public Task<GetSettingRawUseCaseOutput> ExecuteAsync(GetSettingRawInput input, CancellationToken cancellationToken = default)
{
ISpecification<SettingArchive>[] specifications =
{
SettingArchiveSpecification.AppIdEquals(input.AppId),
SettingArchiveSpecification.EnvironmentEquals(input.Environment)
};

var predicate = new CompositeSpecification<SettingArchive>(PredicateOperator.AndAlso, specifications).Satisfy();

return _repository.GetAsync(predicate, cancellationToken)
return _repository.GetAsync(input.AppId, input.Environment, cancellationToken)
.ContinueWith(t => new GetSettingRawUseCaseOutput(t.Result.Data), cancellationToken);
}
}
65 changes: 65 additions & 0 deletions Source/Starfish.Service/UseCases/Setting/PushRedisUseCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Text.Json;
using Nerosoft.Euonia.Application;
using Nerosoft.Euonia.Claims;
using Nerosoft.Starfish.Common;
using Nerosoft.Starfish.Domain;
using Nerosoft.Starfish.Transit;
using StackExchange.Redis;

namespace Nerosoft.Starfish.UseCases;

internal interface IPushRedisUseCase : INonOutputUseCase<PushRedisInput>;

internal record PushRedisInput(long AppId, string Environment, PushRedisRequestDto Data) : IUseCaseInput;

internal sealed class PushRedisUseCase : IPushRedisUseCase
{
private readonly ISettingArchiveRepository _settingRepository;
private readonly IAppInfoRepository _appInfoRepository;
private readonly UserPrincipal _identity;

public PushRedisUseCase(ISettingArchiveRepository settingRepository, IAppInfoRepository appInfoRepository, UserPrincipal identity)
{
_settingRepository = settingRepository;
_appInfoRepository = appInfoRepository;
_identity = identity;
}

public async Task ExecuteAsync(PushRedisInput input, CancellationToken cancellationToken = default)
{
var permission = await _appInfoRepository.CheckPermissionAsync(input.AppId, _identity.GetUserIdOfInt64(), cancellationToken);

if (!permission.IsIn(1, 2))
{
throw new UnauthorizedAccessException();
}

var archive = await _settingRepository.GetAsync(input.AppId, input.Environment, cancellationToken);

if (archive == null)
{
throw new SettingNotFoundException(input.AppId, input.Environment);
}

if (string.IsNullOrWhiteSpace(archive.Data))
{
throw new InvalidDataException();
}

var data = GzipHelper.DecompressFromBase64(archive.Data);

var items = JsonSerializer.Deserialize<Dictionary<string, string>>(data);

var connection = ConnectionMultiplexer.Connect(input.Data.ConnectionString);
using (connection)
{
var entries = items.Select(t => new HashEntry(t.Key, t.Value)).ToArray();

var database = connection.GetDatabase(input.Data.Database);

await database.HashSetAsync(input.Data.Key, entries);
await database.KeyExpireAsync(input.Data.Key, default(TimeSpan?));
await connection.CloseAsync();
}
}
}
22 changes: 22 additions & 0 deletions Source/Starfish.Transit/Setting/PushRedisRequestDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Nerosoft.Starfish.Transit;

/// <summary>
/// 同步配置到Redis请求Dto
/// </summary>
public class PushRedisRequestDto
{
/// <summary>
/// Redis连接字符串
/// </summary>
public string ConnectionString { get; set; }

/// <summary>
/// 数据库
/// </summary>
public int Database { get; set; }

/// <summary>
/// Redis键名称
/// </summary>
public string Key { get; set; }
}
14 changes: 14 additions & 0 deletions Source/Starfish.Webapi/Controllers/SettingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,18 @@ public async Task<IActionResult> GetArchivedAsync(long id, string environment)
var result = await _service.GetSettingRawAsync(id, environment, HttpContext.RequestAborted);
return Ok(result);
}

/// <summary>
/// 推送到Redis
/// </summary>
/// <param name="id"></param>
/// <param name="environment"></param>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost("redis")]
public async Task<IActionResult> PushRedisAsync(long id, string environment, [FromBody] PushRedisRequestDto data)
{
await _service.PushRedisAsync(id, environment, data, HttpContext.RequestAborted);
return Ok();
}
}
Loading

0 comments on commit 4bd9ac9

Please sign in to comment.