diff --git a/Directory.Build.props b/Directory.Build.props index 51099439..8a65bc83 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 1.2.0-preview.2 - 1.2.1-preview.4 + 1.2.0-preview.4 + 1.2.1-preview.8 \ No newline at end of file diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/App.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/App.cs new file mode 100644 index 00000000..8b7f101b --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/App.cs @@ -0,0 +1,38 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[NotMapped] +public class App +{ + public int Id { get; set; } + + public string Name { get; set; } = ""; + + public string Identity { get; set; } = ""; + + public AppTypes Type { get; set; } + + public ServiceTypes ServiceType { get; set; } + + public string Url { get; set; } = ""; + + public string SwaggerUrl { get; set; } = ""; + + public string Description { get; set; } = ""; + + public DateTime CreationTime { get; set; } + + public Guid Creator { get; set; } + + public DateTime ModificationTime { get; set; } + + public Guid Modifier { get; set; } + + private readonly List _appConfigObjects = new(); + public IReadOnlyCollection AppConfigObjects => _appConfigObjects; + + private readonly List _appSecrets = new(); + public IReadOnlyCollection AppSecrets => _appSecrets; +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/AppConfigObject.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppConfigObject.cs new file mode 100644 index 00000000..731ead17 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppConfigObject.cs @@ -0,0 +1,19 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("AppConfigObjects")] +public class AppConfigObject : ConfigObjectBase +{ + [Comment("AppId")] + [Required] + [Range(1, int.MaxValue)] + public int AppId { get; private set; } + + public AppConfigObject(int appId, int environmentClusterId) + { + EnvironmentClusterId = environmentClusterId; + AppId = appId; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/AppPin.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppPin.cs new file mode 100644 index 00000000..90c76040 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppPin.cs @@ -0,0 +1,16 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +public class AppPin : FullAggregateRoot +{ + [Required] + [Range(1, int.MaxValue)] + public int AppId { get; set; } + + public AppPin(int appId) + { + AppId = appId; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/AppSecret.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppSecret.cs new file mode 100644 index 00000000..9a9b7a6e --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/AppSecret.cs @@ -0,0 +1,26 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("AppSecrets")] +public class AppSecret : FullAggregateRoot +{ + [Required] + [Range(1, int.MaxValue)] + public int AppId { get; private set; } + + [Required] + [Range(1, int.MaxValue)] + public int EnvironmentId { get; private set; } + + [Required] + [Range(1, int.MaxValue)] + public SecretType Type { get; private set; } + + [Required] + public Guid EncryptionSecret { get; private set; } + + [Required] + public Guid Secret { get; private set; } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfig.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfig.cs new file mode 100644 index 00000000..020d616c --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfig.cs @@ -0,0 +1,28 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("BizConfigs")] +public class BizConfig : FullAggregateRoot +{ + [Required] + public string Name { get; private set; } + + [Required] + public string Identity { get; private set; } + + private readonly List _bizConfigObjects = new(); + public IReadOnlyCollection BizConfigObjects => _bizConfigObjects; + + public BizConfig(string name, string identity) + { + Name = name; + Identity = identity; + } + + public void Update(string name) + { + Name = name; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfigObject.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfigObject.cs new file mode 100644 index 00000000..cb99f68f --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/BizConfigObject.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("BizConfigObjects")] +public class BizConfigObject : ConfigObjectBase +{ + [Required] + [Range(1, int.MaxValue)] + public int BizConfigId { get; private set; } + + public BizConfig BizConfig { get; private set; } = null!; + + public BizConfigObject(int bizConfigId, int environmentClusterId) + { + BizConfigId = bizConfigId; + EnvironmentClusterId = environmentClusterId; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObject.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObject.cs new file mode 100644 index 00000000..9c7aa25b --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObject.cs @@ -0,0 +1,116 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("ConfigObjects")] +public class ConfigObject : FullAggregateRoot +{ + [Comment("Name")] + [Required(ErrorMessage = "Config object name is required")] + [StringLength(100, MinimumLength = 2, ErrorMessage = "Config object name length range is [2-100]")] + public string Name { get; private set; } + + [Comment("Format")] + [Required(ErrorMessage = "Format Label Code is required")] + [StringLength(100, MinimumLength = 2, ErrorMessage = "Format Label Code length range is [2-100]")] + public string FormatLabelCode { get; private set; } + + [Comment("Type")] + [Range(1, int.MaxValue, ErrorMessage = "Type is required")] + public ConfigObjectType Type { get; private set; } + + [Required] + public bool Encryption { get; private set; } + + [Required] + public string Content { get; private set; } + + [Required] + public string TempContent { get; private set; } + + [Comment("Relation config object Id")] + public int RelationConfigObjectId { get; private set; } + + public bool FromRelation { get; private set; } + + public PublicConfigObject PublicConfigObject { get; private set; } = null!; + + public BizConfigObject BizConfigObject { get; set; } = null!; + + public AppConfigObject AppConfigObject { get; private set; } = null!; + + private readonly List _configObjectRelease = new(); + public IReadOnlyCollection ConfigObjectRelease => _configObjectRelease; + + public ConfigObject(string name, string formatLabelCode, ConfigObjectType type, string content, string tempContent, int relationConfigObjectId = 0, bool fromRelation = false, bool encryption = false) + { + Name = name; + FormatLabelCode = formatLabelCode; + Type = type; + Content = content; + TempContent = tempContent; + RelationConfigObjectId = relationConfigObjectId; + FromRelation = fromRelation; + Encryption = encryption; + } + + public void SetConfigObjectType(ConfigObjectType type) + { + Type = type; + } + + public void SetConfigObjectRelease(IEnumerable configObjectReleases) + { + _configObjectRelease.Clear(); + _configObjectRelease.TryAddRange(configObjectReleases); + } + + public void SetConfigObjectRelease(ConfigObjectRelease configObjectRelease) + { + _configObjectRelease.Clear(); + _configObjectRelease.TryAdd(configObjectRelease); + } + + public void UpdateContent(string content) + { + Content = content; + } + + public void AddContent(string content, string tempContent) + { + Content = content; + TempContent = tempContent; + } + + public void SetPublicConfigObject(int publicConfigId, int environmentClusterId) + { + PublicConfigObject = new PublicConfigObject(publicConfigId, environmentClusterId); + } + + public void SetBizConfigObject(int bizId, int environmentClusterId) + { + BizConfigObject = new BizConfigObject(bizId, environmentClusterId); + } + + public void SetAppConfigObject(int appId, int environmentClusterId) + { + AppConfigObject = new AppConfigObject(appId, environmentClusterId); + } + + public void Revoke() + { + Content = TempContent; + } + + public void Relation(int relationConfigObjectId) + { + RelationConfigObjectId = relationConfigObjectId; + FromRelation = true; + } + + public void UnRelation() + { + RelationConfigObjectId = 0; + } +} diff --git a/src/Services/Masa.Dcc.Service/Domain/App/Aggregates/ConfigObjectBase.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectBase.cs similarity index 92% rename from src/Services/Masa.Dcc.Service/Domain/App/Aggregates/ConfigObjectBase.cs rename to Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectBase.cs index 574077e5..7d5c2521 100644 --- a/src/Services/Masa.Dcc.Service/Domain/App/Aggregates/ConfigObjectBase.cs +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectBase.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Domain.App.Aggregates; +namespace Masa.Dcc.Infrastructure.Domain.Shared; public abstract class ConfigObjectBase : FullAggregateRoot { diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectRelease.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectRelease.cs new file mode 100644 index 00000000..7e628d17 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/ConfigObjectRelease.cs @@ -0,0 +1,57 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("ConfigObjectReleases")] +public class ConfigObjectRelease : FullAggregateRoot +{ + [Comment("Release type")] + public ReleaseType Type { get; set; } + + [Comment("Config object Id")] + [Required(ErrorMessage = "Config object Id is required")] + [Range(minimum: 1, maximum: int.MaxValue, ErrorMessage = "Config object Id is required")] + public int ConfigObjectId { get; set; } + + [Comment("Rollback From Release Id")] + public int FromReleaseId { get; set; } + + [Comment("If it is rolled back, it will be true")] + public bool IsInvalid { get; set; } + + [Comment("Version format is yyyyMMddHHmmss")] + [Required(ErrorMessage = "Version is required")] + public string Version { get; set; } + + [Comment("Name")] + [Required(ErrorMessage = "Name is required", AllowEmptyStrings = true)] + [StringLength(100, MinimumLength = 2, ErrorMessage = "Name length range is [2-100]")] + public string Name { get; set; } + + [Comment("Comment")] + [Required(ErrorMessage = "Comment is required", AllowEmptyStrings = true)] + [StringLength(500, MinimumLength = 0, ErrorMessage = "Comment length range is [0-500]")] + public string Comment { get; set; } + + [Comment("Content")] + [Required(ErrorMessage = "Content is required", AllowEmptyStrings = true)] + [StringLength(int.MaxValue, MinimumLength = 1, ErrorMessage = "Content length range is [1-2147483647]")] + public string Content { get; set; } + + public ConfigObjectRelease(int configObjectId, string name, string comment, string content, string? version = null, int fromReleaseId = 0, ReleaseType type = ReleaseType.MainRelease) + { + ConfigObjectId = configObjectId; + Name = name; + Comment = comment; + Content = content; + Version = version ?? DateTime.UtcNow.ToString("yyyyMMddHHmmss"); + FromReleaseId = fromReleaseId; + Type = type; + } + + public void Invalid() + { + IsInvalid = true; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfig.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfig.cs new file mode 100644 index 00000000..dc037f59 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfig.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("PublicConfigs")] +public class PublicConfig : FullAggregateRoot +{ + [Required] + public string Name { get; private set; } + + [Required] + public string Identity { get; private set; } + + [Required] + public string Description { get; private set; } + + private readonly List _publicConfigObjects = new(); + public IReadOnlyCollection PublicConfigObjects => _publicConfigObjects; + + public PublicConfig(string name, string identity, string description = "") + { + Name = name; + Identity = identity; + Description = description; + } + + public void Update(string name, string description) + { + Name = name; + Description = description; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfigObject.cs b/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfigObject.cs new file mode 100644 index 00000000..c92f5bdd --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/App/PublicConfigObject.cs @@ -0,0 +1,20 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("PublicConfigObjects")] +public class PublicConfigObject : ConfigObjectBase +{ + [Required] + [Range(1, int.MaxValue)] + public int PublicConfigId { get; private set; } + + public PublicConfig PublicConfig { get; private set; } = null!; + + public PublicConfigObject(int publicConfigId, int environmentClusterId) + { + PublicConfigId = publicConfigId; + EnvironmentClusterId = environmentClusterId; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/Label/Label.cs b/Masa.Dcc.Infrastructure.Domain.Shared/Label/Label.cs new file mode 100644 index 00000000..74acd310 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/Label/Label.cs @@ -0,0 +1,54 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Shared; + +[Table("Labels")] +[Index(nameof(TypeCode), nameof(IsDeleted), Name = "IX_TypeCode")] +public class Label : FullAggregateRoot +{ + [Comment("Code")] + [Required(ErrorMessage = "Label code is required")] + [StringLength(100, MinimumLength = 2, ErrorMessage = "Label code length range is [2-100]")] + public string Code { get; set; } + + [Comment("Name")] + [Required(ErrorMessage = "Label name is required")] + [StringLength(100, MinimumLength = 2, ErrorMessage = "Label name length range is [2-100]")] + public string Name { get; private set; } + + [Comment("TypeCode")] + [Required(ErrorMessage = "TypeCode is required")] + [StringLength(255, MinimumLength = 0, ErrorMessage = "TypeCode length range is [0-255]")] + public string TypeCode { get; private set; } + + [Comment("TypeName")] + [Required(ErrorMessage = "TypeName is required")] + [StringLength(255, MinimumLength = 0, ErrorMessage = "TypeName length range is [0-255]")] + public string TypeName { get; private set; } + + [Comment("Description")] + [Required(ErrorMessage = "Description is required")] + [StringLength(255, MinimumLength = 0, ErrorMessage = "Description length range is [0-255]")] + public string Description { get; private set; } + + public Label(string code, string name, string typeCode, string typeName, string description = "") + { + Code = code; + Name = name; + TypeCode = typeCode; + TypeName = typeName; + Description = description; + } + + public Label(string code, string name, string typeCode, string typeName, Guid creator, DateTime creationTime, string description = "") + { + Code = code; + Name = name; + TypeCode = typeCode; + TypeName = typeName; + Creator = creator; + CreationTime = creationTime; + Description = description; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/Masa.Dcc.Infrastructure.Domain.Shared.csproj b/Masa.Dcc.Infrastructure.Domain.Shared/Masa.Dcc.Infrastructure.Domain.Shared.csproj new file mode 100644 index 00000000..567a5685 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/Masa.Dcc.Infrastructure.Domain.Shared.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + diff --git a/Masa.Dcc.Infrastructure.Domain.Shared/_Imports.cs b/Masa.Dcc.Infrastructure.Domain.Shared/_Imports.cs new file mode 100644 index 00000000..b645f07d --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain.Shared/_Imports.cs @@ -0,0 +1,10 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +global using System.ComponentModel.DataAnnotations; +global using System.ComponentModel.DataAnnotations.Schema; +global using Masa.BuildingBlocks.Ddd.Domain.Entities.Full; +global using Masa.BuildingBlocks.StackSdks.Pm.Enum; +global using Masa.BuildingBlocks.StackSdks.Pm.Model; +global using Masa.Dcc.Contracts.Admin.App.Enums; +global using Microsoft.EntityFrameworkCore; diff --git a/Masa.Dcc.Infrastructure.Domain/App/CommandHandler.cs b/Masa.Dcc.Infrastructure.Domain/App/CommandHandler.cs new file mode 100644 index 00000000..1dedf0ea --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/App/CommandHandler.cs @@ -0,0 +1,186 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Service.Admin.Application.App; + +internal class CommandHandler +{ + private readonly IPublicConfigRepository _publicConfigRepository; + private readonly IConfigObjectRepository _configObjectRepository; + private readonly IAppPinRepository _appPinRepository; + private readonly IBizConfigRepository _bizConfigRepository; + private readonly ConfigObjectDomainService _configObjectDomainService; + private readonly IUnitOfWork _unitOfWork; + + public CommandHandler( + IPublicConfigRepository publicConfigRepository, + IConfigObjectRepository configObjectRepository, + IAppPinRepository appPinRepository, + IBizConfigRepository bizConfigRepository, + ConfigObjectDomainService configObjectDomainService, + IUnitOfWork unitOfWork) + { + _publicConfigRepository = publicConfigRepository; + _configObjectRepository = configObjectRepository; + _appPinRepository = appPinRepository; + _bizConfigRepository = bizConfigRepository; + _configObjectDomainService = configObjectDomainService; + _unitOfWork = unitOfWork; + } + + #region PublicConfig + + [EventHandler] + public async Task AddPublicConfigAsync(AddPublicConfigCommand command) + { + var publicConfig = command.AddPublicConfigDto; + + var result = await _publicConfigRepository.AddAsync( + new PublicConfig(publicConfig.Name, publicConfig.Identity, publicConfig.Description)); + + command.PublicConfigDto = result.Adapt(); + } + + [EventHandler] + public async Task UpdatePublicConfigAsync(UpdatePublicConfigCommand command) + { + var publicConfig = command.UpdatePublicConfigDto; + var publicConfigEntity = await _publicConfigRepository.FindAsync(p => p.Id == publicConfig.Id) + ?? throw new UserFriendlyException("Public config does not exist"); + + publicConfigEntity.Update(publicConfig.Name, publicConfig.Description); + await _publicConfigRepository.UpdateAsync(publicConfigEntity); + } + + [EventHandler] + public async Task RemovePublicConfigAsync(RemovePublicConfigCommand command) + { + var publicConfigEntity = await _publicConfigRepository.FindAsync(p => p.Id == command.PublicConfigId) + ?? throw new UserFriendlyException("Public config does not exist"); + + await _publicConfigRepository.RemoveAsync(publicConfigEntity); + } + + #endregion + + #region BizConfig + + [EventHandler] + public async Task AddBizConfigAsync(AddBizConfigCommand command) + { + var bizConfig = command.AddBizConfigDto; + + var result = await _bizConfigRepository.AddAsync(new BizConfig(bizConfig.Name, bizConfig.Identity)); + + await _unitOfWork.SaveChangesAsync(); + + command.BizConfigDto = result.Adapt(); + } + + [EventHandler] + public async Task UpdateBizConfigAsync(UpdateBizConfigCommand command) + { + var bizConfig = command.UpdateBizConfigDto; + var bizConfigEntity = await _bizConfigRepository.FindAsync(p => p.Id == bizConfig.Id) + ?? throw new UserFriendlyException("biz config does not exist"); + + bizConfigEntity.Update(bizConfig.Name); + var result = await _bizConfigRepository.UpdateAsync(bizConfigEntity); + + command.BizConfigDto = result.Adapt(); + } + + #endregion + + #region ConfigObject + + [EventHandler] + public async Task AddConfigObjectAsync(AddConfigObjectCommand command) + { + await _configObjectDomainService.AddConfigObjectAsync(command.ConfigObjectDtos); + } + + [EventHandler] + public async Task RemoveConfigObjectAsync(RemoveConfigObjectCommand command) + { + await _configObjectDomainService.RemoveConfigObjectAsync(command.ConfigObjectDto); + } + + [EventHandler] + public async Task UpdateConfigObjectContentAsync(UpdateConfigObjectContentCommand command) + { + await _configObjectDomainService.UpdateConfigObjectContentAsync(command.ConfigObjectContent); + } + + [EventHandler] + public async Task RevokeConfigObjectAsync(RevokeConfigObjectCommand command) + { + var configObject = await _configObjectRepository.FindAsync(configObject => configObject.Id == command.ConfigObjectId); + + if (configObject == null) + { + throw new UserFriendlyException("Config object does not exist"); + } + + configObject.Revoke(); + + await _configObjectRepository.UpdateAsync(configObject); + } + + [EventHandler] + public async Task CloneConfigObjectAsync(CloneConfigObjectCommand command) + { + await _configObjectDomainService.CloneConfigObjectAsync(command.CloneConfigObject); + } + + #endregion + + #region Release + + [EventHandler] + public async Task AddConfigObjectRelease(AddConfigObjectReleaseCommand command) + { + await _configObjectDomainService.AddConfigObjectReleaseAsync(command.ConfigObjectRelease); + } + + [EventHandler] + public async Task RollbackConfigObjectReleaseAsync(RollbackConfigObjectReleaseCommand command) + { + await _configObjectDomainService.RollbackConfigObjectReleaseAsync(command.RollbackConfigObjectRelease); + } + + #endregion + + #region App + + [EventHandler] + public async Task AddAppPinAsync(AddAppPinCommand command) + { + await _appPinRepository.AddAsync(new AppPin(command.AppId)); + } + + [EventHandler] + public async Task RemoveAppPinAsync(RemoveAppPinCommand command) + { + var appPin = await _appPinRepository.FindAsync(appPin => appPin.AppId == command.AppId); + + if (appPin != null) + await _appPinRepository.RemoveAsync(appPin); + } + + #endregion + + [EventHandler] + public async Task UpdateConfigObjectAsync(UpdateConfigAndPublishCommand command) + { + await _configObjectDomainService.UpdateConfigObjectAsync(command.Environment, command.Cluster, + command.AppId, command.ConfigObject, command.Value); + } + + [EventHandler] + public async Task InitConfigObjectAsync(InitConfigObjectCommand command) + { + await _configObjectDomainService.InitConfigObjectAsync(command.Environment, command.Cluster, + command.AppId, command.ConfigObjects, command.ConfigObjectType, command.IsEncryption); + } +} diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddAppPinCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddAppPinCommand.cs similarity index 79% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/AddAppPinCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/AddAppPinCommand.cs index ee24b9e1..295304d6 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddAppPinCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddAppPinCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record AddAppPinCommand(int AppId) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddBizConfigCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddBizConfigCommand.cs similarity index 85% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/AddBizConfigCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/AddBizConfigCommand.cs index d931a2a9..0603d742 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddBizConfigCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddBizConfigCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { [AllowedEvent] public record AddBizConfigCommand(AddObjectConfigDto AddBizConfigDto) : Command diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectCommand.cs similarity index 81% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectCommand.cs index 993f3a64..bf5b4bc6 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record AddConfigObjectCommand(List ConfigObjectDtos) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectReleaseCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectReleaseCommand.cs similarity index 82% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectReleaseCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectReleaseCommand.cs index b2ae8bc3..debb2b84 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddConfigObjectReleaseCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddConfigObjectReleaseCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record AddConfigObjectReleaseCommand(AddConfigObjectReleaseDto ConfigObjectRelease) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddPublicConfigCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddPublicConfigCommand.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/AddPublicConfigCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/AddPublicConfigCommand.cs index 0890ecc2..cb0950e0 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/AddPublicConfigCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/AddPublicConfigCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record AddPublicConfigCommand(AddObjectConfigDto AddPublicConfigDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/CloneConfigObejctCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/CloneConfigObejctCommand.cs similarity index 81% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/CloneConfigObejctCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/CloneConfigObejctCommand.cs index 5d4be37b..814bbc5f 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/CloneConfigObejctCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/CloneConfigObejctCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record CloneConfigObjectCommand(CloneConfigObjectDto CloneConfigObject) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/InitConfigObjectCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/InitConfigObjectCommand.cs similarity index 86% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/InitConfigObjectCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/InitConfigObjectCommand.cs index fb67b2ae..3f590982 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/InitConfigObjectCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/InitConfigObjectCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record InitConfigObjectCommand(string Environment, string Cluster, string AppId, Dictionary ConfigObjects, ConfigObjectType ConfigObjectType, bool IsEncryption) : Command diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveAppPinCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveAppPinCommand.cs similarity index 79% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveAppPinCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveAppPinCommand.cs index 655dd562..13ad53c5 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveAppPinCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveAppPinCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RemoveAppPinCommand(int AppId) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveConfigObjectCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveConfigObjectCommand.cs similarity index 81% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveConfigObjectCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveConfigObjectCommand.cs index a22658d8..dcf0b876 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemoveConfigObjectCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemoveConfigObjectCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RemoveConfigObjectCommand(RemoveConfigObjectDto ConfigObjectDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemovePublicConfigCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemovePublicConfigCommand.cs similarity index 80% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/RemovePublicConfigCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/RemovePublicConfigCommand.cs index aa7b6b5a..bd1f4cd2 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/RemovePublicConfigCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/RemovePublicConfigCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RemovePublicConfigCommand(int PublicConfigId) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/RevokeConfigObjectCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/RevokeConfigObjectCommand.cs similarity index 80% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/RevokeConfigObjectCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/RevokeConfigObjectCommand.cs index 8b3718c7..d479fc6e 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/RevokeConfigObjectCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/RevokeConfigObjectCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RevokeConfigObjectCommand(int ConfigObjectId) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/RollbackConfigObjectReleaseCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/RollbackConfigObjectReleaseCommand.cs similarity index 83% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/RollbackConfigObjectReleaseCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/RollbackConfigObjectReleaseCommand.cs index bb8bc456..6d80d1c6 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/RollbackConfigObjectReleaseCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/RollbackConfigObjectReleaseCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RollbackConfigObjectReleaseCommand(RollbackConfigObjectReleaseDto RollbackConfigObjectRelease) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateBizConfigCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateBizConfigCommand.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateBizConfigCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateBizConfigCommand.cs index 79b569ca..5787c75f 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateBizConfigCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateBizConfigCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record UpdateBizConfigCommand(UpdateObjectConfigDto UpdateBizConfigDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigAndPublishCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigAndPublishCommand.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigAndPublishCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigAndPublishCommand.cs index 2e1a6511..c429012a 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigAndPublishCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigAndPublishCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record UpdateConfigAndPublishCommand(string Environment, string Cluster, string AppId, string ConfigObject, diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigObjectContentCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigObjectContentCommand.cs similarity index 82% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigObjectContentCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigObjectContentCommand.cs index 11144998..20cc32d9 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdateConfigObjectContentCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdateConfigObjectContentCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record UpdateConfigObjectContentCommand(UpdateConfigObjectContentDto ConfigObjectContent) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdatePublicConfigCommand.cs b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdatePublicConfigCommand.cs similarity index 82% rename from src/Services/Masa.Dcc.Service/Application/App/Commands/UpdatePublicConfigCommand.cs rename to Masa.Dcc.Infrastructure.Domain/App/Commands/UpdatePublicConfigCommand.cs index 990e0b31..662cb9d7 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Commands/UpdatePublicConfigCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Commands/UpdatePublicConfigCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record UpdatePublicConfigCommand(UpdateObjectConfigDto UpdatePublicConfigDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/AppLatestReleaseQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/AppLatestReleaseQuery.cs similarity index 86% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/AppLatestReleaseQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/AppLatestReleaseQuery.cs index 53ca43eb..e1ec055b 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/AppLatestReleaseQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/AppLatestReleaseQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record AppLatestReleaseQuery(List AppIds, int? EnvClusterId = null) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/AppPinQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/AppPinQuery.cs similarity index 67% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/AppPinQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/AppPinQuery.cs index 18d513e1..79b6a039 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/AppPinQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/AppPinQuery.cs @@ -1,7 +1,10 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +using Masa.BuildingBlocks.ReadWriteSplitting.Cqrs.Queries; +using Masa.Dcc.Contracts.Admin.App.Dtos; + +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record AppPinQuery(List AppIds) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/BizConfigsQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/BizConfigsQuery.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/BizConfigsQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/BizConfigsQuery.cs index 30d94b39..d3b0533f 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/BizConfigsQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/BizConfigsQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record BizConfigsQuery(string Identity) : Query { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectListQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectListQuery.cs similarity index 85% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectListQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectListQuery.cs index dcd3266e..587d352e 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectListQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectListQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record ConfigObjectListQuery(List Ids) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectReleaseQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectReleaseQuery.cs similarity index 86% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectReleaseQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectReleaseQuery.cs index ddde94be..18662402 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectReleaseQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectReleaseQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record ConfigObjectReleaseQuery(int ConfigObjectId) : Query { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsByDynamicQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsByDynamicQuery.cs similarity index 88% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsByDynamicQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsByDynamicQuery.cs index 932dcdf7..ce0a48a0 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsByDynamicQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsByDynamicQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record class ConfigObjectsByDynamicQuery(string environment, string cluster, string appId, List? configObjects) : Query> diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsQuery.cs similarity index 88% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsQuery.cs index b6ad5b0f..e6e7b0c3 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/ConfigObjectsQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/ConfigObjectsQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record ConfigObjectsQuery(int EnvClusterId, int ObjectId, ConfigObjectType Type, string ConfigObjectName, bool GetLatestRelease = false) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/ProjectLatestReleaseQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/ProjectLatestReleaseQuery.cs similarity index 86% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/ProjectLatestReleaseQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/ProjectLatestReleaseQuery.cs index 7497ba64..ae099648 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/ProjectLatestReleaseQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/ProjectLatestReleaseQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries; +namespace Masa.Dcc.Infrastructure.Domain.Queries; public record ProjectLatestReleaseQuery(List Projects, int? EnvClusterId = null) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigObjectQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigObjectQuery.cs similarity index 85% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigObjectQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigObjectQuery.cs index 1c9fbea1..667cbd64 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigObjectQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigObjectQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record PublicConfigObjectQuery(int ConfigObjectId) : Query { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigQuery.cs similarity index 85% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigQuery.cs index c71199b0..6a832aae 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries; +namespace Masa.Dcc.Infrastructure.Domain.Queries; public record class PublicConfigQuery(string Environment, string Cluster, string ConfigObject) : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigsQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigsQuery.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigsQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigsQuery.cs index bd837f4d..e8480348 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/PublicConfigsQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/PublicConfigsQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record PublicConfigsQuery : Query> { diff --git a/src/Services/Masa.Dcc.Service/Application/App/Queries/RefreshConfigObjectToRedisQuery.cs b/Masa.Dcc.Infrastructure.Domain/App/Queries/RefreshConfigObjectToRedisQuery.cs similarity index 83% rename from src/Services/Masa.Dcc.Service/Application/App/Queries/RefreshConfigObjectToRedisQuery.cs rename to Masa.Dcc.Infrastructure.Domain/App/Queries/RefreshConfigObjectToRedisQuery.cs index 012c5b64..f2e250e3 100644 --- a/src/Services/Masa.Dcc.Service/Application/App/Queries/RefreshConfigObjectToRedisQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/App/Queries/RefreshConfigObjectToRedisQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.App.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record RefreshConfigObjectToRedisQuery : Query { diff --git a/Masa.Dcc.Infrastructure.Domain/App/QueryHandler.cs b/Masa.Dcc.Infrastructure.Domain/App/QueryHandler.cs new file mode 100644 index 00000000..5759e9f7 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/App/QueryHandler.cs @@ -0,0 +1,290 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Service.Admin.Application.App; + +internal class QueryHandler +{ + private readonly IPublicConfigRepository _publicConfigRepository; + private readonly IPublicConfigObjectRepository _publicConfigObjectRepository; + private readonly IConfigObjectRepository _configObjectRepository; + private readonly ILabelRepository _labelRepository; + private readonly IAppPinRepository _appPinRepository; + private readonly IBizConfigRepository _bizConfigRepository; + private readonly IBizConfigObjectRepository _bizConfigObjectRepository; + private readonly IAppConfigObjectRepository _appConfigObjectRepository; + private readonly IMasaStackConfig _masaStackConfig; + private readonly ConfigObjectDomainService _configObjectDomainService; + private readonly IConfigurationApiClient _configurationApiClient; + + public QueryHandler( + IPublicConfigRepository publicConfigRepository, + IPublicConfigObjectRepository publicConfigObjectRepository, + IConfigObjectRepository configObjectRepository, + ILabelRepository labelRepository, + IAppPinRepository appPinRepository, + IBizConfigRepository bizConfigRepository, + IBizConfigObjectRepository bizConfigObjectRepository, + IAppConfigObjectRepository appConfigObjectRepository, + IMasaStackConfig masaStackConfig, + ConfigObjectDomainService configObjectDomainService, + IConfigurationApiClient configurationApiClient) + { + _publicConfigRepository = publicConfigRepository; + _publicConfigObjectRepository = publicConfigObjectRepository; + _configObjectRepository = configObjectRepository; + _labelRepository = labelRepository; + _appPinRepository = appPinRepository; + _bizConfigRepository = bizConfigRepository; + _bizConfigObjectRepository = bizConfigObjectRepository; + _appConfigObjectRepository = appConfigObjectRepository; + _masaStackConfig = masaStackConfig; + _configObjectDomainService = configObjectDomainService; + _configurationApiClient = configurationApiClient; + } + + [EventHandler] + public async Task GetPublicConfigsAsync(PublicConfigsQuery query) + { + IEnumerable result = await _publicConfigRepository.GetListAsync(); + query.Result = result.Select(p => new PublicConfigDto + { + Id = p.Id, + Name = p.Name, + Identity = p.Identity, + Description = p.Description, + CreationTime = p.CreationTime, + Creator = p.Creator, + Modifier = p.Modifier, + ModificationTime = p.ModificationTime + }).ToList(); + } + + [EventHandler] + public async Task GetLatestReleaseConfigByProjectAsync( + ProjectLatestReleaseQuery query) + { + var dbResult = + await _bizConfigObjectRepository.GetProjectLatestReleaseConfigAsync(query.Projects, + query.EnvClusterId); + + + TypeAdapterConfig<(ConfigObjectRelease Release, int ProjectId), LatestReleaseConfigModel>.NewConfig() + .Map(dest => dest.ConfigObjectId, src => src.Release.ConfigObjectId) + .Map(dest => dest.ProjectId, src => src.ProjectId) + .Map(dest => dest.LastPublishTime, src => src.Release.CreationTime) + .Map(dest => dest.LastPublisherId, src => src.Release.Creator) + .IgnoreNullValues(true) + .IgnoreNonMapped(true); + + query.Result = dbResult + .Adapt, List>(); + + } + + [EventHandler] + public async Task GetLatestReleaseConfigByAppAsync( + AppLatestReleaseQuery query) + { + var dbResult = + await _appConfigObjectRepository.GetAppLatestReleaseConfigAsync(query.AppIds, + query.EnvClusterId); + + TypeAdapterConfig<(int AppId, ConfigObjectRelease Release), LatestReleaseConfigModel>.NewConfig() + .Map(dest => dest.ConfigObjectId, src => src.Release.ConfigObjectId) + .Map(dest => dest.AppId, src => src.AppId) + .Map(dest => dest.LastPublishTime, src => src.Release.CreationTime) + .Map(dest => dest.LastPublisherId, src => src.Release.Creator) + .IgnoreNullValues(true) + .IgnoreNonMapped(true); + + query.Result = + dbResult.Adapt, List>(); + } + + [EventHandler] + public async Task GetBizConfigsAsync(BizConfigsQuery query) + { + var result = await _bizConfigRepository.FindAsync(biz => biz.Identity == query.Identity); + + if (result != null) + { + query.Result = result.Adapt(); + } + } + + [EventHandler] + public async Task GetConfigObjectsAsync(ConfigObjectsQuery query) + { + List objectConfigObjects = new(); + var labels = await _labelRepository.GetListAsync(); + if (query.Type == ConfigObjectType.Public) + { + var data = await _publicConfigObjectRepository.GetListByEnvClusterIdAsync(query.EnvClusterId, query.ObjectId, query.GetLatestRelease); + TypeAdapterConfig.NewConfig() + .Map(dest => dest, src => src.ConfigObject) + .Map(dest => dest.Id, src => src.ConfigObjectId) + .Map(dest => dest.EnvironmentClusterId, src => src.EnvironmentClusterId) + .AfterMapping((src, dest) => + { + SetDest(dest, src.ConfigObject); + }); + objectConfigObjects = data.Adapt, List>(); + } + else if (query.Type == ConfigObjectType.Biz) + { + var data = await _bizConfigObjectRepository.GetListByEnvClusterIdAsync(query.EnvClusterId, query.ObjectId, query.GetLatestRelease); + TypeAdapterConfig.NewConfig() + .Map(dest => dest, src => src.ConfigObject) + .Map(dest => dest.Id, src => src.ConfigObjectId) + .Map(dest => dest.EnvironmentClusterId, src => src.EnvironmentClusterId) + .AfterMapping((src, dest) => + { + SetDest(dest, src.ConfigObject); + }); + objectConfigObjects = data.Adapt, List>(); + } + else if (query.Type == ConfigObjectType.App) + { + var data = await _appConfigObjectRepository.GetListByEnvClusterIdAsync(query.EnvClusterId, query.ObjectId, query.GetLatestRelease); + TypeAdapterConfig.NewConfig() + .Map(dest => dest, src => src.ConfigObject) + .Map(dest => dest.Id, src => src.ConfigObjectId) + .Map(dest => dest.EnvironmentClusterId, src => src.EnvironmentClusterId) + .AfterMapping((src, dest) => + { + SetDest(dest, src.ConfigObject); + }); + objectConfigObjects = data.Adapt, List>(); + } + + void SetDest(ConfigObjectDto dto, ConfigObject configObject) + { + if (query.GetLatestRelease) + { + var release = configObject.ConfigObjectRelease?.MaxBy(x => x.CreationTime); + if (release != null) + { + dto.LatestRelease = new() + { + LastPublishTime = release.CreationTime, + LastPublisherId = release.Creator, + ConfigObjectId = release.ConfigObjectId, + }; + } + } + } + + if (!string.IsNullOrWhiteSpace(query.ConfigObjectName)) + { + objectConfigObjects = objectConfigObjects + .Where(publicConfigObject => publicConfigObject.Name.Contains(query.ConfigObjectName)) + .ToList(); + } + + query.Result = objectConfigObjects.Select(configObject => new ConfigObjectDto + { + Id = configObject.Id, + Name = configObject.Name, + EnvironmentClusterId = configObject.EnvironmentClusterId, + FormatLabelCode = configObject.FormatLabelCode, + FormatName = labels.FirstOrDefault(label => label.Code == configObject.FormatLabelCode)?.Name ?? "", + Type = configObject.Type, + RelationConfigObjectId = configObject.RelationConfigObjectId, + FromRelation = configObject.FromRelation, + Encryption = configObject.Encryption, + Content = configObject.Encryption ? DecryptContent(configObject.Content) : configObject.Content, + TempContent = configObject.Encryption ? DecryptContent(configObject.TempContent) : configObject.TempContent, + CreationTime = configObject.CreationTime, + Creator = configObject.Creator, + ModificationTime = configObject.ModificationTime, + Modifier = configObject.Modifier, + LatestRelease = configObject.LatestRelease + }).ToList(); + } + + private string DecryptContent(string content) + { + if (!string.IsNullOrEmpty(content) && content != "{}" && content != "[]") + { + var secret = _masaStackConfig.DccSecret; + string encryptContent = AesUtils.Decrypt(content, secret, FillType.Left); + + return encryptContent; + } + else + { + return content; + } + } + + [EventHandler] + public async Task GetConfigObjectsByIdsAsync(ConfigObjectListQuery query) + { + var result = await _configObjectRepository.GetListAsync(c => query.Ids.Contains(c.Id)); + + TypeAdapterConfig.NewConfig() + .Map(dest => dest.Content, src => src.Encryption ? DecryptContent(src.Content) : src.Content) + .Map(dest => dest.TempContent, src => src.Encryption ? DecryptContent(src.TempContent) : src.TempContent); + + query.Result = result.ToList().Adapt, List>(); + } + + [EventHandler] + public async Task GetConfigObjectReleaseHistoryAsync(ConfigObjectReleaseQuery query) + { + var configObjectReleases = await _configObjectRepository.GetConfigObjectWithReleaseHistoriesAsync(query.ConfigObjectId); + + TypeAdapterConfig.NewConfig() + .Map(dest => dest.ConfigObjectReleases, src => src.ConfigObjectRelease) + .Map(dest => dest.Content, src => src.Encryption ? DecryptContent(configObjectReleases.Content) : src.Content) + .Map(dest => dest.TempContent, src => src.Encryption ? DecryptContent(configObjectReleases.TempContent) : src.TempContent); + + var result = configObjectReleases?.Adapt(); + result?.ConfigObjectReleases.ForEach(config => + { + var content = result.Encryption ? DecryptContent(config.Content) : config.Content; + config.Content = content; + }); + + query.Result = result ?? new(); + } + + [EventHandler] + public async Task GetAppPinAsync(AppPinQuery query) + { + var appPins = await _appPinRepository.GetListAsync(query.AppIds); + + query.Result = appPins.Adapt>(); + } + + [EventHandler] + public async Task GetByConfigObjectIdAsync(PublicConfigObjectQuery query) + { + var configObject = await _publicConfigObjectRepository.GetByConfigObjectIdAsync(query.ConfigObjectId); + + query.Result = configObject.Adapt(); + } + + [EventHandler] + public async Task RefreshConfigObjectToRedisAsync(RefreshConfigObjectToRedisQuery query) + { + query.Result = await _configObjectDomainService.RefreshConfigObjectToRedisAsync(); + } + + [EventHandler] + public async Task GetConfigObjectsAsync(ConfigObjectsByDynamicQuery query) + { + query.Result = await _configObjectDomainService.GetConfigObjectsAsync(query.environment, query.cluster, query.appId, query.configObjects); + } + + [EventHandler] + public async Task GetPublicConfigAsync(PublicConfigQuery query) + { + query.Result = await _configurationApiClient.GetAsync>( + query.Environment, + query.Cluster, + "public-$Config", + query.ConfigObject); + } +} diff --git a/Masa.Dcc.Infrastructure.Domain/Label/CommandHandler.cs b/Masa.Dcc.Infrastructure.Domain/Label/CommandHandler.cs new file mode 100644 index 00000000..dcc93814 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/Label/CommandHandler.cs @@ -0,0 +1,34 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Service.Admin.Application.Label; + +internal class CommandHandler +{ + private readonly ILabelRepository _labelRepository; + private readonly LabelDomainService _labelDomainService; + + public CommandHandler(ILabelRepository labelRepository, LabelDomainService labelDomainService) + { + _labelRepository = labelRepository; + _labelDomainService = labelDomainService; + } + + [EventHandler] + public async Task AddLabelAsync(AddLabelCommand command) + { + await _labelDomainService.AddLabelAsync(command.LabelDto); + } + + [EventHandler] + public async Task UpdateLabelAsync(UpdateLabelCommand command) + { + await _labelDomainService.UpdateLabelAsync(command.LabelDto); + } + + [EventHandler] + public async Task RemoveLabelAsync(RemoveLabelCommand command) + { + await _labelDomainService.RemoveLaeblAsync(command.TypeCode); + } +} diff --git a/src/Services/Masa.Dcc.Service/Application/Label/Commands/AddLabelCommand.cs b/Masa.Dcc.Infrastructure.Domain/Label/Commands/AddLabelCommand.cs similarity index 79% rename from src/Services/Masa.Dcc.Service/Application/Label/Commands/AddLabelCommand.cs rename to Masa.Dcc.Infrastructure.Domain/Label/Commands/AddLabelCommand.cs index 75536252..eb36aa3f 100644 --- a/src/Services/Masa.Dcc.Service/Application/Label/Commands/AddLabelCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/Label/Commands/AddLabelCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.Label.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record AddLabelCommand(UpdateLabelDto LabelDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/Label/Commands/RemoveLabelCommand.cs b/Masa.Dcc.Infrastructure.Domain/Label/Commands/RemoveLabelCommand.cs similarity index 79% rename from src/Services/Masa.Dcc.Service/Application/Label/Commands/RemoveLabelCommand.cs rename to Masa.Dcc.Infrastructure.Domain/Label/Commands/RemoveLabelCommand.cs index 6e753a96..61df0c94 100644 --- a/src/Services/Masa.Dcc.Service/Application/Label/Commands/RemoveLabelCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/Label/Commands/RemoveLabelCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.Label.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record RemoveLabelCommand(string TypeCode) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/Label/Commands/UpdateLabelCommand.cs b/Masa.Dcc.Infrastructure.Domain/Label/Commands/UpdateLabelCommand.cs similarity index 80% rename from src/Services/Masa.Dcc.Service/Application/Label/Commands/UpdateLabelCommand.cs rename to Masa.Dcc.Infrastructure.Domain/Label/Commands/UpdateLabelCommand.cs index e23fa05f..f9d5e5ac 100644 --- a/src/Services/Masa.Dcc.Service/Application/Label/Commands/UpdateLabelCommand.cs +++ b/Masa.Dcc.Infrastructure.Domain/Label/Commands/UpdateLabelCommand.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.Label.Commands +namespace Masa.Dcc.Infrastructure.Domain.Commands { public record UpdateLabelCommand(UpdateLabelDto LabelDto) : Command { diff --git a/src/Services/Masa.Dcc.Service/Application/Label/Queries/LabelsQuery.cs b/Masa.Dcc.Infrastructure.Domain/Label/Queries/LabelsQuery.cs similarity index 84% rename from src/Services/Masa.Dcc.Service/Application/Label/Queries/LabelsQuery.cs rename to Masa.Dcc.Infrastructure.Domain/Label/Queries/LabelsQuery.cs index 439ecc5a..91595e4d 100644 --- a/src/Services/Masa.Dcc.Service/Application/Label/Queries/LabelsQuery.cs +++ b/Masa.Dcc.Infrastructure.Domain/Label/Queries/LabelsQuery.cs @@ -1,7 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the Apache License. See LICENSE.txt in the project root for license information. -namespace Masa.Dcc.Service.Admin.Application.Label.Queries +namespace Masa.Dcc.Infrastructure.Domain.Queries { public record LabelsQuery(string TypeCode = "") : Query> { diff --git a/Masa.Dcc.Infrastructure.Domain/Label/QueryHandler.cs b/Masa.Dcc.Infrastructure.Domain/Label/QueryHandler.cs new file mode 100644 index 00000000..4d8c65d0 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/Label/QueryHandler.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Service.Admin.Application.Label; + +internal class QueryHandler +{ + private readonly ILabelRepository _labelRepository; + + public QueryHandler(ILabelRepository labelRepository) + { + _labelRepository = labelRepository; + } + + [EventHandler] + public async Task GetLabelsAsync(LabelsQuery labelsQuery) + { + IEnumerable labels; + + if (string.IsNullOrEmpty(labelsQuery.TypeCode)) + labels = await _labelRepository.GetListAsync(); + else + labels = await _labelRepository.GetListAsync(label => label.TypeCode == labelsQuery.TypeCode); + + labelsQuery.Result = labels.Adapt>(); + } +} diff --git a/Masa.Dcc.Infrastructure.Domain/Masa.Dcc.Infrastructure.Domain.csproj b/Masa.Dcc.Infrastructure.Domain/Masa.Dcc.Infrastructure.Domain.csproj new file mode 100644 index 00000000..b6fb78da --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/Masa.Dcc.Infrastructure.Domain.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/Masa.Dcc.Infrastructure.Domain/Services/ConfigObjectDomainService.cs b/Masa.Dcc.Infrastructure.Domain/Services/ConfigObjectDomainService.cs new file mode 100644 index 00000000..859a8233 --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/Services/ConfigObjectDomainService.cs @@ -0,0 +1,677 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Services; + +public class ConfigObjectDomainService : DomainService +{ + private readonly DccDbContext _context; + private readonly IConfigObjectReleaseRepository _configObjectReleaseRepository; + private readonly IConfigObjectRepository _configObjectRepository; + private readonly IAppConfigObjectRepository _appConfigObjectRepository; + private readonly IBizConfigObjectRepository _bizConfigObjectRepository; + private readonly IBizConfigRepository _bizConfigRepository; + private readonly IPublicConfigObjectRepository _publicConfigObjectRepository; + private readonly IPublicConfigRepository _publicConfigRepository; + private readonly IMultilevelCacheClient _memoryCacheClient; + private readonly IPmClient _pmClient; + private readonly IMasaStackConfig _masaStackConfig; + private readonly IUnitOfWork _unitOfWork; + private readonly JsonSerializerOptions _jsonSerializerOptions = new() + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + WriteIndented = true + }; + + public ConfigObjectDomainService( + IDomainEventBus eventBus, + DccDbContext context, + IConfigObjectReleaseRepository configObjectReleaseRepository, + IConfigObjectRepository configObjectRepository, + IAppConfigObjectRepository appConfigObjectRepository, + IBizConfigObjectRepository bizConfigObjectRepository, + IBizConfigRepository bizConfigRepository, + IPublicConfigObjectRepository publicConfigObjectRepository, + IPublicConfigRepository publicConfigRepository, + IMultilevelCacheClient memoryCacheClient, + IPmClient pmClient, + IMasaStackConfig masaStackConfig, + IUnitOfWork unitOfWork) : base(eventBus) + { + _context = context; + _configObjectReleaseRepository = configObjectReleaseRepository; + _configObjectRepository = configObjectRepository; + _appConfigObjectRepository = appConfigObjectRepository; + _bizConfigObjectRepository = bizConfigObjectRepository; + _bizConfigRepository = bizConfigRepository; + _publicConfigObjectRepository = publicConfigObjectRepository; + _publicConfigRepository = publicConfigRepository; + _memoryCacheClient = memoryCacheClient; + _pmClient = pmClient; + _masaStackConfig = masaStackConfig; + _unitOfWork = unitOfWork; + } + + public async Task AddConfigObjectAsync(List configObjectDtos) + { + List configObjects = new(); + foreach (var configObjectDto in configObjectDtos) + { + var configObject = new ConfigObject( + configObjectDto.Name, + configObjectDto.FormatLabelCode, + configObjectDto.Type, + configObjectDto.Content, + configObjectDto.TempContent, + configObjectDto.RelationConfigObjectId, + configObjectDto.FromRelation, + configObjectDto.Encryption); + + configObjects.Add(configObject); + + if (configObjectDto.Type == ConfigObjectType.Public) + { + configObject.SetPublicConfigObject(configObjectDto.ObjectId, configObjectDto.EnvironmentClusterId); + } + else if (configObjectDto.Type == ConfigObjectType.App) + { + configObject.SetAppConfigObject(configObjectDto.ObjectId, configObjectDto.EnvironmentClusterId); + } + else if (configObjectDto.Type == ConfigObjectType.Biz) + { + configObject.SetBizConfigObject(configObjectDto.ObjectId, configObjectDto.EnvironmentClusterId); + } + } + + await _configObjectRepository.AddRangeAsync(configObjects); + } + + public async Task RemoveConfigObjectAsync(RemoveConfigObjectDto dto) + { + var configObjectEntity = await _configObjectRepository.FindAsync(p => p.Id == dto.ConfigObjectId) + ?? throw new UserFriendlyException("Config object does not exist"); + + await _configObjectRepository.RemoveAsync(configObjectEntity); + + var key = $"{dto.EnvironmentName}-{dto.ClusterName}-{dto.AppId}-{configObjectEntity.Name}"; + await _memoryCacheClient.RemoveAsync(key.ToLower()); + } + + public async Task UpdateConfigObjectContentAsync(UpdateConfigObjectContentDto dto) + { + var configObject = await _configObjectRepository.FindAsync(configObject => configObject.Id == dto.ConfigObjectId) + ?? throw new UserFriendlyException("Config object does not exist"); + + if (dto.FormatLabelCode.Trim().ToLower() != "properties") + { + string content = dto.Content; + if (configObject.Encryption) + { + content = EncryptContent(dto.Content); + } + + configObject.UpdateContent(content); + configObject.UnRelation(); + } + else + { + string content = configObject.Content; + if (configObject.Encryption && configObject.Content != "[]") + { + content = DecryptContent(configObject.Content); + } + + var propertyEntities = JsonSerializer.Deserialize>(content) ?? new(); + if (dto.AddConfigObjectPropertyContent.Any()) + { + propertyEntities.AddRange(dto.AddConfigObjectPropertyContent); + } + if (dto.DeleteConfigObjectPropertyContent.Any()) + { + propertyEntities.RemoveAll(prop => dto.DeleteConfigObjectPropertyContent.Select(prop => prop.Key).Contains(prop.Key)); + } + if (dto.EditConfigObjectPropertyContent.Any()) + { + propertyEntities.RemoveAll(prop => dto.EditConfigObjectPropertyContent.Select(prop => prop.Key).Contains(prop.Key)); + propertyEntities.AddRange(dto.EditConfigObjectPropertyContent); + } + + content = JsonSerializer.Serialize(propertyEntities, _jsonSerializerOptions); + if (configObject.Encryption) + { + content = EncryptContent(content); + } + configObject.UpdateContent(content); + } + + await _configObjectRepository.UpdateAsync(configObject); + } + + private string EncryptContent(string content) + { + var secret = _masaStackConfig.DccSecret; + + var encryptContent = AesUtils.Encrypt(content, secret, FillType.Left); + return encryptContent; + } + + private string DecryptContent(string content) + { + var secret = _masaStackConfig.DccSecret; + + var encryptContent = AesUtils.Decrypt(content, secret, FillType.Left); + return encryptContent; + } + + public async Task CloneConfigObjectAsync(CloneConfigObjectDto dto) + { + //add + await CheckConfigObjectDuplication(dto.ConfigObjects, dto.ToObjectId); + await CloneConfigObjectsAsync(dto.ConfigObjects, dto.ToObjectId); + + //update + var envClusterIds = dto.CoverConfigObjects.Select(c => c.EnvironmentClusterId); + var configNames = dto.CoverConfigObjects.Select(c => c.Name).Distinct(); + + IEnumerable needEditConfig = new List(); + if (dto.ConfigObjectType == ConfigObjectType.App) + { + var appConfigObjects = await _appConfigObjectRepository.GetListAsync( + app => app.AppId == dto.ToObjectId && envClusterIds.Contains(app.EnvironmentClusterId)); + needEditConfig = await _configObjectRepository.GetListAsync(c => appConfigObjects.Select(app => app.ConfigObjectId).Contains(c.Id) && configNames.Contains(c.Name)); + } + else if (dto.ConfigObjectType == ConfigObjectType.Biz) + { + var bizConfigObjects = await _bizConfigObjectRepository.GetListAsync( + biz => biz.BizConfigId == dto.ToObjectId && envClusterIds.Contains(biz.EnvironmentClusterId)); + needEditConfig = await _configObjectRepository.GetListAsync(c => bizConfigObjects.Select(biz => biz.ConfigObjectId).Contains(c.Id) && configNames.Contains(c.Name)); + } + else if (dto.ConfigObjectType == ConfigObjectType.Public) + { + var publicConfigObjects = await _publicConfigObjectRepository.GetListAsync( + publicConfig => publicConfig.PublicConfigId == dto.ToObjectId && envClusterIds.Contains(publicConfig.EnvironmentClusterId)); + var s = await _configObjectRepository.GetListAsync(c => publicConfigObjects.Select(publicConfig => publicConfig.ConfigObjectId).Contains(c.Id)); + var ss = publicConfigObjects.Select(publicConfig => publicConfig.ConfigObjectId); + needEditConfig = await _configObjectRepository.GetListAsync(c => ss.Contains(c.Id) && configNames.Contains(c.Name)); + } + + foreach (var editConfig in needEditConfig) + { + dto.CoverConfigObjects.ForEach(configObject => + { + if (editConfig.Type == configObject.Type && editConfig.Name.Equals(configObject.Name)) + { + string tempontent = editConfig.FormatLabelCode.ToLower() switch + { + "json" => "{}", + "properties" => "[]", + _ => "", + }; + editConfig.AddContent(configObject.Content, tempontent); + } + }); + } + await _configObjectRepository.UpdateRangeAsync(needEditConfig); + } + + private async Task CloneConfigObjectsAsync(List configObjects, int appId) + { + List cloneConfigObjects = new(); + foreach (var configObjectDto in configObjects) + { + var configObject = new ConfigObject( + configObjectDto.Name, + configObjectDto.FormatLabelCode, + configObjectDto.Type, + configObjectDto.Content, + configObjectDto.TempContent, + encryption: configObjectDto.Encryption); + cloneConfigObjects.Add(configObject); + + if (configObjectDto.Type == ConfigObjectType.Public) + { + configObject.SetPublicConfigObject(appId, configObjectDto.EnvironmentClusterId); + } + else if (configObjectDto.Type == ConfigObjectType.App) + { + configObject.SetAppConfigObject(appId, configObjectDto.EnvironmentClusterId); + } + else if (configObjectDto.Type == ConfigObjectType.Biz) + { + configObject.SetBizConfigObject(appId, configObjectDto.EnvironmentClusterId); + } + + if (configObject.Encryption) + { + var encryptConten = EncryptContent(configObject.Content); + configObject.UpdateContent(encryptConten); + } + } + await _configObjectRepository.AddRangeAsync(cloneConfigObjects); + } + + private async Task CheckConfigObjectDuplication(List configObjects, int appId) + { + if (configObjects?.Count > 0) + { + var configType = configObjects.First().Type; + var configObjectNames = configObjects.Select(e => e.Name); + switch (configType) + { + case ConfigObjectType.Public: + var allPublicConfigs = await _publicConfigObjectRepository.GetListByPublicConfigIdAsync(appId); + foreach (var item in configObjects) + { + if (allPublicConfigs.Any(e => e.EnvironmentClusterId == item.EnvironmentClusterId && e.ConfigObject.Name == item.Name)) + { + throw new UserFriendlyException($"Configuration Name '{item.Name}' already exist in the environment cluster '{item.EnvironmentClusterId}'."); + } + } + break; + case ConfigObjectType.Biz: + var bizConfigObjects = await _bizConfigObjectRepository.GetListByBizConfigIdAsync(appId); + foreach (var item in configObjects) + { + if (bizConfigObjects.Any(e => e.EnvironmentClusterId == item.EnvironmentClusterId && e.ConfigObject.Name == item.Name)) + { + throw new UserFriendlyException($"Configuration Name '{item.Name}' already exist in the environment cluster '{item.EnvironmentClusterId}'."); + } + } + break; + case ConfigObjectType.App: + var allAppConfigObjects = await _appConfigObjectRepository.GetListByAppIdAsync(appId); + foreach (var item in configObjects) + { + if (allAppConfigObjects.Any(e => e.EnvironmentClusterId == item.EnvironmentClusterId && e.ConfigObject.Name == item.Name)) + { + throw new UserFriendlyException($"Configuration Name '{item.Name}' already exist for environment cluster's '{item.EnvironmentClusterId}'. "); + } + } + break; + } + } + } + + public async Task AddConfigObjectReleaseAsync(AddConfigObjectReleaseDto dto) + { + var configObject = (await _configObjectRepository.FindAsync( + configObject => configObject.Id == dto.ConfigObjectId)) ?? throw new Exception("Config object does not exist"); + + configObject.AddContent(configObject.Content, configObject.Content); + await _configObjectRepository.UpdateAsync(configObject); + + var configObjectRelease = new ConfigObjectRelease( + dto.ConfigObjectId, + dto.Name, + dto.Comment, + configObject.Content); + await _configObjectReleaseRepository.AddAsync(configObjectRelease); + + var relationConfigObjects = await _configObjectRepository.GetRelationConfigObjectWithReleaseHistoriesAsync(configObject.Id); + if (relationConfigObjects.Any()) + { + var allEnvClusters = await _pmClient.ClusterService.GetEnvironmentClustersAsync(); + var appConfigObjects = await _appConfigObjectRepository.GetListAsync(app => relationConfigObjects.Select(c => c.Id).Contains(app.ConfigObjectId)); + var apps = await _pmClient.AppService.GetListAsync(); + + foreach (var item in appConfigObjects) + { + var envCluster = allEnvClusters.FirstOrDefault(c => c.Id == item.EnvironmentClusterId) ?? new(); + var app = apps.FirstOrDefault(a => a.Id == item.AppId) ?? new(); + var relationConfigObject = relationConfigObjects.First(c => c.Id == item.ConfigObjectId); + var key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{app.Identity}-{relationConfigObject.Name}"; + + if (relationConfigObject.FormatLabelCode.ToLower() == "properties") + { + var appRelease = relationConfigObject.ConfigObjectRelease.OrderByDescending(c => c.Id).FirstOrDefault(); + if (appRelease == null) + { + await _memoryCacheClient.SetAsync(key.ToLower(), new PublishReleaseModel + { + Content = dto.Content, + FormatLabelCode = configObject.FormatLabelCode, + Encryption = configObject.Encryption + }); + } + else + { + //compare + var publicContents = JsonSerializer.Deserialize>(dto.Content) ?? new(); + var appContents = JsonSerializer.Deserialize>(appRelease.Content) ?? new(); + + var exceptContent = publicContents.ExceptBy(appContents.Select(c => c.Key), content => content.Key).ToList(); + var content = appContents.Union(exceptContent).ToList(); + + var releaseContent = new PublishReleaseModel + { + Content = JsonSerializer.Serialize(content, _jsonSerializerOptions), + FormatLabelCode = configObject.FormatLabelCode, + Encryption = configObject.Encryption + }; + await _memoryCacheClient.SetAsync(key.ToLower(), releaseContent); + } + } + else + { + var releaseContent = new PublishReleaseModel + { + Content = dto.Content, + FormatLabelCode = configObject.FormatLabelCode, + Encryption = configObject.Encryption + }; + await _memoryCacheClient.SetAsync(key.ToLower(), releaseContent); + } + } + } + else + { + //add redis cache + var key = $"{dto.EnvironmentName}-{dto.ClusterName}-{dto.Identity}-{configObject.Name}"; + if (configObject.Encryption) + { + dto.Content = EncryptContent(dto.Content); + } + var releaseContent = new PublishReleaseModel + { + Content = dto.Content, + FormatLabelCode = configObject.FormatLabelCode, + Encryption = configObject.Encryption + }; + await _memoryCacheClient.SetAsync(key.ToLower(), releaseContent); + } + } + + public async Task RollbackConfigObjectReleaseAsync(RollbackConfigObjectReleaseDto rollbackDto) + { + var latestConfigObjectRelease = await _context.Set() + .Where(cor => cor.ConfigObjectId == rollbackDto.ConfigObjectId) + .OrderByDescending(cor => cor.Id) + .FirstOrDefaultAsync(); + + var rollbackToEntity = await _configObjectReleaseRepository.FindAsync( + ocr => ocr.Id == rollbackDto.RollbackToReleaseId); + + if (latestConfigObjectRelease == null || rollbackToEntity == null) + { + throw new Exception("要回滚的版本不存在"); + } + + if (rollbackDto.RollbackToReleaseId == latestConfigObjectRelease.FromReleaseId) + { + throw new UserFriendlyException("该版本已作废"); + } + if (rollbackToEntity.Version == latestConfigObjectRelease.Version) + { + throw new UserFriendlyException("两个版本相同"); + } + + //rollback + //add + await _configObjectReleaseRepository.AddAsync(new ConfigObjectRelease( + rollbackToEntity.ConfigObjectId, + rollbackToEntity.Name, + $"由 {latestConfigObjectRelease.Name} 回滚至 {rollbackToEntity.Name}", + rollbackToEntity.Content, + rollbackToEntity.Version, + latestConfigObjectRelease.Id + )); + + //Invalid rollback entity + latestConfigObjectRelease.Invalid(); + await _configObjectReleaseRepository.UpdateAsync(latestConfigObjectRelease); + + //Update ConfigObject entity + var configObject = (await _configObjectRepository.FindAsync(config => config.Id == rollbackDto.ConfigObjectId))!; + configObject.AddContent(configObject.Content, rollbackToEntity.Content); + await _configObjectRepository.UpdateAsync(configObject); + + string key = string.Empty; + var envClusters = await _pmClient.ClusterService.GetEnvironmentClustersAsync(); + if (configObject.Type == ConfigObjectType.Public) + { + var publicConfigObject = await _publicConfigObjectRepository.GetByConfigObjectIdAsync(configObject.Id); + var publicConfig = await _publicConfigRepository.FindAsync(c => c.Id == publicConfigObject.PublicConfigId) ?? throw new MasaException(); + var envCluster = envClusters.First(e => e.Id == publicConfigObject.EnvironmentClusterId); + key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{publicConfig.Identity}-{configObject.Name}"; + } + else if (configObject.Type == ConfigObjectType.Biz) + { + var bizConfigObject = await _bizConfigObjectRepository.GetByConfigObjectIdAsync(configObject.Id); + var bizConfig = await _bizConfigRepository.FindAsync(c => c.Id == bizConfigObject.BizConfigId) ?? throw new MasaException(); + var envCluster = envClusters.First(e => e.Id == bizConfigObject.EnvironmentClusterId); + key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{bizConfig.Identity}-{configObject.Name}"; + } + else if (configObject.Type == ConfigObjectType.App) + { + var appConfigObject = await _appConfigObjectRepository.GetbyConfigObjectIdAsync(configObject.Id); + var app = await _pmClient.AppService.GetAsync(appConfigObject.AppId) ?? throw new MasaException(); ; + var envCluster = envClusters.First(e => e.Id == appConfigObject.EnvironmentClusterId); + key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{app.Identity}-{configObject.Name}"; + } + + var releaseContent = new PublishReleaseModel + { + Content = configObject.Encryption ? EncryptContent(rollbackToEntity.Content) : rollbackToEntity.Content, + FormatLabelCode = configObject.FormatLabelCode, + Encryption = configObject.Encryption + }; + await _memoryCacheClient.SetAsync(key.ToLower(), releaseContent); + } + + public async Task UpdateConfigObjectAsync( + string environmentName, + string clusterName, + string appId, + string configObjectName, + string value) + { + var configObjects = await _configObjectRepository.GetListAsync(config => config.Name == configObjectName); + if (!configObjects.Any()) + { + throw new UserFriendlyException("ConfigObject does not exist"); + } + + var environmentClusters = await _pmClient.ClusterService.GetEnvironmentClustersAsync(); + var environmentCluster = environmentClusters.FirstOrDefault(ec => ec.EnvironmentName.ToLower() == environmentName.ToLower() && ec.ClusterName.ToLower() == clusterName.ToLower()) + ?? throw new UserFriendlyException("Environment cluster does not exist"); + + ConfigObject? configObject = null; + + var publicConfig = await _publicConfigRepository.FindAsync(p => p.Identity.ToLower() == appId.ToLower()); + if (publicConfig == null) + { + var appDetail = await _pmClient.AppService.GetByIdentityAsync(appId); + var appConfigObjects = await _appConfigObjectRepository.GetListByEnvClusterIdAsync(environmentCluster.Id, appDetail.Id); + configObject = configObjects.FirstOrDefault(c => appConfigObjects.Select(ac => ac.ConfigObjectId).Contains(c.Id)) ?? throw new UserFriendlyException("ConfigObject does not exist"); + } + else + { + var publicConfigObjects = await _publicConfigObjectRepository.GetListByEnvClusterIdAsync(environmentCluster.Id, publicConfig.Id); + configObject = configObjects.FirstOrDefault(c => publicConfigObjects.Select(ac => ac.ConfigObjectId).Contains(c.Id)) ?? throw new UserFriendlyException("ConfigObject does not exist"); + } + + if (configObject.Encryption) + { + value = EncryptContent(value); + } + configObject.UpdateContent(value); + await _configObjectRepository.UpdateAsync(configObject); + + var releaseModel = new AddConfigObjectReleaseDto + { + Type = ReleaseType.MainRelease, + ConfigObjectId = configObject.Id, + Name = "通过Sdk发布", + EnvironmentName = environmentName, + ClusterName = clusterName, + Identity = appId, + Content = value + }; + + await AddConfigObjectReleaseAsync(releaseModel); + } + + public async Task InitConfigObjectAsync( + string environmentName, + string clusterName, + string appId, + Dictionary configObjects, + ConfigObjectType configObjectType = ConfigObjectType.App, + bool isEncryption = false) + { + var envs = await _pmClient.EnvironmentService.GetListAsync(); + var env = envs.FirstOrDefault(e => e.Name.ToLower() == environmentName.ToLower()) ?? throw new UserFriendlyException("Environment does not exist"); + var clusters = await _pmClient.ClusterService.GetListByEnvIdAsync(env.Id); + var cluster = clusters.FirstOrDefault(c => c.Name.ToLower() == clusterName.ToLower()) ?? throw new UserFriendlyException("Cluster does not exist"); + foreach (var configObject in configObjects) + { + var configObjectName = configObject.Key; + var key = $"{environmentName}-{clusterName}-{appId}-{configObjectName}".ToLower(); + var redisData = await _memoryCacheClient.GetAsync(key); + if (redisData != null) + { + continue; + } + + string content = configObject.Value; + if (isEncryption) + content = EncryptContent(content); + + var newConfigObject = new ConfigObject( + configObjectName, + "JSON", + configObjectType, + content, + "{}", + encryption: isEncryption); + + var publicConfig = await _publicConfigRepository.FindAsync(publicConfig => publicConfig.Identity == appId); + if (publicConfig != null) + { + newConfigObject.SetConfigObjectType(ConfigObjectType.App); + newConfigObject.SetPublicConfigObject(publicConfig.Id, cluster.EnvironmentClusterId); + } + else + { + var bizConfig = await _bizConfigRepository.FindAsync(bizConfig => bizConfig.Identity == appId); + if (bizConfig != null) + { + newConfigObject.SetConfigObjectType(ConfigObjectType.Biz); + newConfigObject.SetBizConfigObject(bizConfig.Id, cluster.EnvironmentClusterId); + } + else + { + newConfigObject.SetConfigObjectType(ConfigObjectType.App); + var app = await _pmClient.AppService.GetByIdentityAsync(appId); + if (app != null) + { + newConfigObject.SetAppConfigObject(app.Id, cluster.EnvironmentClusterId); + } + else + { + throw new UserFriendlyException("AppId Error"); + } + } + } + await _configObjectRepository.AddAsync(newConfigObject); + await _unitOfWork.SaveChangesAsync(); + + var releaseModel = new AddConfigObjectReleaseDto + { + Type = ReleaseType.MainRelease, + ConfigObjectId = newConfigObject.Id, + Name = "通过Sdk发布", + EnvironmentName = environmentName, + ClusterName = clusterName, + Identity = appId, + Content = configObject.Value + }; + await AddConfigObjectReleaseAsync(releaseModel); + } + } + + public async Task RefreshConfigObjectToRedisAsync() + { + var configObjectInfo = await _configObjectRepository.GetNewestConfigObjectReleaseWithAppInfo(); + var apps = await _pmClient.AppService.GetListAsync(); + var envClusters = await _pmClient.ClusterService.GetEnvironmentClustersAsync(); + var publicConfig = (await _publicConfigRepository.GetListAsync()).FirstOrDefault() + ?? throw new UserFriendlyException("PublicConfig is null"); + + configObjectInfo.ForEach(config => + { + if (config.ConfigObject.Type == ConfigObjectType.App) + { + apps.Where(app => app.Id == config.ObjectId).ToList().ForEach(app => + { + app.EnvironmentClusters.ForEach(async envCluster => + { + if (envCluster.Id == config.EnvironmentClusterId) + { + var key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{app.Identity}-{config.ConfigObject.Name}"; + await _memoryCacheClient.SetAsync(key.ToLower(), new PublishReleaseModel + { + Content = config.ConfigObject.Content, + FormatLabelCode = config.ConfigObject.FormatLabelCode, + Encryption = config.ConfigObject.Encryption + }); + } + }); + }); + } + else if (config.ConfigObject.Type == ConfigObjectType.Public) + { + envClusters.Where(ec => ec.Id == config.EnvironmentClusterId).ToList().ForEach(async envCluster => + { + var key = $"{envCluster.EnvironmentName}-{envCluster.ClusterName}-{publicConfig.Identity}-{config.ConfigObject.Name}"; + await _memoryCacheClient.SetAsync(key.ToLower(), new PublishReleaseModel + { + Content = config.ConfigObject.Content, + FormatLabelCode = config.ConfigObject.FormatLabelCode, + Encryption = config.ConfigObject.Encryption + }); + }); + } + }); + + return "success"; + } + + public async Task> GetConfigObjectsAsync(string environmentName, + string clusterName, string appId, List? configObjects) + { + var resultDic = new Dictionary(); + + var envs = await _pmClient.EnvironmentService.GetListAsync(); + var env = envs.FirstOrDefault(e => e.Name.ToLower() == environmentName.ToLower()) ?? throw new UserFriendlyException("Environment does not exist"); + var clusters = await _pmClient.ClusterService.GetListByEnvIdAsync(env.Id); + var cluster = clusters.FirstOrDefault(c => c.Name.ToLower() == clusterName.ToLower()) ?? throw new UserFriendlyException("Cluster does not exist"); + var apps = await _pmClient.AppService.GetListAsync(); + var app = apps.FirstOrDefault(apps => apps.Identity.ToLower() == appId.ToLower()) ?? throw new UserFriendlyException("AppId does not exist"); + + Expression> configObjectFilter = configObject => + configObject.AppConfigObject.EnvironmentClusterId == cluster.Id && + configObject.AppConfigObject.AppId == app.Id && + ((configObjects == null || configObjects.Count == 0) || configObjects.Contains(configObject.Name)); + var configObjectList = await _configObjectRepository.GetListAsync(configObjectFilter); + if (configObjects == null || configObjects.Count == 0) + { + var configObjectPublicList = await _configObjectRepository.GetListAsync(configObject => configObject.PublicConfigObject.EnvironmentClusterId == cluster.Id); + configObjectList = configObjectList.Union(configObjectPublicList); + } + + foreach (var configObject in configObjectList) + { + var key = $"{configObject.Name}".ToLower();//{environmentName}-{clusterName}-{appId}- + if (resultDic.ContainsKey(key)) continue; + resultDic.Add(key, new PublishReleaseModel() + { + Encryption = configObject.Encryption, + FormatLabelCode = configObject.FormatLabelCode, + Content = configObject.Content, + }); + } + + return resultDic; + } +} diff --git a/Masa.Dcc.Infrastructure.Domain/Services/LabelDomainService.cs b/Masa.Dcc.Infrastructure.Domain/Services/LabelDomainService.cs new file mode 100644 index 00000000..36448dba --- /dev/null +++ b/Masa.Dcc.Infrastructure.Domain/Services/LabelDomainService.cs @@ -0,0 +1,84 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Dcc.Infrastructure.Domain.Services; + +public class LabelDomainService : DomainService +{ + private readonly ILabelRepository _labelRepository; + private readonly IDistributedCacheClient _distributedCacheClient; + private readonly II18n _i18n; + + public LabelDomainService(IDomainEventBus eventBus, + ILabelRepository labelRepository, + IDistributedCacheClient distributedCacheClient, + II18n i18N) : base(eventBus) + { + _labelRepository = labelRepository; + _distributedCacheClient = distributedCacheClient; + _i18n = i18N; + } + + public async Task AddLabelAsync(UpdateLabelDto labelDto) + { + if (!labelDto.LabelValues.Any()) + { + throw new UserFriendlyException("Label values can not be null"); + } + else + { + var label = await _labelRepository.FindAsync(x => x.TypeCode == labelDto.TypeCode); + if (label is not null) + { + throw new UserFriendlyException(_i18n.T("Duplicate label type code")); + } + + List