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