diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 000000000..b475c7f1a --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,32 @@ +name: Lint + +on: + push: + branches: + - 'main' + - 'dev' + pull_request: + types: [ opened, synchronize, reopened ] + +permissions: + checks: write + contents: write + +jobs: + run-linters: + name: Run linters + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + + - name: Set up .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: "9.0.x" + + - name: Run linters + uses: wearerequired/lint-action@v2 + with: + dotnet_format: true \ No newline at end of file diff --git a/AevatarStation.sln b/AevatarStation.sln index 08628045d..8d377801a 100644 --- a/AevatarStation.sln +++ b/AevatarStation.sln @@ -79,6 +79,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VerifyJsonDesIssue", "sampl EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VerifyStreamApp", "samples\VerifyStreamApp\VerifyStreamApp.csproj", "{64F10B47-10FE-4CF9-A498-817A3F0D2CB5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "E2E.Grains", "samples\E2E.Grains\E2E.Grains.csproj", "{A3CB94CF-B96B-4BEE-AF94-32B661BC2345}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -509,6 +511,18 @@ Global {64F10B47-10FE-4CF9-A498-817A3F0D2CB5}.Release|x64.Build.0 = Release|Any CPU {64F10B47-10FE-4CF9-A498-817A3F0D2CB5}.Release|x86.ActiveCfg = Release|Any CPU {64F10B47-10FE-4CF9-A498-817A3F0D2CB5}.Release|x86.Build.0 = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|x64.ActiveCfg = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|x64.Build.0 = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|x86.ActiveCfg = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Debug|x86.Build.0 = Debug|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|Any CPU.Build.0 = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|x64.ActiveCfg = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|x64.Build.0 = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|x86.ActiveCfg = Release|Any CPU + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -549,6 +563,7 @@ Global {9367124E-A85D-4067-98C8-42F672DC95AC} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA} {55E2C369-C501-43DA-A8CA-A6C4D765DD8F} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA} {64F10B47-10FE-4CF9-A498-817A3F0D2CB5} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA} + {A3CB94CF-B96B-4BEE-AF94-32B661BC2345} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/src/Aevatar.Application.Contracts/AISmartDtoExtensions.cs b/src/Aevatar.Application.Contracts/AISmartDtoExtensions.cs index edd0c1663..d30b16b45 100644 --- a/src/Aevatar.Application.Contracts/AISmartDtoExtensions.cs +++ b/src/Aevatar.Application.Contracts/AISmartDtoExtensions.cs @@ -1,6 +1,4 @@ -using Volo.Abp.Identity; -using Volo.Abp.ObjectExtending; -using Volo.Abp.Threading; +using Volo.Abp.Threading; namespace Aevatar; @@ -10,19 +8,6 @@ public static class AevatarDtoExtensions public static void Configure() { - OneTimeRunner.Run(() => - { - /* You can add extension properties to DTOs - * defined in the depended modules. - * - * Example: - * - * ObjectExtensionManager.Instance - * .AddOrUpdateProperty("Title"); - * - * See the documentation for more: - * https://docs.abp.io/en/abp/latest/Object-Extensions - */ - }); + OneTimeRunner.Run(() => { }); } -} +} \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Account/IAccountService.cs b/src/Aevatar.Application.Contracts/Account/IAccountService.cs index 8f8497988..966d492c4 100644 --- a/src/Aevatar.Application.Contracts/Account/IAccountService.cs +++ b/src/Aevatar.Application.Contracts/Account/IAccountService.cs @@ -4,7 +4,7 @@ namespace Aevatar.Account; -public interface IAccountService: IAccountAppService +public interface IAccountService : IAccountAppService { Task SendRegisterCodeAsync(SendRegisterCodeDto input); Task RegisterAsync(AevatarRegisterDto input); diff --git a/src/Aevatar.Application.Contracts/Account/SendRegisterCodeDto.cs b/src/Aevatar.Application.Contracts/Account/SendRegisterCodeDto.cs index 9cae5cffb..2f79874cd 100644 --- a/src/Aevatar.Application.Contracts/Account/SendRegisterCodeDto.cs +++ b/src/Aevatar.Application.Contracts/Account/SendRegisterCodeDto.cs @@ -10,10 +10,9 @@ public class SendRegisterCodeDto [EmailAddress] [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxEmailLength))] public string Email { get; set; } - - [Required] - public string AppName { get; set; } - + + [Required] public string AppName { get; set; } + [Required] [DynamicStringLength(typeof(IdentityUserConsts), nameof(IdentityUserConsts.MaxUserNameLength))] public string UserName { get; set; } diff --git a/src/Aevatar.Application.Contracts/Account/VerifyRegisterCodeDto.cs b/src/Aevatar.Application.Contracts/Account/VerifyRegisterCodeDto.cs index 677acf98a..f493ed1f2 100644 --- a/src/Aevatar.Application.Contracts/Account/VerifyRegisterCodeDto.cs +++ b/src/Aevatar.Application.Contracts/Account/VerifyRegisterCodeDto.cs @@ -8,6 +8,5 @@ public class VerifyRegisterCodeDto [EmailAddress] public string Email { get; set; } - [Required] - public string Code { get; set; } -} \ No newline at end of file + [Required] public string Code { get; set; } +} \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/ApiKeys/CreateAppIdDto.cs b/src/Aevatar.Application.Contracts/ApiKeys/CreateAppIdDto.cs index 3605c1689..ab9cba644 100644 --- a/src/Aevatar.Application.Contracts/ApiKeys/CreateAppIdDto.cs +++ b/src/Aevatar.Application.Contracts/ApiKeys/CreateAppIdDto.cs @@ -6,5 +6,4 @@ public class CreateAppIdDto { public Guid ProjectId { get; set; } public string Name { get; set; } - } \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Organizations/GetOrganizationListDto.cs b/src/Aevatar.Application.Contracts/Organizations/GetOrganizationListDto.cs index 8a0218dc8..6135e6a2e 100644 --- a/src/Aevatar.Application.Contracts/Organizations/GetOrganizationListDto.cs +++ b/src/Aevatar.Application.Contracts/Organizations/GetOrganizationListDto.cs @@ -1,6 +1,3 @@ namespace Aevatar.Organizations; -public class GetOrganizationListDto -{ - -} \ No newline at end of file +public class GetOrganizationListDto; \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Organizations/GetOrganizationMemberListDto.cs b/src/Aevatar.Application.Contracts/Organizations/GetOrganizationMemberListDto.cs index c853bfe9e..ce53deb96 100644 --- a/src/Aevatar.Application.Contracts/Organizations/GetOrganizationMemberListDto.cs +++ b/src/Aevatar.Application.Contracts/Organizations/GetOrganizationMemberListDto.cs @@ -1,6 +1,3 @@ namespace Aevatar.Organizations; -public class GetOrganizationMemberListDto -{ - -} \ No newline at end of file +public class GetOrganizationMemberListDto; \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Permissions/AevatarPermissionDefinitionProvider.cs b/src/Aevatar.Application.Contracts/Permissions/AevatarPermissionDefinitionProvider.cs index eac62010a..24f8dc54d 100644 --- a/src/Aevatar.Application.Contracts/Permissions/AevatarPermissionDefinitionProvider.cs +++ b/src/Aevatar.Application.Contracts/Permissions/AevatarPermissionDefinitionProvider.cs @@ -1,4 +1,3 @@ -using System.Linq; using Aevatar.Localization; using Aevatar.Organizations; using Aevatar.PermissionManagement; @@ -76,37 +75,59 @@ public override void Define(IPermissionDefinitionContext context) } var developerPlatformGroup = context.AddGroup(AevatarPermissions.DeveloperPlatform); - - var organizationsPermission = developerPlatformGroup.AddPermission(AevatarPermissions.Organizations.Default, L("Permission:Organizations")); + + var organizationsPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.Organizations.Default, + L("Permission:Organizations")); organizationsPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; - organizationsPermission.AddChild(AevatarPermissions.Organizations.Edit, L("Permission:Organizations.Edit")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; - - var projectsPermission = developerPlatformGroup.AddPermission(AevatarPermissions.Projects.Default, L("Permission:Projects")); + organizationsPermission.AddChild(AevatarPermissions.Organizations.Edit, L("Permission:Organizations.Edit")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; + + var projectsPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.Projects.Default, L("Permission:Projects")); projectsPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - projectsPermission.AddChild(AevatarPermissions.Projects.Create, L("Permission:Projects.Create")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; - projectsPermission.AddChild(AevatarPermissions.Projects.Edit, L("Permission:Projects.Edit")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - projectsPermission.AddChild(AevatarPermissions.Projects.Delete, L("Permission:Projects.Delete")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; - - var organizationMembersPermission = developerPlatformGroup.AddPermission(AevatarPermissions.Members.Default, L("Permission:Members")); - organizationMembersPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - organizationMembersPermission.AddChild(AevatarPermissions.Members.Manage, L("Permission:Members.Manage")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - - var apiKeysPermission = developerPlatformGroup.AddPermission(AevatarPermissions.ApiKeys.Default, L("Permission:ApiKeys")); + projectsPermission.AddChild(AevatarPermissions.Projects.Create, L("Permission:Projects.Create")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; + projectsPermission.AddChild(AevatarPermissions.Projects.Edit, L("Permission:Projects.Edit")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + projectsPermission.AddChild(AevatarPermissions.Projects.Delete, L("Permission:Projects.Delete")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.Organization; + + var organizationMembersPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.Members.Default, L("Permission:Members")); + organizationMembersPermission.Properties[AevatarPermissions.OrganizationScopeKey] = + PermissionScope.OrganizationAndProject; + organizationMembersPermission.AddChild(AevatarPermissions.Members.Manage, L("Permission:Members.Manage")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + + var apiKeysPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.ApiKeys.Default, L("Permission:ApiKeys")); apiKeysPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Create, L("Permission:ApiKeys.Create")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Edit, L("Permission:ApiKeys.Edit")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Delete, L("Permission:ApiKeys.Delete")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - - var rolesPermission = developerPlatformGroup.AddPermission(AevatarPermissions.Roles.Default, L("Permission:Roles")); + apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Create, L("Permission:ApiKeys.Create")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Edit, L("Permission:ApiKeys.Edit")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + apiKeysPermission.AddChild(AevatarPermissions.ApiKeys.Delete, L("Permission:ApiKeys.Delete")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + + var rolesPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.Roles.Default, L("Permission:Roles")); apiKeysPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - rolesPermission.AddChild(AevatarPermissions.Roles.Create, L("Permission:Roles.Create")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - rolesPermission.AddChild(AevatarPermissions.Roles.Edit, L("Permission:Roles.Edit")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - rolesPermission.AddChild(AevatarPermissions.Roles.Delete, L("Permission:Roles.Delete")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - - var dashboardsPermission = developerPlatformGroup.AddPermission(AevatarPermissions.Dashboard, L("Permission:Dashboards")); - dashboardsPermission.Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - dashboardsPermission.AddChild(AevatarPermissions.LLMSModels.Default, L("Permission:LLMSModels")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; - dashboardsPermission.AddChild(AevatarPermissions.ApiRequests.Default, L("Permission:ApiRequests")).Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + rolesPermission.AddChild(AevatarPermissions.Roles.Create, L("Permission:Roles.Create")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + rolesPermission.AddChild(AevatarPermissions.Roles.Edit, L("Permission:Roles.Edit")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + rolesPermission.AddChild(AevatarPermissions.Roles.Delete, L("Permission:Roles.Delete")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + + var dashboardsPermission = + developerPlatformGroup.AddPermission(AevatarPermissions.Dashboard, L("Permission:Dashboards")); + dashboardsPermission.Properties[AevatarPermissions.OrganizationScopeKey] = + PermissionScope.OrganizationAndProject; + dashboardsPermission.AddChild(AevatarPermissions.LLMSModels.Default, L("Permission:LLMSModels")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; + dashboardsPermission.AddChild(AevatarPermissions.ApiRequests.Default, L("Permission:ApiRequests")) + .Properties[AevatarPermissions.OrganizationScopeKey] = PermissionScope.OrganizationAndProject; } private static LocalizableString L(string name) diff --git a/src/Aevatar.Application.Contracts/Permissions/AevatarPermissions.cs b/src/Aevatar.Application.Contracts/Permissions/AevatarPermissions.cs index c5a4a0b83..1d31b0713 100644 --- a/src/Aevatar.Application.Contracts/Permissions/AevatarPermissions.cs +++ b/src/Aevatar.Application.Contracts/Permissions/AevatarPermissions.cs @@ -1,118 +1,117 @@ -namespace Aevatar.Permissions +namespace Aevatar.Permissions; + +public static class AevatarPermissions { - public static class AevatarPermissions + public const string BasicUser = "basicUser"; + public const string DeveloperManager = "developerManager"; + public const string AdminGroup = "AdminManagement"; + public const string AdminPolicy = AdminGroup + ".AdminPolicy"; + public const string DeveloperPlatform = "DeveloperPlatform"; + + public const string OrganizationScopeKey = "Scope"; + + // Permissions for Agent Management + public static class Agent + { + public const string GroupName = "AgentManagement"; + public const string ViewLogs = GroupName + ".ViewLogs"; + public const string ViewAllType = GroupName + ".ViewAllType"; + public const string ViewList = GroupName + ".ViewList"; + public const string Create = GroupName + ".Create"; + public const string View = GroupName + ".View"; + public const string Update = GroupName + ".Update"; + public const string Delete = GroupName + ".Delete"; + } + + // Permissions for Relationship Management + public static class Relationship + { + public const string GroupName = "AgentRelationshipManagement"; + + public const string ViewRelationship = GroupName + ".View"; + public const string AddSubAgent = GroupName + ".AddSubAgent"; + public const string RemoveSubAgent = GroupName + ".RemoveSubAgent"; + public const string RemoveAllSubAgents = GroupName + ".RemoveAllSubAgents"; + } + + // Permissions for Event Management + public static class EventManagement + { + public const string GroupName = "EventManagement"; + + public const string Publish = GroupName + ".Publish"; + public const string View = GroupName + ".View"; + } + + public static class HostManagement + { + public const string GroupName = "HostManagement"; + public const string Logs = GroupName + ".ViewLogs"; + } + + public static class CqrsManagement + { + public const string GroupName = "CqrsManagement"; + public const string Logs = GroupName + ".ViewLogs"; + public const string States = GroupName + ".ViewStates"; + } + + public static class SubscriptionManagent + { + public const string GroupName = "SubscriptionManagement"; + + public const string CreateSubscription = GroupName + ".CreateSubscription"; + public const string CancelSubscription = GroupName + ".CancelSubscription"; + public const string ViewSubscriptionStatus = GroupName + ".ViewSubscription"; + } + + public static class Organizations + { + public const string Default = DeveloperPlatform + ".Organizations"; + public const string Create = Default + ".Create"; + public const string Edit = Default + ".Edit"; + public const string Delete = Default + ".Delete"; + } + + public static class Members + { + public const string Default = DeveloperPlatform + ".Members"; + public const string Manage = Default + ".Manage"; + } + + public static class Projects + { + public const string Default = DeveloperPlatform + ".Projects"; + public const string Create = Default + ".Create"; + public const string Edit = Default + ".Edit"; + public const string Delete = Default + ".Delete"; + } + + public static class ApiKeys + { + public const string Default = DeveloperPlatform + ".ApiKeys"; + public const string Create = Default + ".Create"; + public const string Edit = Default + ".Edit"; + public const string Delete = Default + ".Delete"; + } + + public static class Roles + { + public const string Default = DeveloperPlatform + ".Roles"; + public const string Create = Default + ".Create"; + public const string Edit = Default + ".Edit"; + public const string Delete = Default + ".Delete"; + } + + public const string Dashboard = DeveloperPlatform + ".Dashboards"; + + public static class LLMSModels + { + public const string Default = Dashboard + ".LLMSModels"; + } + + public static class ApiRequests { - public const string BasicUser = "basicUser"; - public const string DeveloperManager = "developerManager"; - public const string AdminGroup = "AdminManagement"; - public const string AdminPolicy = AdminGroup+".AdminPolicy"; - public const string DeveloperPlatform = "DeveloperPlatform"; - - public const string OrganizationScopeKey = "Scope"; - - // Permissions for Agent Management - public static class Agent - { - public const string GroupName = "AgentManagement"; - public const string ViewLogs = GroupName + ".ViewLogs"; - public const string ViewAllType = GroupName + ".ViewAllType"; - public const string ViewList = GroupName + ".ViewList"; - public const string Create = GroupName + ".Create"; - public const string View = GroupName + ".View"; - public const string Update = GroupName + ".Update"; - public const string Delete = GroupName + ".Delete"; - } - - // Permissions for Relationship Management - public static class Relationship - { - public const string GroupName = "AgentRelationshipManagement"; - - public const string ViewRelationship = GroupName + ".View"; - public const string AddSubAgent = GroupName + ".AddSubAgent"; - public const string RemoveSubAgent = GroupName + ".RemoveSubAgent"; - public const string RemoveAllSubAgents = GroupName + ".RemoveAllSubAgents"; - } - - // Permissions for Event Management - public static class EventManagement - { - public const string GroupName = "EventManagement"; - - public const string Publish = GroupName + ".Publish"; - public const string View = GroupName + ".View"; - } - - public static class HostManagement - { - public const string GroupName = "HostManagement"; - public const string Logs = GroupName + ".ViewLogs"; - } - - public static class CqrsManagement - { - public const string GroupName = "CqrsManagement"; - public const string Logs = GroupName + ".ViewLogs"; - public const string States = GroupName + ".ViewStates"; - } - - public static class SubscriptionManagent - { - public const string GroupName = "SubscriptionManagement"; - - public const string CreateSubscription = GroupName + ".CreateSubscription"; - public const string CancelSubscription = GroupName + ".CancelSubscription"; - public const string ViewSubscriptionStatus = GroupName + ".ViewSubscription"; - } - - public static class Organizations - { - public const string Default = DeveloperPlatform + ".Organizations"; - public const string Create = Default + ".Create"; - public const string Edit = Default + ".Edit"; - public const string Delete = Default + ".Delete"; - } - - public static class Members - { - public const string Default = DeveloperPlatform + ".Members"; - public const string Manage = Default + ".Manage"; - } - - public static class Projects - { - public const string Default = DeveloperPlatform + ".Projects"; - public const string Create = Default + ".Create"; - public const string Edit = Default + ".Edit"; - public const string Delete = Default + ".Delete"; - } - - public static class ApiKeys - { - public const string Default = DeveloperPlatform + ".ApiKeys"; - public const string Create = Default + ".Create"; - public const string Edit = Default + ".Edit"; - public const string Delete = Default + ".Delete"; - } - - public static class Roles - { - public const string Default = DeveloperPlatform + ".Roles"; - public const string Create = Default + ".Create"; - public const string Edit = Default + ".Edit"; - public const string Delete = Default + ".Delete"; - } - - public const string Dashboard = DeveloperPlatform + ".Dashboards"; - - public static class LLMSModels - { - public const string Default = Dashboard + ".LLMSModels"; - } - - public static class ApiRequests - { - public const string Default = Dashboard + ".ApiRequests"; - } + public const string Default = Dashboard + ".ApiRequests"; } -} +} \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Projects/CreateProjectDto.cs b/src/Aevatar.Application.Contracts/Projects/CreateProjectDto.cs index 21880e933..4a4ba9b2d 100644 --- a/src/Aevatar.Application.Contracts/Projects/CreateProjectDto.cs +++ b/src/Aevatar.Application.Contracts/Projects/CreateProjectDto.cs @@ -6,8 +6,6 @@ namespace Aevatar.Projects; public class CreateProjectDto : CreateOrganizationDto { - [Required] - public Guid OrganizationId { get; set; } - [Required] - public string DomainName { get; set; } + [Required] public Guid OrganizationId { get; set; } + [Required] public string DomainName { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Projects/UpdateProjectDto.cs b/src/Aevatar.Application.Contracts/Projects/UpdateProjectDto.cs index d5a12a8fe..1a8f45b02 100644 --- a/src/Aevatar.Application.Contracts/Projects/UpdateProjectDto.cs +++ b/src/Aevatar.Application.Contracts/Projects/UpdateProjectDto.cs @@ -5,6 +5,5 @@ namespace Aevatar.Projects; public class UpdateProjectDto : UpdateOrganizationDto { - [Required] - public string DomainName { get; set; } + [Required] public string DomainName { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/Query/AgentEventLogsDto.cs b/src/Aevatar.Application.Contracts/Query/AgentEventLogsDto.cs index 8a806e887..5ff3066f7 100644 --- a/src/Aevatar.Application.Contracts/Query/AgentEventLogsDto.cs +++ b/src/Aevatar.Application.Contracts/Query/AgentEventLogsDto.cs @@ -16,5 +16,5 @@ public class AgentEventDto public string AgentGrainType { get; set; } public string EventName { get; set; } public DateTime Ctime { get; set; } - public string EventJson{ get; set; } + public string EventJson { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Application.Contracts/SignalR/SignalRMessage/NotificationHandleResponse.cs b/src/Aevatar.Application.Contracts/SignalR/SignalRMessage/NotificationHandleResponse.cs index 93a89fdf6..31fdd85b5 100644 --- a/src/Aevatar.Application.Contracts/SignalR/SignalRMessage/NotificationHandleResponse.cs +++ b/src/Aevatar.Application.Contracts/SignalR/SignalRMessage/NotificationHandleResponse.cs @@ -4,13 +4,12 @@ namespace Aevatar.SignalR.SignalRMessage; -public class NotificationResponse:ISignalRMessage +public class NotificationResponse : ISignalRMessage { public string MessageType => "NotificationAction"; public NotificationResponseMessage Data { get; set; } } - [GenerateSerializer] public class NotificationResponseMessage { diff --git a/src/Aevatar.Application.Grains/AevatarGrainsAutoMapperProfile.cs b/src/Aevatar.Application.Grains/AevatarGrainsAutoMapperProfile.cs index e45967782..6d3d879f5 100644 --- a/src/Aevatar.Application.Grains/AevatarGrainsAutoMapperProfile.cs +++ b/src/Aevatar.Application.Grains/AevatarGrainsAutoMapperProfile.cs @@ -6,7 +6,5 @@ public class AevatarGrainsAutoMapperProfile : Profile { public AevatarGrainsAutoMapperProfile() { - // User AutoMap - } } \ No newline at end of file diff --git a/src/Aevatar.Application.Grains/Agents/Creator/CreatorGAgent.cs b/src/Aevatar.Application.Grains/Agents/Creator/CreatorGAgent.cs index c2e1f3dee..58265bd9d 100644 --- a/src/Aevatar.Application.Grains/Agents/Creator/CreatorGAgent.cs +++ b/src/Aevatar.Application.Grains/Agents/Creator/CreatorGAgent.cs @@ -16,23 +16,23 @@ public class CreatorGAgent : GAgentBase, { private readonly ILogger _logger; - public CreatorGAgent(ILogger logger) + public CreatorGAgent(ILogger logger) { _logger = logger; } - + public override Task GetDescriptionAsync() { return Task.FromResult( "Represents an agent responsible for creating and grouping other agents"); } - + public async Task GetAgentAsync() { _logger.LogInformation("GetAgentAsync {state}", JsonConvert.SerializeObject(State)); return State; } - + public async Task CreateAgentAsync(AgentData agentData) { _logger.LogInformation("CreateAgentAsync"); @@ -48,7 +48,7 @@ public async Task CreateAgentAsync(AgentData agentData) }); await ConfirmEvents(); } - + public async Task UpdateAgentAsync(UpdateAgentInput dto) { _logger.LogInformation("UpdateAgentAsync"); @@ -69,9 +69,9 @@ public async Task DeleteAgentAsync() }); await ConfirmEvents(); } - + public async Task UpdateAvailableEventsAsync(List? eventTypeList) - { + { _logger.LogInformation("UpdateAvailableEventsAsync {list}", JsonConvert.SerializeObject(eventTypeList)); if (eventTypeList == null) { @@ -88,15 +88,16 @@ public async Task UpdateAvailableEventsAsync(List? eventTypeList) Description = t.GetCustomAttribute()?.Description ?? "No description", }); } - + RaiseEvent(new UpdateAvailableEventsGEvent() { EventInfoList = eventDescriptionList }); await ConfirmEvents(); - _logger.LogInformation("UpdateAvailableEventsAsync Finish {list}", JsonConvert.SerializeObject(eventDescriptionList)); + _logger.LogInformation("UpdateAvailableEventsAsync Finish {list}", + JsonConvert.SerializeObject(eventDescriptionList)); } - + public async Task PublishEventAsync(T @event) where T : EventBase { if (@event == null) @@ -104,11 +105,12 @@ public async Task PublishEventAsync(T @event) where T : EventBase throw new ArgumentNullException(nameof(@event)); } - Logger.LogInformation( "publish event: {event}", @event); + Logger.LogInformation("publish event: {event}", @event); await PublishAsync(@event); } - - protected override void GAgentTransitionState(CreatorGAgentState state, StateLogEventBase @event) + + protected override void GAgentTransitionState(CreatorGAgentState state, + StateLogEventBase @event) { switch (@event) { diff --git a/src/Aevatar.Application.Grains/Agents/Group/GroupGAgent.cs b/src/Aevatar.Application.Grains/Agents/Group/GroupGAgent.cs index f0f2562d0..e51022699 100644 --- a/src/Aevatar.Application.Grains/Agents/Group/GroupGAgent.cs +++ b/src/Aevatar.Application.Grains/Agents/Group/GroupGAgent.cs @@ -9,12 +9,11 @@ namespace Aevatar.Application.Grains.Agents.Group; [LogConsistencyProvider(ProviderName = "LogStorage")] public class GroupGAgent : GAgentBase { - public override Task GetDescriptionAsync() { return Task.FromResult("An agent to inform other agents when a social event is published."); } - + protected override async Task OnGAgentActivateAsync(CancellationToken cancellationToken) { State.RegisteredAgents = 0; diff --git a/src/Aevatar.Application.Grains/Agents/Group/IGroupStateAgent.cs b/src/Aevatar.Application.Grains/Agents/Group/IGroupStateAgent.cs index 0b731269e..6cbd0547e 100644 --- a/src/Aevatar.Application.Grains/Agents/Group/IGroupStateAgent.cs +++ b/src/Aevatar.Application.Grains/Agents/Group/IGroupStateAgent.cs @@ -2,7 +2,4 @@ namespace Aevatar.Application.Grains.Agents.Group; -public interface IGroupStateAgent: IStateGAgent -{ - -} \ No newline at end of file +public interface IGroupStateAgent : IStateGAgent; \ No newline at end of file diff --git a/src/Aevatar.Application.Grains/Agents/Publisher/PublishingGAgent.cs b/src/Aevatar.Application.Grains/Agents/Publisher/PublishingGAgent.cs index a6f68b797..c88e11ebe 100644 --- a/src/Aevatar.Application.Grains/Agents/Publisher/PublishingGAgent.cs +++ b/src/Aevatar.Application.Grains/Agents/Publisher/PublishingGAgent.cs @@ -8,16 +8,14 @@ namespace Aevatar.Application.Grains.Agents.Publisher; [GenerateSerializer] -public class PublishingAgentState : StateBase -{ -} +public class PublishingAgentState : StateBase; [StorageProvider(ProviderName = "PubSubStore")] [LogConsistencyProvider(ProviderName = "LogStorage")] [GAgent("publish")] public class PublishingGAgent : GAgentBase, IPublishingGAgent { - public PublishingGAgent() + public PublishingGAgent() { } diff --git a/src/Aevatar.Application.Grains/Agents/TestAgent/AgentChildTest.cs b/src/Aevatar.Application.Grains/Agents/TestAgent/AgentChildTest.cs index ee759371a..c50023eee 100644 --- a/src/Aevatar.Application.Grains/Agents/TestAgent/AgentChildTest.cs +++ b/src/Aevatar.Application.Grains/Agents/TestAgent/AgentChildTest.cs @@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations; using Aevatar.Core; using Aevatar.Core.Abstractions; -using Aevatar.GAgents.AI.Options; using Microsoft.Extensions.Logging; using Orleans.Providers; @@ -69,9 +68,7 @@ await PublishAsync(new FrontParentTestCreateEvent } } -public interface IFrontAgentChildTest : IGAgent -{ -} +public interface IFrontAgentChildTest : IGAgent; [GenerateSerializer] public class ChildAgentState : StateBase @@ -82,9 +79,7 @@ public class ChildAgentState : StateBase } [GenerateSerializer] -public class FrontChildTestEvent : StateLogEventBase -{ -} +public class FrontChildTestEvent : StateLogEventBase; [GenerateSerializer] public class FrontChildTestCreateSEvent : FrontChildTestEvent diff --git a/src/Aevatar.Application/Account/AccountService.cs b/src/Aevatar.Application/Account/AccountService.cs index bd89571df..3cc284cfb 100644 --- a/src/Aevatar.Application/Account/AccountService.cs +++ b/src/Aevatar.Application/Account/AccountService.cs @@ -18,7 +18,7 @@ public class AccountService : AccountAppService, IAccountService { private readonly IAevatarAccountEmailer _aevatarAccountEmailer; private readonly AccountOptions _accountOptions; - private readonly IDistributedCache _registerCode; + private readonly IDistributedCache _registerCode; private readonly DistributedCacheEntryOptions _defaultCacheOptions; public AccountService(IdentityUserManager userManager, IIdentityRoleRepository roleRepository, @@ -66,13 +66,13 @@ public async Task SendRegisterCodeAsync(SendRegisterCodeDto input) { throw new UserFriendlyException($"The email: {input.Email} has been registered."); } - + user = await UserManager.FindByNameAsync(input.UserName); if (user != null) { throw new UserFriendlyException($"The user name: {input.UserName} has been registered."); } - + var code = GenerateVerificationCode(); await _registerCode.SetAsync(GetRegisterCodeKey(input.Email), code, _defaultCacheOptions); await _aevatarAccountEmailer.SendRegisterCodeAsync(input.Email, code); @@ -90,7 +90,7 @@ public override async Task SendPasswordResetCodeAsync(SendPasswordResetCodeDto i var resetToken = await UserManager.GeneratePasswordResetTokenAsync(user); await _aevatarAccountEmailer.SendPasswordResetLinkAsync(user, resetToken); } - + private string GenerateVerificationCode() { var random = new Random(); diff --git a/src/Aevatar.Application/Account/AevatarAccountEmailer.cs b/src/Aevatar.Application/Account/AevatarAccountEmailer.cs index 72bf2b27c..b1fd31bb4 100644 --- a/src/Aevatar.Application/Account/AevatarAccountEmailer.cs +++ b/src/Aevatar.Application/Account/AevatarAccountEmailer.cs @@ -31,12 +31,12 @@ public class AevatarAccountEmailer : IAevatarAccountEmailer, ITransientDependenc private readonly IEmailSender _emailSender; private readonly IStringLocalizer _stringLocalizer; private readonly AccountOptions _accountOptions; - private readonly IDistributedCache _lastEmailCache; + private readonly IDistributedCache _lastEmailCache; private readonly DistributedCacheEntryOptions _defaultCacheOptions; public AevatarAccountEmailer(IEmailSender emailSender, ITemplateRenderer templateRenderer, IStringLocalizer stringLocalizer, IOptionsSnapshot accountOptions, - IDistributedCache lastEmailCache) + IDistributedCache lastEmailCache) { _emailSender = emailSender; _templateRenderer = templateRenderer; @@ -58,7 +58,7 @@ public async Task SendRegisterCodeAsync(string email, string code) ); await CheckSendEmailAsync(email); - + await _emailSender.SendAsync( email, "Registration", @@ -75,9 +75,9 @@ public async Task SendPasswordResetLinkAsync(IdentityUser user, string resetToke AccountEmailTemplates.PasswordResetLink, new { link = link } ); - + await CheckSendEmailAsync(user.Email); - + await _emailSender.SendAsync( user.Email, "PasswordReset", @@ -93,7 +93,7 @@ private async Task CheckSendEmailAsync(string email) { throw new UserFriendlyException("Email sent too frequently. Please try again later."); } - + await _lastEmailCache.SetAsync(key, email, _defaultCacheOptions); } } \ No newline at end of file diff --git a/src/Aevatar.Application/AevatarApplicationAutoMapperProfile.cs b/src/Aevatar.Application/AevatarApplicationAutoMapperProfile.cs index b47fb378a..840aadc87 100644 --- a/src/Aevatar.Application/AevatarApplicationAutoMapperProfile.cs +++ b/src/Aevatar.Application/AevatarApplicationAutoMapperProfile.cs @@ -38,7 +38,7 @@ public AevatarApplicationAutoMapperProfile() s.ExtraProperties.ContainsKey(AevatarConsts.ProjectDomainNameKey) ? s.ExtraProperties[AevatarConsts.ProjectDomainNameKey].ToString() : null)); - + CreateMap() .ForMember(d => d.Time, m => m.MapFrom(s => DateTimeHelper.ToUnixTimeMilliseconds(s.Time))); diff --git a/src/Aevatar.Application/AevatarApplicationModule.cs b/src/Aevatar.Application/AevatarApplicationModule.cs index 6fd0de5b2..90084231a 100644 --- a/src/Aevatar.Application/AevatarApplicationModule.cs +++ b/src/Aevatar.Application/AevatarApplicationModule.cs @@ -48,16 +48,13 @@ public class AevatarApplicationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - Configure(options => - { - options.AddMaps(); - }); - + Configure(options => { options.AddMaps(); }); + Configure(options => { options.FileSets.AddEmbedded(); }); - + var configuration = context.Services.GetConfiguration(); Configure(configuration.GetSection("NameContest")); context.Services.AddSingleton(); @@ -67,8 +64,8 @@ public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddSingleton(); Configure(configuration.GetSection("HostDeploy")); context.Services.Configure(configuration.GetSection("Host")); - + Configure(configuration.GetSection("Account")); Configure(configuration.GetSection("ApiRequest")); } -} +} \ No newline at end of file diff --git a/src/Aevatar.Application/ApiRequests/ApiRequestSegment.cs b/src/Aevatar.Application/ApiRequests/ApiRequestSegment.cs index 37be297e7..7264648b8 100644 --- a/src/Aevatar.Application/ApiRequests/ApiRequestSegment.cs +++ b/src/Aevatar.Application/ApiRequests/ApiRequestSegment.cs @@ -7,5 +7,4 @@ public class ApiRequestSegment public string AppId { get; set; } public DateTime SegmentTime { get; set; } public long Count { get; set; } - } \ No newline at end of file diff --git a/src/Aevatar.Application/ApiRequests/ApiRequestService.cs b/src/Aevatar.Application/ApiRequests/ApiRequestService.cs index 5cb0607a0..8f5089ea2 100644 --- a/src/Aevatar.Application/ApiRequests/ApiRequestService.cs +++ b/src/Aevatar.Application/ApiRequests/ApiRequestService.cs @@ -19,11 +19,12 @@ public ApiRequestService(IApiRequestSnapshotRepository apiRequestSnapshotReposit public async Task> GetListAsync(GetApiRequestDto input) { var organizationId = input.ProjectId.HasValue ? input.ProjectId.Value : input.OrganizationId.Value; - + var query = await _apiRequestSnapshotRepository.GetQueryableAsync(); query = query.Where(o => - o.OrganizationId == organizationId && o.Time >= DateTimeHelper.FromUnixTimeMilliseconds(input.StartTime) && - o.Time <= DateTimeHelper.FromUnixTimeMilliseconds(input.EndTime)) + o.OrganizationId == organizationId && + o.Time >= DateTimeHelper.FromUnixTimeMilliseconds(input.StartTime) && + o.Time <= DateTimeHelper.FromUnixTimeMilliseconds(input.EndTime)) .OrderBy(o => o.Time); var list = query.ToList(); diff --git a/src/Aevatar.Application/ApiRequests/ApiRequestStatisticsMiddleware.cs b/src/Aevatar.Application/ApiRequests/ApiRequestStatisticsMiddleware.cs index 5340d516e..be7f3a0bb 100644 --- a/src/Aevatar.Application/ApiRequests/ApiRequestStatisticsMiddleware.cs +++ b/src/Aevatar.Application/ApiRequests/ApiRequestStatisticsMiddleware.cs @@ -18,11 +18,11 @@ public ApiRequestStatisticsMiddleware(RequestDelegate next, IApiRequestProvider public async Task InvokeAsync(HttpContext context) { var clientId = context.User.FindFirst("client_id")?.Value; - if(!clientId.IsNullOrWhiteSpace()) + if (!clientId.IsNullOrWhiteSpace()) { await _apiRequestProvider.IncreaseRequestAsync(clientId, DateTime.UtcNow); } - + await _next(context); } } \ No newline at end of file diff --git a/src/Aevatar.Application/ApiRequests/IApiRequestProvider.cs b/src/Aevatar.Application/ApiRequests/IApiRequestProvider.cs index 4c34c4415..bb0029a42 100644 --- a/src/Aevatar.Application/ApiRequests/IApiRequestProvider.cs +++ b/src/Aevatar.Application/ApiRequests/IApiRequestProvider.cs @@ -78,16 +78,17 @@ public async Task FlushAsync() var time = item.Value.SegmentTime.Date.AddHours(item.Value.SegmentTime.Hour); await UpdateSnapshotAsync(app.ProjectId, time, item.Value.Count, insertEntities, updateEntities); - + var organization = await _organizationUnitRepository.GetAsync(app.ProjectId); - await UpdateSnapshotAsync(organization.ParentId.Value, time, item.Value.Count, insertEntities, updateEntities); + await UpdateSnapshotAsync(organization.ParentId.Value, time, item.Value.Count, insertEntities, + updateEntities); } if (insertEntities.Values.Count > 0) { await _apiRequestSnapshotRepository.InsertManyAsync(insertEntities.Values); } - + if (updateEntities.Values.Count > 0) { await _apiRequestSnapshotRepository.UpdateManyAsync(updateEntities.Values); @@ -130,7 +131,7 @@ private string GetApiRequestKey(string appId, DateTime dateTime) { return $"{appId}-{dateTime}"; } - + private DateTime GetSegmentTime(DateTime dateTime) { var minute = (dateTime.Minute / _apiRequestOptions.FlushPeriod) * _apiRequestOptions.FlushPeriod; diff --git a/src/Aevatar.Application/Common/ReflectionUtil.cs b/src/Aevatar.Application/Common/ReflectionUtil.cs index 6437a1d47..de8eed614 100644 --- a/src/Aevatar.Application/Common/ReflectionUtil.cs +++ b/src/Aevatar.Application/Common/ReflectionUtil.cs @@ -11,7 +11,7 @@ public static object ConvertValue(Type targetType, object? value) { return null; } - + if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(List<>)) { var elementType = targetType.GetGenericArguments()[0]; @@ -24,7 +24,7 @@ public static object ConvertValue(Type targetType, object? value) return list; } - + return Convert.ChangeType(value, targetType); } } \ No newline at end of file diff --git a/src/Aevatar.Application/Dapr/DaprProvider.cs b/src/Aevatar.Application/Dapr/DaprProvider.cs index b6f4d1e0d..fc6375566 100644 --- a/src/Aevatar.Application/Dapr/DaprProvider.cs +++ b/src/Aevatar.Application/Dapr/DaprProvider.cs @@ -26,13 +26,15 @@ public async Task PublishEventAsync(string pubsubName, string topicName, T me try { await _daprClient.PublishEventAsync(pubsubName, topicName, message); - _logger.LogInformation("Dapr event published. pubsubName: {pubsub}, topicName: {topicName}, message: {message}", + _logger.LogInformation( + "Dapr event published. pubsubName: {pubsub}, topicName: {topicName}, message: {message}", pubsubName, topicName, message); } catch (Exception ex) { - _logger.LogError(ex, "Error publishing event. pubsubName: {pubsub}, topicName: {topicName},, message: {message}", - pubsubName, topicName,message); + _logger.LogError(ex, + "Error publishing event. pubsubName: {pubsub}, topicName: {topicName},, message: {message}", + pubsubName, topicName, message); ; } } diff --git a/src/Aevatar.Application/DateTimeHelper.cs b/src/Aevatar.Application/DateTimeHelper.cs index bafd20edd..74662d62c 100644 --- a/src/Aevatar.Application/DateTimeHelper.cs +++ b/src/Aevatar.Application/DateTimeHelper.cs @@ -7,7 +7,7 @@ public class DateTimeHelper public static long ToUnixTimeMilliseconds(DateTime value) { var span = value - DateTime.UnixEpoch; - return (long) span.TotalMilliseconds; + return (long)span.TotalMilliseconds; } public static DateTime FromUnixTimeMilliseconds(long value) diff --git a/src/Aevatar.Application/Notification/NotificationCreateEventBusHandler.cs b/src/Aevatar.Application/Notification/NotificationCreateEventBusHandler.cs index 8e6520df7..cfb02693f 100644 --- a/src/Aevatar.Application/Notification/NotificationCreateEventBusHandler.cs +++ b/src/Aevatar.Application/Notification/NotificationCreateEventBusHandler.cs @@ -5,7 +5,8 @@ namespace Aevatar.Notification; -public class NotificationCreateEventBusHandler:IDistributedEventHandler, ITransientDependency +public class NotificationCreateEventBusHandler : IDistributedEventHandler, + ITransientDependency { private readonly INotificationService _notificationService; diff --git a/src/Aevatar.Application/Notification/NotificationImpl/OrganizationVisit.cs b/src/Aevatar.Application/Notification/NotificationImpl/OrganizationVisit.cs index 91082cf1b..586ddbce1 100644 --- a/src/Aevatar.Application/Notification/NotificationImpl/OrganizationVisit.cs +++ b/src/Aevatar.Application/Notification/NotificationImpl/OrganizationVisit.cs @@ -14,7 +14,8 @@ public class OrganizationVisit : NotificationHandlerBase private readonly IdentityUserManager _userManager; private readonly ILogger _logger; - public OrganizationVisit(IOrganizationService organizationService, IdentityUserManager userManager, ILogger logger) + public OrganizationVisit(IOrganizationService organizationService, IdentityUserManager userManager, + ILogger logger) { _organizationService = organizationService; _userManager = userManager; @@ -34,10 +35,10 @@ public override async Task GetContentForShowAsync(OrganizationVisitInfo stopWatch.Start(); var creator = await _userManager.GetByIdAsync(input.Creator); var organization = await _organizationService.GetAsync(input.OrganizationId); - + stopWatch.Stop(); _logger.LogInformation($"StopWatch GetContentForShowAsync use time:{stopWatch.ElapsedMilliseconds}"); - + return $"{creator!.Name} has invited you to join {organization.DisplayName}"; } diff --git a/src/Aevatar.Application/Notification/NotificationProcessor.cs b/src/Aevatar.Application/Notification/NotificationProcessor.cs index 6ae942e0a..db34f63f9 100644 --- a/src/Aevatar.Application/Notification/NotificationProcessor.cs +++ b/src/Aevatar.Application/Notification/NotificationProcessor.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Reflection; using Aevatar.Notification.NotificationImpl; using Aevatar.Notification.Parameters; using Microsoft.Extensions.DependencyInjection; @@ -26,34 +24,6 @@ public NotificationProcessorFactory(IServiceProvider serviceProvider, ILogger - // t.IsClass && - // !t.IsAbstract && - // t.GetInterfaces().Any(item => - // item.IsGenericType && item.GetGenericTypeDefinition() == typeof(INotificationHandler<>)) - // ); - // - // - // foreach (var item in handlerTypes) - // { - // var instance = - // ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider, item) as INotificationHandlerType; - // if (instance == null) - // { - // _logger.LogError( - // $"[NotificationProcessor] Constructor ActivatorUtilities.GetServiceOrCreateInstance error:{item.FullName}"); - // continue; - // } - // - // _typeDic.TryAdd(instance.Type, item); - // - // var inheritInterface = item.GetInterfaces().First(w => w.IsGenericType && w.GetGenericTypeDefinition() == typeof(INotificationHandler<>)); - // var genericType = inheritInterface.GetGenericArguments()[0]; - // _typeToGeneratorDic.TryAdd(item, genericType); - // } - _typeDic.TryAdd(NotificationTypeEnum.OrganizationInvitation, typeof(OrganizationVisit)); _typeToGeneratorDic.TryAdd(typeof(OrganizationVisit), typeof(OrganizationVisitInfo)); } diff --git a/src/Aevatar.Application/Notification/NotificationService.cs b/src/Aevatar.Application/Notification/NotificationService.cs index 8f3858814..144491a82 100644 --- a/src/Aevatar.Application/Notification/NotificationService.cs +++ b/src/Aevatar.Application/Notification/NotificationService.cs @@ -90,17 +90,22 @@ public async Task CreateAsync(NotificationTypeEnum notificationTypeEnum, G { _logger.LogDebug($"Push new message to {(Guid)notification.CreatorId!} and {notification.Receiver}"); await _hubService.ResponseAsync([(Guid)notification.CreatorId!, notification.Receiver], - new NotificationResponse() + new NotificationResponse { - Data = new NotificationResponseMessage() - { Id = notification.Id, Status = NotificationStatusEnum.None } + Data = new NotificationResponseMessage + { + Id = notification.Id, + Status = NotificationStatusEnum.None + } }); - + _logger.LogDebug($"Push unread message to {target}"); var unreadCount = await GetUnreadCountAsync(target); await _hubService.ResponseAsync([target], - new UnreadNotificationResponse() - { Data = new UnreadNotification(unreadCount: unreadCount) }); + new UnreadNotificationResponse + { + Data = new UnreadNotification(unreadCount: unreadCount) + }); }); @@ -122,10 +127,13 @@ public async Task WithdrawAsync(Guid? creator, Guid notificationId) _ = Task.Run(async () => { await _hubService.ResponseAsync([(Guid)notification.CreatorId!, notification.Receiver], - new NotificationResponse() + new NotificationResponse { - Data = new NotificationResponseMessage() - { Id = notificationId, Status = NotificationStatusEnum.Withdraw } + Data = new NotificationResponseMessage + { + Id = notificationId, + Status = NotificationStatusEnum.Withdraw + } }); }); @@ -164,8 +172,14 @@ public async Task Response(Guid notificationId, Guid? receiver, Notificati _ = Task.Run(async () => { await _hubService.ResponseAsync([(Guid)notification.CreatorId!, notification.Receiver], - new NotificationResponse() - { Data = new NotificationResponseMessage() { Id = notificationId, Status = status } }); + new NotificationResponse + { + Data = new NotificationResponseMessage + { + Id = notificationId, + Status = status + } + }); }); return true; @@ -216,8 +230,9 @@ public async Task> GetOrganizationVisitInfo(Guid user if (organizationInfoObj != null) { var organizationVisitInfo = organizationInfoObj as OrganizationVisitInfo; - var organizationInfo = await _organizationUnitRepository.GetAsync(organizationVisitInfo!.OrganizationId); - result.Add(new OrganizationVisitDto() + var organizationInfo = + await _organizationUnitRepository.GetAsync(organizationVisitInfo!.OrganizationId); + result.Add(new OrganizationVisitDto { Id = item.Id, OrganizationId = organizationInfo.Id, @@ -242,8 +257,8 @@ public async Task ReadAsync(Guid userId, ReadNotificationDto input) if (input.NotificationId.HasValue) { var notification = - await _notificationRepository.FirstAsync( - o => o.Id == input.NotificationId.Value && o.Receiver == userId); + await _notificationRepository.FirstAsync(o => + o.Id == input.NotificationId.Value && o.Receiver == userId); notification.IsRead = true; await _notificationRepository.UpdateAsync(notification); @@ -262,7 +277,9 @@ await _notificationRepository.FirstAsync( } await _hubService.ResponseAsync([userId], - new UnreadNotificationResponse() - { Data = new UnreadNotification(unreadCount: unreadCount) }); + new UnreadNotificationResponse + { + Data = new UnreadNotification(unreadCount: unreadCount) + }); } } \ No newline at end of file diff --git a/src/Aevatar.Application/Organizations/OrganizationPermissionChecker.cs b/src/Aevatar.Application/Organizations/OrganizationPermissionChecker.cs index 2e9f077ff..a40640d6c 100644 --- a/src/Aevatar.Application/Organizations/OrganizationPermissionChecker.cs +++ b/src/Aevatar.Application/Organizations/OrganizationPermissionChecker.cs @@ -20,7 +20,7 @@ public class OrganizationPermissionChecker : IOrganizationPermissionChecker, ITr private readonly IPermissionDefinitionManager _permissionDefinitionManager; private readonly ICurrentPrincipalAccessor _principalAccessor; private readonly ISimpleStateCheckerManager _stateCheckerManager; - + public const string ProviderName = "R"; public OrganizationPermissionChecker(IdentityRoleManager roleManager, IPermissionStore permissionStore, @@ -51,7 +51,7 @@ public async Task IsGrantedAsync(Guid organizationId, string permissionNam { return false; } - + if (currentUserRoles.Contains(AevatarConsts.AdminRoleName)) { return true; @@ -76,7 +76,7 @@ private async Task IsGrantedAsync(string name, string role) { return false; } - + if (!permission.IsEnabled) { return false; @@ -86,7 +86,7 @@ private async Task IsGrantedAsync(string name, string role) { return false; } - + if (!await _permissionStore.IsGrantedAsync(name, ProviderName, role)) { return false; diff --git a/src/Aevatar.Application/Organizations/OrganizationPermissionService.cs b/src/Aevatar.Application/Organizations/OrganizationPermissionService.cs index 02dc79471..35a1fd067 100644 --- a/src/Aevatar.Application/Organizations/OrganizationPermissionService.cs +++ b/src/Aevatar.Application/Organizations/OrganizationPermissionService.cs @@ -20,7 +20,7 @@ public class OrganizationPermissionService : AevatarAppService, IOrganizationPer protected readonly IPermissionManager PermissionManager; protected readonly IPermissionDefinitionManager PermissionDefinitionManager; protected readonly ISimpleStateCheckerManager SimpleStateCheckerManager; - + public OrganizationPermissionService( IPermissionManager permissionManager, IPermissionDefinitionManager permissionDefinitionManager, @@ -43,7 +43,7 @@ public async Task GetAsync(Guid organizationId, stri var result = new GetPermissionListResultDto { EntityDisplayName = providerKey, - Groups = new List() + Groups = [] }; foreach (var group in (await PermissionDefinitionManager.GetGroupsAsync()).Where(o => @@ -112,15 +112,16 @@ await PermissionManager.GetAsync(neededCheckPermissions.Select(x => x.Name).ToAr return result; } - public async Task UpdateAsync(Guid organizationId, string providerName, string providerKey, UpdatePermissionsDto input) + public async Task UpdateAsync(Guid organizationId, string providerName, string providerKey, + UpdatePermissionsDto input) { OrganizationRoleHelper.CheckRoleInOrganization(organizationId, providerKey); - + if (OrganizationRoleHelper.IsOwner(providerKey)) { throw new UserFriendlyException("The owner role cannot be modified."); } - + await CheckProviderPolicy(providerName); foreach (var permissionDto in input.Permissions) @@ -128,22 +129,23 @@ public async Task UpdateAsync(Guid organizationId, string providerName, string p await PermissionManager.SetAsync(permissionDto.Name, providerName, providerKey, permissionDto.IsGranted); } } - + private PermissionGrantInfoDto CreatePermissionGrantInfoDto(PermissionDefinition permission) { - return new PermissionGrantInfoDto { + return new PermissionGrantInfoDto + { Name = permission.Name, DisplayName = permission.DisplayName?.Localize(StringLocalizerFactory), ParentName = permission.Parent?.Name, AllowedProviders = permission.Providers, - GrantedProviders = new List() + GrantedProviders = [] }; } private PermissionGroupDto CreatePermissionGroupDto(PermissionGroupDefinition group) { var localizableDisplayName = group.DisplayName as LocalizableString; - + return new PermissionGroupDto { Name = group.Name, @@ -155,13 +157,14 @@ private PermissionGroupDto CreatePermissionGroupDto(PermissionGroupDefinition gr Permissions = new List() }; } - + protected virtual async Task CheckProviderPolicy(string providerName) { var policyName = Options.ProviderPolicies.GetOrDefault(providerName); if (policyName.IsNullOrEmpty()) { - throw new AbpException($"No policy defined to get/set permissions for the provider '{providerName}'. Use {nameof(PermissionManagementOptions)} to map the policy."); + throw new AbpException( + $"No policy defined to get/set permissions for the provider '{providerName}'. Use {nameof(PermissionManagementOptions)} to map the policy."); } } } \ No newline at end of file diff --git a/src/Aevatar.Application/Organizations/OrganizationRoleHelper.cs b/src/Aevatar.Application/Organizations/OrganizationRoleHelper.cs index 767f48528..9b1d3f621 100644 --- a/src/Aevatar.Application/Organizations/OrganizationRoleHelper.cs +++ b/src/Aevatar.Application/Organizations/OrganizationRoleHelper.cs @@ -9,12 +9,12 @@ public static string GetRoleName(Guid organizationId, string roleName) { return $"{organizationId.ToString()}_{roleName}"; } - + public static string GetRoleOrganizationIdName(string roleName) { return roleName.Split("_")[0]; } - + public static void CheckRoleInOrganization(Guid organizationId, string roleName) { var roleOrganizationId = GetRoleOrganizationIdName(roleName); diff --git a/src/Aevatar.Application/Organizations/OrganizationRoleService.cs b/src/Aevatar.Application/Organizations/OrganizationRoleService.cs index 4edc6558a..f5b7a5e0a 100644 --- a/src/Aevatar.Application/Organizations/OrganizationRoleService.cs +++ b/src/Aevatar.Application/Organizations/OrganizationRoleService.cs @@ -52,7 +52,7 @@ public async Task CreateAsync(Guid organizationId, IdentityRole OrganizationRoleHelper.GetRoleName(organizationId, input.Name) ); (await RoleManager.CreateAsync(role)).CheckErrors(); - + var organization = await OrganizationUnitRepository.GetAsync(organizationId); organization.TryGetOrganizationRoles(out var roles); roles.Add(role.Id); @@ -75,30 +75,30 @@ public async Task UpdateAsync(Guid organizationId, Guid id, Ide var newName = OrganizationRoleHelper.GetRoleName(organizationId, input.Name); - (await RoleManager.SetRoleNameAsync(role,newName)).CheckErrors(); - + (await RoleManager.SetRoleNameAsync(role, newName)).CheckErrors(); + (await RoleManager.UpdateAsync(role)).CheckErrors(); - + return ObjectMapper.Map(role); } public async Task DeleteAsync(Guid organizationId, Guid id) { var role = await RoleManager.GetByIdAsync(id); - + if (OrganizationRoleHelper.IsOwner(role.Name)) { throw new UserFriendlyException("The owner role cannot be deleted."); } - + OrganizationRoleHelper.CheckRoleInOrganization(organizationId, role.Name); - + var organization = await OrganizationUnitRepository.GetAsync(organizationId); organization.TryGetOrganizationRoles(out var roles); roles.Remove(role.Id); organization.ExtraProperties[AevatarConsts.OrganizationRoleKey] = roles; await OrganizationUnitManager.UpdateAsync(organization); - + await RoleManager.DeleteAsync(role); } } \ No newline at end of file diff --git a/src/Aevatar.Application/Organizations/OrganizationService.cs b/src/Aevatar.Application/Organizations/OrganizationService.cs index f0ec12470..2d8b186e2 100644 --- a/src/Aevatar.Application/Organizations/OrganizationService.cs +++ b/src/Aevatar.Application/Organizations/OrganizationService.cs @@ -11,7 +11,6 @@ using Volo.Abp.Application.Dtos; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Domain.Repositories; -using Volo.Abp.EventBus.Distributed; using Volo.Abp.Identity; using Volo.Abp.PermissionManagement; using IdentityRole = Volo.Abp.Identity.IdentityRole; @@ -56,14 +55,14 @@ public virtual async Task> GetListAsync(GetOrgani if (CurrentUser.IsInRole(AevatarConsts.AdminRoleName)) { organizations = await OrganizationUnitRepository.GetListAsync(); - foreach (var organization in organizations.OrderBy(o=>o.CreationTime)) + foreach (var organization in organizations.OrderBy(o => o.CreationTime)) { if (!organization.TryGetExtraPropertyValue(AevatarConsts.OrganizationTypeKey, out var type) || type != OrganizationType.Organization) { continue; } - + result.Add(ObjectMapper.Map(organization)); } } @@ -71,7 +70,7 @@ public virtual async Task> GetListAsync(GetOrgani { var user = await IdentityUserManager.GetByIdAsync(CurrentUser.Id.Value); organizations = await IdentityUserManager.GetOrganizationUnitsAsync(user); - foreach (var organization in organizations.OrderBy(o=>o.CreationTime)) + foreach (var organization in organizations.OrderBy(o => o.CreationTime)) { if (!organization.TryGetExtraPropertyValue(AevatarConsts.OrganizationTypeKey, out var type) || type != OrganizationType.Organization) @@ -198,7 +197,7 @@ protected virtual async Task AddReaderRoleAsync(Guid organizationId) OrganizationRoleHelper.GetRoleName(organizationId, AevatarConsts.OrganizationReaderRoleName) ); (await RoleManager.CreateAsync(role)).CheckErrors(); - + foreach (var permission in GetReaderPermissions()) { await PermissionManager.SetForRoleAsync(role.Name, permission, true); @@ -206,7 +205,7 @@ protected virtual async Task AddReaderRoleAsync(Guid organizationId) return role.Id; } - + protected virtual List GetReaderPermissions() { return @@ -292,9 +291,9 @@ protected virtual async Task AddMemberAsync(Guid organizationId, IdentityUser us RoleId = roleId.Value, Vistor = user.Id })); - + SetMemberStatus(organizationId, user, MemberStatus.Inviting); - SetMemberInvitationInfo(organizationId,user, new MemberInvitationInfo + SetMemberInvitationInfo(organizationId, user, new MemberInvitationInfo { Inviter = CurrentUser.Id.Value, InvitationId = notificationId @@ -360,9 +359,11 @@ public virtual async Task SetMemberRoleAsync(Guid organizationId, SetOrganizatio user.AddRole(input.RoleId); SetMemberStatus(organizationId, user, MemberStatus.Joined); - - (await IdentityUserManager.UpdateAsync(user)).CheckErrors();; - (await IdentityUserManager.UpdateSecurityStampAsync(user)).CheckErrors();; + + (await IdentityUserManager.UpdateAsync(user)).CheckErrors(); + ; + (await IdentityUserManager.UpdateSecurityStampAsync(user)).CheckErrors(); + ; } public virtual async Task RefuseInvitationAsync(Guid organizationId, Guid userId) @@ -373,12 +374,12 @@ public virtual async Task RefuseInvitationAsync(Guid organizationId, Guid userId { throw new UserFriendlyException("User is not in current organization."); } - + var userStatus = GetMemberStatus(organizationId, user); if (userStatus == MemberStatus.Inviting) { - SetMemberStatus(organizationId,user,MemberStatus.Refused); - (await IdentityUserManager.UpdateAsync(user)).CheckErrors();; + SetMemberStatus(organizationId, user, MemberStatus.Refused); + (await IdentityUserManager.UpdateAsync(user)).CheckErrors(); } } @@ -463,7 +464,7 @@ protected virtual async Task DeleteOrganizationRoleAsync(OrganizationUnit organi return null; } - protected virtual async Task IsOrganizationOwnerAsync(Guid organizationId,Guid userId) + protected virtual async Task IsOrganizationOwnerAsync(Guid organizationId, Guid userId) { var organization = await OrganizationUnitRepository.GetAsync(organizationId); var user = await IdentityUserManager.GetByIdAsync(userId); @@ -505,7 +506,7 @@ private void SetMemberStatus(Guid organizationId, IdentityUser user, MemberStatu { { organizationId.ToString(), memberStatus } }; } } - + private MemberInvitationInfo GetMemberInvitationInfo(Guid organizationId, IdentityUser user) { if (user.ExtraProperties.TryGetValue(AevatarConsts.MemberInvitationInfoKey, out var info)) diff --git a/src/Aevatar.Application/Organizations/OrganizationUnitExtensions.cs b/src/Aevatar.Application/Organizations/OrganizationUnitExtensions.cs index de9dfdda9..5a1db49db 100644 --- a/src/Aevatar.Application/Organizations/OrganizationUnitExtensions.cs +++ b/src/Aevatar.Application/Organizations/OrganizationUnitExtensions.cs @@ -18,10 +18,11 @@ public static bool TryGetExtraPropertyValue(this OrganizationUnit organizatio value = default; return false; } - + public static bool TryGetOrganizationRoles(this OrganizationUnit organizationUnit, out List value) { - if (organizationUnit.TryGetExtraPropertyValue>(AevatarConsts.OrganizationRoleKey, out var valueObject)) + if (organizationUnit.TryGetExtraPropertyValue>(AevatarConsts.OrganizationRoleKey, + out var valueObject)) { value = valueObject.OfType().ToList(); return true; diff --git a/src/Aevatar.Application/Plugins/PluginService.cs b/src/Aevatar.Application/Plugins/PluginService.cs index ad99ad47c..6af48919c 100644 --- a/src/Aevatar.Application/Plugins/PluginService.cs +++ b/src/Aevatar.Application/Plugins/PluginService.cs @@ -39,7 +39,7 @@ public async Task> GetListAsync(GetPluginDto input) var key = Guid.Parse(item.Key.Split("_").Last()); pluginStatus[key] = item.Value; } - + var pluginDtos = new List(); foreach (var plugin in list) { @@ -78,7 +78,7 @@ public async Task CreateAsync(Guid projectId, string name, byte[] cod var id = await _pluginGAgentManager.AddPluginAsync(new AddPluginDto { Code = code, - TenantId =projectId + TenantId = projectId }); var plugin = new Plugin(id) @@ -87,34 +87,34 @@ public async Task CreateAsync(Guid projectId, string name, byte[] cod Name = name }; await _pluginRepository.InsertAsync(plugin); - + return ObjectMapper.Map(plugin); } public async Task UpdateAsync(Guid id, string name, byte[] code) { var plugin = await _pluginRepository.GetAsync(id); - + await _pluginGAgentManager.UpdatePluginAsync(new Aevatar.Core.Abstractions.Plugin.UpdatePluginDto { Code = code, - TenantId =plugin.ProjectId, + TenantId = plugin.ProjectId, PluginCodeId = plugin.Id }); plugin.Name = name; await _pluginRepository.UpdateAsync(plugin); - + return ObjectMapper.Map(plugin); } public async Task DeleteAsync(Guid id) { var plugin = await _pluginRepository.GetAsync(id); - + await _pluginGAgentManager.RemovePluginAsync(new RemovePluginDto { - TenantId =plugin.ProjectId, + TenantId = plugin.ProjectId, PluginCodeId = plugin.Id }); diff --git a/src/Aevatar.Application/Projects/ProjectService.cs b/src/Aevatar.Application/Projects/ProjectService.cs index b4830e04c..1bd77f993 100644 --- a/src/Aevatar.Application/Projects/ProjectService.cs +++ b/src/Aevatar.Application/Projects/ProjectService.cs @@ -83,7 +83,7 @@ protected override List GetOwnerPermissions() AevatarPermissions.ApiRequests.Default ]; } - + protected override List GetReaderPermissions() { return @@ -128,7 +128,7 @@ await IsOrganizationOwnerAsync(input.OrganizationId, CurrentUser.Id.Value)) } var result = new List(); - foreach (var organization in organizations.OrderBy(o=>o.CreationTime)) + foreach (var organization in organizations.OrderBy(o => o.CreationTime)) { var projectDto = ObjectMapper.Map(organization); projectDto.MemberCount = await UserRepository.CountAsync(u => @@ -163,7 +163,7 @@ protected override async Task AddMemberAsync(Guid organizationId, IdentityUser u (await IdentityUserManager.UpdateSecurityStampAsync(user)).CheckErrors(); await IdentityUserManager.AddToOrganizationUnitAsync(user.Id, organizationId); } - + protected override async Task RemoveMemberAsync(Guid organizationId, IdentityUser user) { var children = await OrganizationUnitManager.FindChildrenAsync(organizationId, true); diff --git a/src/Aevatar.Application/Properties/AssemblyInfo.cs b/src/Aevatar.Application/Properties/AssemblyInfo.cs index 103114e9c..8efc90968 100644 --- a/src/Aevatar.Application/Properties/AssemblyInfo.cs +++ b/src/Aevatar.Application/Properties/AssemblyInfo.cs @@ -1,2 +1,2 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleToAttribute("Aevatar.Application.Tests")] +[assembly: InternalsVisibleToAttribute("Aevatar.Application.Tests")] \ No newline at end of file diff --git a/src/Aevatar.Application/Schema/SchemaProvider.cs b/src/Aevatar.Application/Schema/SchemaProvider.cs index ab2350418..a67d83e99 100644 --- a/src/Aevatar.Application/Schema/SchemaProvider.cs +++ b/src/Aevatar.Application/Schema/SchemaProvider.cs @@ -25,7 +25,7 @@ public JsonSchema GetTypeSchema(Type type) { FlattenInheritanceHierarchy = true, GenerateEnumMappingDescription = true, - SchemaProcessors ={ new IgnoreSpecificBaseProcessor() } + SchemaProcessors = { new IgnoreSpecificBaseProcessor() } }; var schemaData = JsonSchema.FromType(type, settings); diff --git a/src/Aevatar.Application/Service/AgentService.cs b/src/Aevatar.Application/Service/AgentService.cs index 454ad7674..762b04eb9 100644 --- a/src/Aevatar.Application/Service/AgentService.cs +++ b/src/Aevatar.Application/Service/AgentService.cs @@ -11,7 +11,6 @@ using Aevatar.Common; using Aevatar.Core.Abstractions; using Aevatar.CQRS; -using Aevatar.CQRS.Dto; using Aevatar.CQRS.Provider; using Aevatar.Exceptions; using Aevatar.Options; @@ -428,9 +427,9 @@ public async Task AddSubAgentAsync(Guid guid, AddSubAgentDto addSub businessAgents.Add(businessAgent); subAgentGuids.Add(grainId.GetGuidKey()); } - + await agent.RegisterManyAsync(businessAgents); - + foreach (var businessAgent in businessAgents) { var eventsHandledByAgent = await businessAgent.GetAllSubscribedEventsAsync(); @@ -522,7 +521,6 @@ public async Task GetAgentRelationshipAsync(Guid guid) var agentState = await creatorAgent.GetAgentAsync(); var agent = await _gAgentFactory.GetGAgentAsync(agentState.BusinessAgentGrainId); - var parentGrainId = await agent.GetParentAsync(); var subAgentGrainIds = await GetSubAgentGrainIds(agent); var subAgentGuids = subAgentGrainIds.Select(x => x.GetGuidKey()).ToList(); @@ -543,7 +541,10 @@ public async Task RemoveAllSubAgentAsync(Guid guid) var agent = await _gAgentFactory.GetGAgentAsync(agentState.BusinessAgentGrainId); var subAgentGrainIds = await GetSubAgentGrainIds(agent); await RemoveSubAgentAsync(guid, - new RemoveSubAgentDto { RemovedSubAgents = subAgentGrainIds.Select(x => x.GetGuidKey()).ToList() }); + new RemoveSubAgentDto + { + RemovedSubAgents = subAgentGrainIds.Select(x => x.GetGuidKey()).ToList() + }); } private async Task> GetSubAgentGrainIds(IGAgent agent) diff --git a/src/Aevatar.Application/Service/DeveloperService.cs b/src/Aevatar.Application/Service/DeveloperService.cs index 53371dba1..3b6a1921c 100644 --- a/src/Aevatar.Application/Service/DeveloperService.cs +++ b/src/Aevatar.Application/Service/DeveloperService.cs @@ -1,31 +1,28 @@ -using System.Collections.Generic; using System.Threading.Tasks; using Aevatar.WebHook.Deploy; using Volo.Abp.Application.Services; namespace Aevatar.Service; - public interface IDeveloperService { Task CreateHostAsync(string HostId, string version, string corsUrls); Task DestroyHostAsync(string inputHostId, string inputVersion); - Task UpdateDockerImageAsync(string appId, string version, string newImage); } -public class DeveloperService: ApplicationService, IDeveloperService +public class DeveloperService : ApplicationService, IDeveloperService { private readonly IHostDeployManager _hostDeployManager; - public DeveloperService(IHostDeployManager hostDeployManager - ) + + public DeveloperService(IHostDeployManager hostDeployManager) { _hostDeployManager = hostDeployManager; } public async Task CreateHostAsync(string HostId, string version, string corsUrls) { - await _hostDeployManager.CreateHostAsync(HostId, version,corsUrls); + await _hostDeployManager.CreateHostAsync(HostId, version, corsUrls); } public async Task DestroyHostAsync(string inputHostId, string inputVersion) @@ -35,9 +32,6 @@ public async Task DestroyHostAsync(string inputHostId, string inputVersion) public async Task UpdateDockerImageAsync(string appId, string version, string newImage) { - await _hostDeployManager.UpdateDockerImageAsync(appId, version,newImage); + await _hostDeployManager.UpdateDockerImageAsync(appId, version, newImage); } - -} - - +} \ No newline at end of file diff --git a/src/Aevatar.Application/Service/IWebhookService.cs b/src/Aevatar.Application/Service/IWebhookService.cs index 62f7142f6..8fe3e8faa 100644 --- a/src/Aevatar.Application/Service/IWebhookService.cs +++ b/src/Aevatar.Application/Service/IWebhookService.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Services; @@ -11,4 +10,4 @@ public interface IWebhookService : IApplicationService Task> GetWebhookCodeAsync(string webhookId, string version); Task DestroyWebhookAsync(string inputWebhookId, string inputVersion); Task UpdateCodeAsync(string webhookId, string version, Dictionary codeFiles); -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.Application/Service/ProjectAppIdService.cs b/src/Aevatar.Application/Service/ProjectAppIdService.cs index 6c2b10232..3d5e6b9f1 100644 --- a/src/Aevatar.Application/Service/ProjectAppIdService.cs +++ b/src/Aevatar.Application/Service/ProjectAppIdService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Aevatar.ApiKey; using Aevatar.ApiKeys; @@ -25,7 +24,8 @@ public class ProjectAppIdService : IProjectAppIdService, ITransientDependency private readonly IdentityUserManager _identityUserManager; public ProjectAppIdService(IProjectAppIdRepository projectAppIdRepository, ILogger logger, - IOrganizationPermissionChecker organizationPermission, IUserAppService userAppService, IdentityUserManager identityUserManager) + IOrganizationPermissionChecker organizationPermission, IUserAppService userAppService, + IdentityUserManager identityUserManager) { _projectAppIdRepository = projectAppIdRepository; _logger = logger; @@ -34,7 +34,6 @@ public ProjectAppIdService(IProjectAppIdRepository projectAppIdRepository, ILogg _identityUserManager = identityUserManager; } - public async Task CreateAsync(Guid projectId, string keyName, Guid? currentUserId) { _logger.LogDebug($"[ProjectAppIdService][CreateAsync] projectId:{projectId}, keyName:{keyName}"); @@ -51,7 +50,7 @@ public async Task CreateAsync(Guid projectId, string keyName, Guid? currentUserI CreationTime = DateTime.Now, CreatorId = currentUserId, }; - + await _userAppService.RegisterClientAuthentication(appId, appSecret); await _projectAppIdRepository.InsertAsync(projectAppIdInfo); } @@ -63,7 +62,7 @@ public async Task DeleteAsync(Guid appId) { throw new UserFriendlyException("Api key not found"); } - + await _organizationPermission.AuthenticateAsync(appIdInfo.ProjectId, AevatarPermissions.ApiKeys.Delete); await _projectAppIdRepository.HardDeleteAsync(f => f.Id == appId); await _userAppService.DeleteClientAndAuthentication(appIdInfo.AppId); @@ -91,7 +90,6 @@ public async Task ModifyApiKeyAsync(Guid appId, string keyName) throw new BusinessException(message: "AppId is the same "); } - appIdInfo.AppName = keyName; await _projectAppIdRepository.UpdateAsync(appIdInfo); @@ -99,16 +97,20 @@ public async Task ModifyApiKeyAsync(Guid appId, string keyName) public async Task> GetApiKeysAsync(Guid projectId) { - APIKeyPagedRequestDto requestDto = new APIKeyPagedRequestDto() - { ProjectId = projectId, MaxResultCount = 10, SkipCount = 0 }; + var requestDto = new APIKeyPagedRequestDto + { + ProjectId = projectId, + MaxResultCount = 10, + SkipCount = 0 + }; var appIdList = await _projectAppIdRepository.GetProjectAppIds(requestDto); - + var result = new List(); foreach (var item in appIdList.Items) { var creatorInfo = await _identityUserManager.GetByIdAsync((Guid)item.CreatorId!); - result.Add(new ProjectAppIdListResponseDto() + result.Add(new ProjectAppIdListResponseDto { Id = item.Id, AppId = item.AppId, diff --git a/src/Aevatar.Application/Service/SubscriptionAppService.cs b/src/Aevatar.Application/Service/SubscriptionAppService.cs index 062107783..5fb038e78 100644 --- a/src/Aevatar.Application/Service/SubscriptionAppService.cs +++ b/src/Aevatar.Application/Service/SubscriptionAppService.cs @@ -40,13 +40,13 @@ public class SubscriptionAppService : ApplicationService, ISubscriptionAppServic private readonly IUserAppService _userAppService; private readonly IGAgentFactory _gAgentFactory; private readonly GrainTypeResolver _grainTypeResolver; - + public SubscriptionAppService( IClusterClient clusterClient, IObjectMapper objectMapper, IUserAppService userAppService, IGAgentFactory gAgentFactory, - ILogger logger, + ILogger logger, GrainTypeResolver grainTypeResolver) { _clusterClient = clusterClient; @@ -56,21 +56,23 @@ public SubscriptionAppService( _gAgentFactory = gAgentFactory; _grainTypeResolver = grainTypeResolver; } - + public async Task> GetAvailableEventsAsync(Guid agentId) { var agent = _clusterClient.GetGrain(agentId); - + var agentState = await agent.GetAgentAsync(); - _logger.LogInformation("GetAvailableEventsAsync id: {id} state: {state}", agentId, JsonConvert.SerializeObject(agentState)); - + _logger.LogInformation("GetAvailableEventsAsync id: {id} state: {state}", agentId, + JsonConvert.SerializeObject(agentState)); + var eventDescriptionList = new List(); foreach (var evt in agentState.EventInfoList) { var eventType = evt.EventType; - PropertyInfo[] properties = eventType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); + var properties = eventType.GetProperties(BindingFlags.Public | BindingFlags.Instance | + BindingFlags.Static | BindingFlags.DeclaredOnly); var eventPropertyList = new List(); - foreach (PropertyInfo property in properties) + foreach (var property in properties) { var eventProperty = new EventProperty() { @@ -80,7 +82,7 @@ public async Task> GetAvailableEventsAsync(Guid agentI }; eventPropertyList.Add(eventProperty); } - + eventDescriptionList.Add(new EventDescriptionDto() { EventType = eventType.FullName ?? eventType.Name, @@ -88,25 +90,25 @@ public async Task> GetAvailableEventsAsync(Guid agentI EventProperties = eventPropertyList }); } - + return eventDescriptionList; } - + public async Task SubscribeAsync(CreateSubscriptionDto createSubscriptionDto) { + var input = _objectMapper.Map(createSubscriptionDto); + var subscriptionStateAgent = + _clusterClient.GetGrain( + GuidUtil.StringToGuid(createSubscriptionDto.AgentId.ToString())); + + input.UserId = _userAppService.GetCurrentUserId(); + var subscriptionState = await subscriptionStateAgent.SubscribeAsync(input); - var input = _objectMapper.Map(createSubscriptionDto); - var subscriptionStateAgent = - _clusterClient.GetGrain(GuidUtil.StringToGuid(createSubscriptionDto.AgentId.ToString())); - - input.UserId = _userAppService.GetCurrentUserId(); - var subscriptionState = await subscriptionStateAgent.SubscribeAsync(input); - - var agent = _clusterClient.GetGrain(input.AgentId); - var agentState = await agent.GetAgentAsync(); - var businessAgent = await _gAgentFactory.GetGAgentAsync(agentState.BusinessAgentGrainId); - await businessAgent.RegisterAsync(subscriptionStateAgent); - return _objectMapper.Map(subscriptionState); + var agent = _clusterClient.GetGrain(input.AgentId); + var agentState = await agent.GetAgentAsync(); + var businessAgent = await _gAgentFactory.GetGAgentAsync(agentState.BusinessAgentGrainId); + await businessAgent.RegisterAsync(subscriptionStateAgent); + return _objectMapper.Map(subscriptionState); } public async Task CancelSubscriptionAsync(Guid subscriptionId) @@ -117,10 +119,11 @@ public async Task CancelSubscriptionAsync(Guid subscriptionId) var currentUserId = _userAppService.GetCurrentUserId(); if (subscriptionState.UserId != currentUserId) { - _logger.LogInformation("User {userId} is not allowed to cancel subscription {subscriptionId}.", currentUserId, subscriptionId); + _logger.LogInformation("User {userId} is not allowed to cancel subscription {subscriptionId}.", + currentUserId, subscriptionId); throw new UserFriendlyException("User is not allowed to cancel subscription"); } - + var agent = _clusterClient.GetGrain(subscriptionState.AgentId); await agent.UnregisterAsync(subscriptionStateAgent); await subscriptionStateAgent.UnsubscribeAsync(); @@ -137,15 +140,9 @@ public async Task PublishEventAsync(PublishEventDto dto) { var agent = _clusterClient.GetGrain(dto.AgentId); var agentState = await agent.GetAgentAsync(); - _logger.LogInformation("PublishEventAsync id: {id} state: {state}", dto.AgentId, JsonConvert.SerializeObject(agentState)); - - /*var currentUserId = _userAppService.GetCurrentUserId(); - if (agentState.UserId != currentUserId) - { - _logger.LogInformation("User {userId} is not allowed to publish event {eventType}.", currentUserId, dto.EventType); - throw new UserFriendlyException("User is not allowed to publish event"); - }*/ - + _logger.LogInformation("PublishEventAsync id: {id} state: {state}", dto.AgentId, + JsonConvert.SerializeObject(agentState)); + var eventList = agentState.EventInfoList; var eventDescription = eventList.Find(i => i.EventType.FullName == dto.EventType); @@ -162,32 +159,32 @@ public async Task PublishEventAsync(PublishEventDto dto) throw new UserFriendlyException("event could not be found"); } } - + var propertiesString = JsonConvert.SerializeObject(dto.EventProperties); var eventInstance = JsonConvert.DeserializeObject(propertiesString, eventDescription.EventType) as EventBase; - + if (eventInstance == null) { - _logger.LogError("Event {type} could not be instantiated with param {param}", dto.EventType, propertiesString); + _logger.LogError("Event {type} could not be instantiated with param {param}", dto.EventType, + propertiesString); throw new UserFriendlyException("event could not be instantiated"); } - + await agent.PublishEventAsync(eventInstance); - } - + private async Task RefreshEventListAsync(ICreatorGAgent creatorAgent) { var agentState = await creatorAgent.GetAgentAsync(); var totalEventList = new List(); - + var agent = await _gAgentFactory.GetGAgentAsync(agentState.BusinessAgentGrainId); var eventsHandledBySelf = await agent.GetAllSubscribedEventsAsync(); if (eventsHandledBySelf != null) { totalEventList.AddRange(eventsHandledBySelf); } - + var children = await agent.GetChildrenAsync(); var creatorGAgentType = _grainTypeResolver.GetGrainType(typeof(CreatorGAgent)); var subscriptionGAgentType = _grainTypeResolver.GetGrainType(typeof(SubscriptionGAgent)); @@ -208,7 +205,7 @@ private async Task RefreshEventListAsync(ICreatorGAgent creatorAgent) totalEventList.AddRange(eventsToAdd); } } - + await creatorAgent.UpdateAvailableEventsAsync(totalEventList); } } \ No newline at end of file diff --git a/src/Aevatar.Application/Service/UserAppService.cs b/src/Aevatar.Application/Service/UserAppService.cs index fd06f2589..99604177d 100644 --- a/src/Aevatar.Application/Service/UserAppService.cs +++ b/src/Aevatar.Application/Service/UserAppService.cs @@ -15,13 +15,12 @@ namespace Aevatar.Service; - public interface IUserAppService { Task ResetPasswordAsync(string userName, string newPassword); Task RegisterClientAuthentication(string clientId, string clientSecret); Guid GetCurrentUserId(); - Task GrantClientPermissionsAsync(string clientId); + Task GrantClientPermissionsAsync(string clientId); Task DeleteClientAndAuthentication(string clientId); } @@ -50,7 +49,7 @@ public UserAppService( } - public async Task RegisterClientAuthentication(string clientId, string clientSecret) + public async Task RegisterClientAuthentication(string clientId, string clientSecret) { if (await _applicationManager.FindByClientIdAsync(clientId) != null) { @@ -76,18 +75,19 @@ public async Task RegisterClientAuthentication(string clientId, string clientS await SetClientPermissionsAsync(clientId); await _applicationManager.CreateAsync(openIddictApplicationDescriptor); - + } - + private async Task SetClientPermissionsAsync(string clientId) { - var permissions= await _permissionManager.GetAllAsync(RolePermissionValueProvider.ProviderName, AevatarPermissions.DeveloperManager); + var permissions = await _permissionManager.GetAllAsync(RolePermissionValueProvider.ProviderName, + AevatarPermissions.DeveloperManager); foreach (var permission in permissions) { if (permission.IsGranted) { - await _permissionManager.SetForClientAsync(clientId,permission.Name,true); + await _permissionManager.SetForClientAsync(clientId, permission.Name, true); } } } @@ -101,7 +101,8 @@ public async Task ResetPasswordAsync(string userName, string newPassword) if (CurrentUser.UserName != userName) { - _logger.LogInformation($"[ResetPasswordAsync] CurrentUser.UserName:{CurrentUser.UserName} userName:{userName}"); + _logger.LogInformation( + $"[ResetPasswordAsync] CurrentUser.UserName:{CurrentUser.UserName} userName:{userName}"); throw new UserFriendlyException("Can only reset your own password"); } @@ -119,15 +120,15 @@ public async Task ResetPasswordAsync(string userName, string newPassword) .Aggregate((errors, error) => errors + ", " + error)); } } - + public Guid GetCurrentUserId() { if (!CurrentUser.UserName.IsNullOrEmpty()) { return GuidUtil.StringToGuid(CurrentUser.UserName); } - - var clientId = CurrentUser.GetAllClaims().First(o => o.Type == "client_id").Value; + + var clientId = CurrentUser.GetAllClaims().First(o => o.Type == "client_id").Value; return GuidUtil.StringToGuid(clientId); } @@ -138,14 +139,16 @@ public async Task GrantClientPermissionsAsync(string clientId) public async Task DeleteClientAndAuthentication(string clientId) { - var application = await _applicationManager.FindByClientIdAsync(clientId); + var application = await _applicationManager.FindByClientIdAsync(clientId); if (application == null) { throw new UserFriendlyException("A app with the same ID already exists."); } + await _applicationManager.DeleteAsync(application); - - var permissions= await _permissionManager.GetAllAsync(RolePermissionValueProvider.ProviderName, AevatarPermissions.DeveloperManager); + + var permissions = await _permissionManager.GetAllAsync(RolePermissionValueProvider.ProviderName, + AevatarPermissions.DeveloperManager); foreach (var permission in permissions) { if (permission.IsGranted) diff --git a/src/Aevatar.Application/Service/WebhookService.cs b/src/Aevatar.Application/Service/WebhookService.cs index 803b6df9b..99d972872 100644 --- a/src/Aevatar.Application/Service/WebhookService.cs +++ b/src/Aevatar.Application/Service/WebhookService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Threading.Tasks; using Aevatar.Application.Grains.Agents.Code; using Aevatar.Common; @@ -48,6 +47,7 @@ public async Task> GetWebhookCodeAsync(string webhook { result[file.Key] = Convert.ToBase64String(file.Value); } + return result; } @@ -56,7 +56,7 @@ public async Task DestroyWebhookAsync(string inputWebhookId, string inputVersion // Clear all CodeFiles in ICodeGAgent by uploading an empty dictionary await _clusterClient.GetGrain(GuidUtil.StringToGuid(inputWebhookId)).UploadCodeAsync( inputWebhookId, inputVersion, new Dictionary()); - + await _hostDeployManager.DestroyWebHookAsync(inputWebhookId, inputVersion); } diff --git a/src/Aevatar.Application/Validator/LuceneQueryValidator.cs b/src/Aevatar.Application/Validator/LuceneQueryValidator.cs index a9e1e87a5..20b1c344e 100644 --- a/src/Aevatar.Application/Validator/LuceneQueryValidator.cs +++ b/src/Aevatar.Application/Validator/LuceneQueryValidator.cs @@ -10,7 +10,7 @@ public LuceneQueryValidator() RuleFor(x => x.QueryString) .Must(NotContainsScript).WithMessage("Script queries are not allowed."); } - + private bool NotContainsScript(string query) { return !query.Contains("_script"); diff --git a/src/Aevatar.AuthServer/AevatarAuthServerModule.cs b/src/Aevatar.AuthServer/AevatarAuthServerModule.cs index b540420cf..14d65638c 100644 --- a/src/Aevatar.AuthServer/AevatarAuthServerModule.cs +++ b/src/Aevatar.AuthServer/AevatarAuthServerModule.cs @@ -48,7 +48,7 @@ namespace Aevatar.AuthServer; typeof(AbpOpenIddictDomainModule), typeof(AevatarMongoDbModule), typeof(AevatarApplicationContractsModule) - )] +)] public class AevatarAuthServerModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) @@ -74,7 +74,7 @@ public override void PreConfigureServices(ServiceConfigurationContext context) options.UseAspNetCore(); }); }); - + //add signature grant type PreConfigure(builder => { @@ -90,21 +90,18 @@ public override void PreConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - + context.Services.Configure(configuration.GetSection("Signature")); context.Services.Configure(configuration.GetSection("Chains")); - Configure(options => - { - options.CheckLibs = false; - }); + Configure(options => { options.CheckLibs = false; }); context.Services.Configure(options => { options.Grants.Add(GrantTypeConstants.SIGNATURE, new SignatureGrantHandler()); - options.Grants.Add(GrantTypeConstants.GOOGLE, - new GoogleGrantHandler(context.Services.GetRequiredService(), + options.Grants.Add(GrantTypeConstants.GOOGLE, + new GoogleGrantHandler(context.Services.GetRequiredService(), context.Services.GetRequiredService>())); - options.Grants.Add(GrantTypeConstants.APPLE, - new AppleGrantHandler(context.Services.GetRequiredService(), + options.Grants.Add(GrantTypeConstants.APPLE, + new AppleGrantHandler(context.Services.GetRequiredService(), context.Services.GetRequiredService>())); }); @@ -141,18 +138,15 @@ public override void ConfigureServices(ServiceConfigurationContext context) { options.StyleBundles.Configure( LeptonXLiteThemeBundles.Styles.Global, - bundle => - { - bundle.AddFiles("/global-styles.css"); - } + bundle => { bundle.AddFiles("/global-styles.css"); } ); }); Configure(options => { - //options.IsEnabledForGetRequests = true; - options.ApplicationName = "AuthServer"; - options.IsEnabled = false;//Disables the auditing system + //options.IsEnabledForGetRequests = true; + options.ApplicationName = "AuthServer"; + options.IsEnabled = false; //Disables the auditing system }); Configure(options => @@ -163,24 +157,15 @@ public override void ConfigureServices(ServiceConfigurationContext context) options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password"; }); - Configure(options => - { - options.IsJobExecutionEnabled = false; - }); + Configure(options => { options.IsJobExecutionEnabled = false; }); + + Configure(options => { options.KeyPrefix = "Aevatar:"; }); - Configure(options => - { - options.KeyPrefix = "Aevatar:"; - }); - var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("AevatarAuthServer"); - + context.Services.AddHealthChecks(); - - Configure(options => - { - options.Conventions.Add(new ApplicationDescription()); - }); + + Configure(options => { options.Conventions.Add(new ApplicationDescription()); }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -199,7 +184,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex { app.UseErrorPage(); } - + app.UseHealthChecks("/health"); app.UseCorrelationId(); @@ -208,12 +193,10 @@ public override void OnApplicationInitialization(ApplicationInitializationContex app.UseAuthentication(); app.UseAbpOpenIddictValidation(); - //app.UseMultiTenancy(); - app.UseUnitOfWork(); app.UseAuthorization(); app.UseAuditing(); app.UseAbpSerilogEnrichers(); app.UseConfiguredEndpoints(); } -} +} \ No newline at end of file diff --git a/src/Aevatar.AuthServer/AppleGrantHandler.cs b/src/Aevatar.AuthServer/AppleGrantHandler.cs index 0bb06ff10..06b4c1fb4 100644 --- a/src/Aevatar.AuthServer/AppleGrantHandler.cs +++ b/src/Aevatar.AuthServer/AppleGrantHandler.cs @@ -43,10 +43,10 @@ public async Task HandleAsync(ExtensionGrantContext context) var code = context.Request.GetParameter("code")?.ToString(); var idToken = context.Request.GetParameter("id_token")?.ToString(); var source = context.Request.GetParameter("source")?.ToString(); - - _logger.LogInformation("AppleGrantHandler.HandleAsync source: {source} idToken: {idToken} code: {code}", + + _logger.LogInformation("AppleGrantHandler.HandleAsync source: {source} idToken: {idToken} code: {code}", source, idToken, code); - + var aud = source == "ios" ? _configuration["Apple:NativeClientId"] : _configuration["Apple:WebClientId"]; if (string.IsNullOrEmpty(idToken)) { @@ -55,16 +55,18 @@ public async Task HandleAsync(ExtensionGrantContext context) _logger.LogInformation("Missing both id_token and code"); return ErrorResult("Missing both id_token and code"); } - + idToken = await ExchangeCodeForTokenAsync(code, aud); - _logger.LogInformation("AppleGrantHandler.HandleAsync ExchangeCodeForTokenAsync code: {idToken} aud: {aud} token: {token}", code, aud, idToken); + _logger.LogInformation( + "AppleGrantHandler.HandleAsync ExchangeCodeForTokenAsync code: {idToken} aud: {aud} token: {token}", + code, aud, idToken); if (idToken.IsNullOrEmpty()) { return ErrorResult("Code invalid or expired"); } } - + var (isValid, principal) = await ValidateAppleToken(idToken, aud); if (!isValid) { @@ -83,7 +85,7 @@ public async Task HandleAsync(ExtensionGrantContext context) { user = new IdentityUser(Guid.NewGuid(), name, email: Guid.NewGuid().ToString("N") + "@ABP.IO"); await userManager.CreateAsync(user); - await userManager.SetRolesAsync(user, + await userManager.SetRolesAsync(user, [AevatarPermissions.BasicUser]); } @@ -121,12 +123,13 @@ await context.HttpContext.RequestServices.GetRequiredService GetApplePublicKeysAsync(string kid) { using var client = new HttpClient(); @@ -165,13 +168,13 @@ private async Task GetApplePublicKeysAsync(string kid) { var modulus = Base64UrlEncoder.DecodeBytes(key["n"].ToString()); var exponent = Base64UrlEncoder.DecodeBytes(key["e"].ToString()); - + var rsaParameters = new RSAParameters { Modulus = modulus, Exponent = exponent }; - + return new RsaSecurityKey(rsaParameters); } } @@ -185,7 +188,7 @@ private AppleUserInfo ExtractAppleUser(ClaimsPrincipal principal) var firstName = principal.FindFirstValue(ClaimTypes.GivenName); var lastName = principal.FindFirstValue(ClaimTypes.Surname); var sub = principal.FindFirstValue(ClaimTypes.NameIdentifier); - + if (email?.EndsWith("@privaterelay.appleid.com") == true) { email = $"{sub}@apple.privaterelay.com"; @@ -230,12 +233,12 @@ private async Task> GetResourcesAsync(ExtensionGrantContext return resources; } - + private async Task ExchangeCodeForTokenAsync(string code, string clientId) { var clientSecret = GenerateClientSecret(clientId); using var client = new HttpClient(); - + var body = new List> { new KeyValuePair("grant_type", "authorization_code"), @@ -244,9 +247,9 @@ private async Task ExchangeCodeForTokenAsync(string code, string clientI new KeyValuePair("client_id", clientId), new KeyValuePair("client_secret", clientSecret), }; - + var response = await client.PostAsync(AppleConstants.TokenEndpoint, new FormUrlEncodedContent(body)); - + if (!response.IsSuccessStatusCode) { _logger.LogError("Token exchange failed. StatusCode: {StatusCode}, Response: {ResponseBody}", @@ -254,44 +257,44 @@ private async Task ExchangeCodeForTokenAsync(string code, string clientI await response.Content.ReadAsStringAsync()); return ""; } - + var json = await response.Content.ReadAsStringAsync(); var tokenResp = JsonConvert.DeserializeObject(json); return tokenResp.IdToken; } - + private string GenerateClientSecret(string clientId) { - var key = Regex.Replace(_configuration["Apple:Pk"], @"\t|\n|\r", ""); + var key = Regex.Replace(_configuration["Apple:Pk"], @"\t|\n|\r", ""); using var algorithm = ECDsa.Create(); algorithm.ImportPkcs8PrivateKey(Convert.FromBase64String(key), out _); var now = DateTime.UtcNow; var header = new { - alg = "ES256", - kid = _configuration["Apple:KeyId"] + alg = "ES256", + kid = _configuration["Apple:KeyId"] }; - + var payload = new { - iss = _configuration["Apple:TeamId"], - iat = new DateTimeOffset(now).ToUnixTimeSeconds(), + iss = _configuration["Apple:TeamId"], + iat = new DateTimeOffset(now).ToUnixTimeSeconds(), exp = new DateTimeOffset(now.AddMinutes(30)).ToUnixTimeSeconds(), - aud = "https://appleid.apple.com", - sub = clientId + aud = "https://appleid.apple.com", + sub = clientId }; - + var encodedHeader = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header))); var encodedPayload = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload))); - + var stringToSign = $"{encodedHeader}.{encodedPayload}"; var signature = algorithm.SignData(Encoding.UTF8.GetBytes(stringToSign), HashAlgorithmName.SHA256); var encodedSignature = Base64UrlEncode(signature); - + return $"{encodedHeader}.{encodedPayload}.{encodedSignature}"; } - + private static string Base64UrlEncode(byte[] input) { return Convert.ToBase64String(input) @@ -299,20 +302,16 @@ private static string Base64UrlEncode(byte[] input) .Replace("/", "_") .TrimEnd('='); } - + public class TokenResponse { - [JsonProperty("access_token")] - public string? AccessToken { get; set; } + [JsonProperty("access_token")] public string? AccessToken { get; set; } - [JsonProperty("id_token")] - public string? IdToken { get; set; } + [JsonProperty("id_token")] public string? IdToken { get; set; } - [JsonProperty("expires_in")] - public int ExpiresIn { get; set; } + [JsonProperty("expires_in")] public int ExpiresIn { get; set; } - [JsonProperty("token_type")] - public string? TokenType { get; set; } + [JsonProperty("token_type")] public string? TokenType { get; set; } } private class AppleUserInfo diff --git a/src/Aevatar.AuthServer/ApplicationDescription.cs b/src/Aevatar.AuthServer/ApplicationDescription.cs index b9533c6d6..7ef6286a5 100644 --- a/src/Aevatar.AuthServer/ApplicationDescription.cs +++ b/src/Aevatar.AuthServer/ApplicationDescription.cs @@ -3,7 +3,7 @@ namespace Aevatar; -public class ApplicationDescription: IApplicationModelConvention +public class ApplicationDescription : IApplicationModelConvention { public ApplicationDescription() { @@ -11,6 +11,6 @@ public ApplicationDescription() public void Apply(ApplicationModel application) { - application.Controllers.RemoveAll(x=>x.ControllerType == typeof(TokenController)); + application.Controllers.RemoveAll(x => x.ControllerType == typeof(TokenController)); } } \ No newline at end of file diff --git a/src/Aevatar.AuthServer/Constants/AppleConstants.cs b/src/Aevatar.AuthServer/Constants/AppleConstants.cs index d79fd9973..37459b786 100644 --- a/src/Aevatar.AuthServer/Constants/AppleConstants.cs +++ b/src/Aevatar.AuthServer/Constants/AppleConstants.cs @@ -6,9 +6,9 @@ public static class AppleConstants public const string TokenEndpoint = AuthorityUrl + "/auth/token"; public const string JwksEndpoint = AuthorityUrl + "/auth/keys"; public const string ValidIssuer = AuthorityUrl; - + public static class Claims { public const string Kid = "kid"; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.AuthServer/Dtos/ManagerCacheDto.cs b/src/Aevatar.AuthServer/Dtos/ManagerCacheDto.cs index 265ccc5b3..adece6fe2 100644 --- a/src/Aevatar.AuthServer/Dtos/ManagerCacheDto.cs +++ b/src/Aevatar.AuthServer/Dtos/ManagerCacheDto.cs @@ -1,7 +1,7 @@ namespace Aevatar.Dtos; public class ManagerCacheDto -{ - public string CaHash { get; set; } +{ + public string CaHash { get; set; } public string CaAddress { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.AuthServer/GoogleGrantHandler.cs b/src/Aevatar.AuthServer/GoogleGrantHandler.cs index 8e5a61702..f1803c815 100644 --- a/src/Aevatar.AuthServer/GoogleGrantHandler.cs +++ b/src/Aevatar.AuthServer/GoogleGrantHandler.cs @@ -18,9 +18,9 @@ public class GoogleGrantHandler : ITokenExtensionGrant private readonly ILogger _logger; public string Name => GrantTypeConstants.GOOGLE; - + public GoogleGrantHandler( - IConfiguration configuration, + IConfiguration configuration, ILogger logger) { _configuration = configuration; @@ -31,7 +31,7 @@ public async Task HandleAsync(ExtensionGrantContext context) { var idToken = context.Request.GetParameter("id_token").ToString(); var source = context.Request.GetParameter("source")?.ToString(); - + _logger.LogInformation("GoogleGrantHandler.HandleAsync source: {source} idToken: {idToken}", source, idToken); if (string.IsNullOrEmpty(idToken)) { @@ -39,9 +39,9 @@ public async Task HandleAsync(ExtensionGrantContext context) OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, new AuthenticationProperties(new Dictionary { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = + [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = + [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Missing id_token parameter" })); } @@ -59,41 +59,41 @@ public async Task HandleAsync(ExtensionGrantContext context) { clientId = _configuration["Google:ClientId"]; } - + if (string.IsNullOrEmpty(clientId)) { _logger.LogInformation("GoogleGrantHandler.HandleAsync: clientId not found"); return new ForbidResult( OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - new AuthenticationProperties(new Dictionary + new AuthenticationProperties( + new Dictionary { [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidRequest, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = - "client Id not found" + [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "client Id not found" } ) ); } - + _logger.LogInformation("GoogleGrantHandler.HandleAsync: clientId: {clientId}", clientId); - + var payload = await ValidateGoogleTokenAsync(idToken, clientId); _logger.LogInformation("GoogleGrantHandler.HandleAsync: payload: {payload}", payload); - + if (payload == null) { return new ForbidResult( OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, new AuthenticationProperties(new Dictionary { - [OpenIddictServerAspNetCoreConstants.Properties.Error] = + [OpenIddictServerAspNetCoreConstants.Properties.Error] = OpenIddictConstants.Errors.InvalidGrant, - [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = + [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "Invalid Google token" })); } - + var email = payload.Email; _logger.LogInformation("GoogleGrantHandler.HandleAsync: email: {email}", email); var userManager = context.HttpContext.RequestServices.GetRequiredService(); @@ -107,6 +107,7 @@ public async Task HandleAsync(ExtensionGrantContext context) await userManager.SetRolesAsync(user, [AevatarPermissions.BasicUser]); } + var identityUser = await userManager.FindByNameAsync(name); var identityRoleManager = context.HttpContext.RequestServices.GetRequiredService(); var roleNames = new List(); @@ -115,13 +116,13 @@ await userManager.SetRolesAsync(user, var role = await identityRoleManager.GetByIdAsync(userRole.RoleId); roleNames.Add(role.Name); } - - + + var userClaimsPrincipalFactory = context.HttpContext.RequestServices .GetRequiredService>(); var claimsPrincipal = await userClaimsPrincipalFactory.CreateAsync(user); claimsPrincipal.SetClaim(OpenIddictConstants.Claims.Subject, user.Id.ToString()); - claimsPrincipal.SetClaim(OpenIddictConstants.Claims.Role, string.Join(",",roleNames)); + claimsPrincipal.SetClaim(OpenIddictConstants.Claims.Role, string.Join(",", roleNames)); claimsPrincipal.SetScopes(context.Request.GetScopes()); claimsPrincipal.SetResources(await GetResourcesAsync(context, claimsPrincipal.GetScopes())); claimsPrincipal.SetAudiences("Aevatar"); @@ -147,8 +148,8 @@ await context.HttpContext.RequestServices.GetRequiredService> GetResourcesAsync(ExtensionGrantContext context, ImmutableArray scopes) { diff --git a/src/Aevatar.AuthServer/ManagerCheckHelper.cs b/src/Aevatar.AuthServer/ManagerCheckHelper.cs index 06cbc2878..8148c222c 100644 --- a/src/Aevatar.AuthServer/ManagerCheckHelper.cs +++ b/src/Aevatar.AuthServer/ManagerCheckHelper.cs @@ -16,7 +16,8 @@ public class ManagerCheckHelper var response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); - return !content.IsNullOrEmpty() && caHash.Equals(JsonConvert.DeserializeObject(content)?.CaHash); + return !content.IsNullOrEmpty() && + caHash.Equals(JsonConvert.DeserializeObject(content)?.CaHash); } catch (Exception e) { diff --git a/src/Aevatar.AuthServer/Program.cs b/src/Aevatar.AuthServer/Program.cs index e15461b20..869f5df11 100644 --- a/src/Aevatar.AuthServer/Program.cs +++ b/src/Aevatar.AuthServer/Program.cs @@ -32,15 +32,12 @@ public async static Task Main(string[] args) // builder.Configuration.AddJsonFile("apollo.appsettings.json"); builder.Host.AddAppSettingsSecretsJson() .UseAutofac() - // .UseApollo() .UseSerilog() - // .UseOrleansClient() ; await builder.AddApplicationAsync(); var app = builder.Build(); await app.InitializeApplicationAsync(); await app.RunAsync(); - //CreateHostBuilder(args).Build().Run(); return 0; } catch (Exception ex) @@ -58,6 +55,7 @@ public async static Task Main(string[] args) Log.CloseAndFlush(); } } + private static IHostBuilder CreateHostBuilder(string[] args) { return Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) @@ -66,4 +64,4 @@ private static IHostBuilder CreateHostBuilder(string[] args) //.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) .UseSerilog(); } -} +} \ No newline at end of file diff --git a/src/Aevatar.AuthServer/Provider/IWalletLoginProvider.cs b/src/Aevatar.AuthServer/Provider/IWalletLoginProvider.cs index b50b2723b..d0a502597 100644 --- a/src/Aevatar.AuthServer/Provider/IWalletLoginProvider.cs +++ b/src/Aevatar.AuthServer/Provider/IWalletLoginProvider.cs @@ -2,9 +2,11 @@ namespace Aevatar.Provider; public interface IWalletLoginProvider { - List CheckParams(string publicKeyVal, string signatureVal, string chainId, + List CheckParams(string publicKeyVal, string signatureVal, string chainId, string timestamp); + string GetErrorMessage(List errors); - Task VerifySignatureAndParseWalletAddressAsync(string publicKeyVal, string signatureVal, string timestampVal, - string caHash, string chainId); + + Task VerifySignatureAndParseWalletAddressAsync(string publicKeyVal, string signatureVal, + string timestampVal, string caHash, string chainId); } \ No newline at end of file diff --git a/src/Aevatar.AuthServer/Provider/UserInformationProvider.cs b/src/Aevatar.AuthServer/Provider/UserInformationProvider.cs index 3184aa610..63975e797 100644 --- a/src/Aevatar.AuthServer/Provider/UserInformationProvider.cs +++ b/src/Aevatar.AuthServer/Provider/UserInformationProvider.cs @@ -5,15 +5,15 @@ namespace Aevatar.Provider; -public class UserInformationProvider: IUserInformationProvider, ISingletonDependency +public class UserInformationProvider : IUserInformationProvider, ISingletonDependency { private readonly ILogger _logger; private readonly IRepository _userExtensionRepository; private readonly IObjectMapper _objectMapper; - + public UserInformationProvider(IRepository userExtensionRepository, - IObjectMapper objectMapper,ILogger logger) + IObjectMapper objectMapper, ILogger logger) { _userExtensionRepository = userExtensionRepository; _objectMapper = objectMapper; @@ -46,7 +46,8 @@ public async Task GetUserExtensionInfoByIdAsync(Guid userId) { return new UserExtensionDto(); } - return _objectMapper.Map(userExtension); + + return _objectMapper.Map(userExtension); } public async Task GetUserExtensionInfoByWalletAddressAsync(string address) diff --git a/src/Aevatar.AuthServer/Provider/WalletLoginProvider.cs b/src/Aevatar.AuthServer/Provider/WalletLoginProvider.cs index 843a0cc91..1e3c6ecec 100644 --- a/src/Aevatar.AuthServer/Provider/WalletLoginProvider.cs +++ b/src/Aevatar.AuthServer/Provider/WalletLoginProvider.cs @@ -18,14 +18,15 @@ namespace Aevatar.Provider; -public class WalletLoginProvider: IWalletLoginProvider, ISingletonDependency +public class WalletLoginProvider : IWalletLoginProvider, ISingletonDependency { private readonly ILogger _logger; private readonly SignatureGrantOptions _signatureGrantOptions; private readonly ChainOptions _chainOptions; - + private const string GetHolderInfoMethodName = "GetHolderInfo"; private const string Nonce = "Nonce:"; + public WalletLoginProvider(ILogger logger, IOptionsMonitor signatureOptions, IOptionsMonitor chainOptions) { @@ -34,7 +35,7 @@ public WalletLoginProvider(ILogger logger, _chainOptions = chainOptions.CurrentValue; } - public List CheckParams(string publicKeyVal, string signatureVal, string chainId, + public List CheckParams(string publicKeyVal, string signatureVal, string chainId, string plainText) { var errors = new List(); @@ -62,11 +63,11 @@ public List CheckParams(string publicKeyVal, string signatureVal, string } public async Task VerifySignatureAndParseWalletAddressAsync(string publicKeyVal, string signatureVal, - string plainText, string caHash, string chainId) + string plainText, string caHash, string chainId) { var rawText = Encoding.UTF8.GetString(ByteArrayHelper.HexStringToByteArray(plainText)); _logger.LogInformation("rawText:{rawText}", rawText); - var timestampVal = rawText.TrimEnd().Substring(rawText.LastIndexOf(Nonce) + Nonce.Length); + var timestampVal = rawText.TrimEnd().Substring(rawText.LastIndexOf(Nonce) + Nonce.Length); var timestamp = long.Parse(timestampVal); _logger.LogInformation("timestamp:{timestamp}", timestamp); //Validate timestamp validity period @@ -107,10 +108,11 @@ public async Task VerifySignatureAndParseWalletAddressAsync(string publi var caAddress = addressInfos[0].Address; return caAddress; } + return signAddress; } - private string VerifySignature( string plainText, string signatureVal,string publicKeyVal) + private string VerifySignature(string plainText, string signatureVal, string publicKeyVal) { var signature = ByteArrayHelper.HexStringToByteArray(signatureVal); var hash = Encoding.UTF8.GetBytes(plainText).ComputeHash(); @@ -119,7 +121,7 @@ private string VerifySignature( string plainText, string signatureVal,string pub { throw new UserFriendlyException("Signature validation failed new."); } - + //Since it is not possible to determine whether the CA wallet manager address is in managerPublicKey or in managerPublicKeyOld //therefore, the accurate manager address is obtained from publicKeyVal. var signAddress = Address.FromPublicKey(publicKey).ToBase58(); @@ -152,8 +154,8 @@ public bool IsTimeStampOutRange(long timestamp, out int timeRange) return false; } - - + + private async Task CheckManagerAddressAsync(string chainId, string caHash, string manager) { string graphQlUrl = _signatureGrantOptions.PortkeyV2GraphQLUrl; @@ -161,17 +163,20 @@ public bool IsTimeStampOutRange(long timestamp, out int timeRange) if (!graphQlResult.HasValue || !graphQlResult.Value) { _logger.LogDebug("graphql is invalid."); - var contractResult = await CheckManagerAddressFromContractAsync(chainId, caHash, manager, _chainOptions); + var contractResult = await CheckManagerAddressFromContractAsync(chainId, caHash, manager, _chainOptions); if (!contractResult.HasValue || !contractResult.Value) { _logger.LogDebug("contract is invalid."); - return await ManagerCheckHelper.CheckManagerFromCache(_signatureGrantOptions.CheckManagerUrl, manager, caHash); + return await ManagerCheckHelper.CheckManagerFromCache(_signatureGrantOptions.CheckManagerUrl, manager, + caHash); } + return true; } + return true; } - + private async Task CheckManagerAddressFromContractAsync(string chainId, string caHash, string manager, ChainOptions chainOptions) { @@ -182,12 +187,12 @@ public bool IsTimeStampOutRange(long timestamp, out int timeRange) }; var output = - await CallTransactionAsync(chainId, GetHolderInfoMethodName, param, + await CallTransactionAsync(chainId, GetHolderInfoMethodName, param, chainOptions); return output?.ManagerInfos?.Any(t => t.Address.ToBase58() == manager); } - + private async Task CheckManagerAddressFromGraphQlAsync(string url, string caHash, string managerAddress) { @@ -197,7 +202,7 @@ await CallTransactionAsync(chainId, GetHolderInfoMethodName var caHolderManagerInfos = loginChainHolderInfo?.ManagerInfos; return caHolderManagerInfos?.Any(t => t.Address == managerAddress); } - + private async Task CallTransactionAsync(string chainId, string methodName, IMessage param, ChainOptions chainOptions) where T : class, IMessage, new() { @@ -232,7 +237,7 @@ await client.GenerateTransactionAsync(address, contractAddress, return null; } } - + private async Task GetHolderInfosAsync(string url, string caHash) { using var graphQlClient = new GraphQLHttpClient(url, new NewtonsoftJsonSerializer()); @@ -245,14 +250,16 @@ private async Task GetHolderInfosAsync(string url, string }", Variables = new { - caHash, skipCount = 0, maxResultCount = 10 + caHash, + skipCount = 0, + maxResultCount = 10 } }; var graphQlResponse = await graphQlClient.SendQueryAsync(request); return graphQlResponse.Data; } - + private async Task> GetAddressInfosAsync(string caHash) { var addressInfos = new List(); @@ -286,7 +293,7 @@ private async Task> GetAddressInfosAsync(string caHash return addressInfos; } - + private async Task GetAddressInfoFromContractAsync(string chainId, string caHash) { var param = new GetHolderInfoInput @@ -295,7 +302,7 @@ private async Task GetAddressInfoFromContractAsync(string c LoginGuardianIdentifierHash = Hash.Empty }; - var output = await CallTransactionAsync(chainId, GetHolderInfoMethodName, param, + var output = await CallTransactionAsync(chainId, GetHolderInfoMethodName, param, _chainOptions); return new UserChainAddressDto() diff --git a/src/Aevatar.AuthServer/SignatureGrantHandler.cs b/src/Aevatar.AuthServer/SignatureGrantHandler.cs index 7b61e5704..e08f11404 100644 --- a/src/Aevatar.AuthServer/SignatureGrantHandler.cs +++ b/src/Aevatar.AuthServer/SignatureGrantHandler.cs @@ -46,7 +46,7 @@ public async Task HandleAsync(ExtensionGrantContext context) }!)); } - string walletAddress = string.Empty; + var walletAddress = string.Empty; try { walletAddress = await _walletLoginProvider.VerifySignatureAndParseWalletAddressAsync(publicKeyVal, diff --git a/src/Aevatar.CQRS/AevatarStateProjector.cs b/src/Aevatar.CQRS/AevatarStateProjector.cs index bdfe5a7e0..732bb6003 100644 --- a/src/Aevatar.CQRS/AevatarStateProjector.cs +++ b/src/Aevatar.CQRS/AevatarStateProjector.cs @@ -34,7 +34,8 @@ public AevatarStateProjector( _logger = logger; _batchOptions = options.Value; // Initialize timer - int timerPeriodMs = Math.Max(_batchOptions.FlushMinPeriodInMs, (int)(_batchOptions.BatchTimeoutSeconds * _batchOptions.FlushMinPeriodInMs / 2)); + int timerPeriodMs = Math.Max(_batchOptions.FlushMinPeriodInMs, + (int)(_batchOptions.BatchTimeoutSeconds * _batchOptions.FlushMinPeriodInMs / 2)); _flushTimer = new System.Threading.Timer(FlushTimerCallback, null, timerPeriodMs, timerPeriodMs); } @@ -57,9 +58,9 @@ public Task ProjectAsync(T state) where T : StateWrapperBase GrainId grainId = wrapper.GrainId; StateBase wrapperState = wrapper.State; int version = wrapper.Version; - + _logger.LogDebug("AevatarStateProjector GrainId {GrainId} Version {Version}", grainId.ToString(), version); - + var command = new SaveStateCommand { Id = grainId.ToString(), @@ -77,9 +78,9 @@ public Task ProjectAsync(T state) where T : StateWrapperBase ); // 检查是否需要执行刷新操作 - var shouldFlush = _latestCommands.Count >= _batchOptions.BatchSize || + var shouldFlush = _latestCommands.Count >= _batchOptions.BatchSize || (DateTime.UtcNow - _lastFlushTime).TotalSeconds >= _batchOptions.BatchTimeoutSeconds; - + if (shouldFlush && Interlocked.CompareExchange(ref _isProcessing, 1, 0) == 0) { // 非阻塞方式执行刷新 @@ -126,7 +127,7 @@ public async Task FlushAsync(CancellationToken cancellationToken = default) { // 计算批处理大小 int effectiveBatchSize = CalculateEffectiveBatchSize(); - + // 获取批处理数据 var currentBatch = _latestCommands.Values .OrderByDescending(c => c.Version) @@ -136,11 +137,11 @@ public async Task FlushAsync(CancellationToken cancellationToken = default) if (currentBatch.Count > 0) { - _logger.LogInformation("Processing batch: {BatchSize} commands (total pending: {TotalCount})", + _logger.LogInformation("Processing batch: {BatchSize} commands (total pending: {TotalCount})", currentBatch.Count, _latestCommands.Count); - + await SendBatchAsync(currentBatch, cancellationToken); - + // 处理完成后移除已处理的命令 foreach (var cmd in currentBatch) { @@ -163,19 +164,19 @@ private int CalculateEffectiveBatchSize() { // 默认使用配置的批大小 int size = _batchOptions.BatchSize; - + // 如果队列较大,增加批大小以加快处理 if (_latestCommands.Count > _batchOptions.BatchSize * 5) { size = Math.Min(_batchOptions.BatchSize * 2, _batchOptions.MaxBatchSize); } - + // 检查内存压力 if (GC.GetTotalMemory(false) > _batchOptions.HighMemoryThreshold) { size = Math.Max(_batchOptions.MinBatchSize, size / 2); } - + return size; } @@ -198,23 +199,23 @@ private async Task SendBatchAsync(List batch, CancellationToke { Commands = batch }; - + await _mediator.Send(batchCommand, cancellationToken); return; // 成功发送后直接返回 } catch (Exception ex) { retryCount++; - + if (retryCount >= _batchOptions.MaxRetryCount) { _logger.LogError(ex, "Failed to process batch after {RetryCount} attempts", retryCount); throw; // 达到最大重试次数,向上抛出异常 } - - _logger.LogWarning(ex, "Error processing batch, will retry ({RetryCount}/{MaxRetries})", + + _logger.LogWarning(ex, "Error processing batch, will retry ({RetryCount}/{MaxRetries})", retryCount, _batchOptions.MaxRetryCount); - + // 指数退避策略 int delayMs = (int)(_batchOptions.RetryBaseDelaySeconds * 1000 * Math.Pow(2, retryCount - 1)); await Task.Delay(delayMs, cancellationToken); @@ -226,7 +227,7 @@ public void Dispose() { if (_disposed) return; _disposed = true; - + // 尝试执行最后一次刷新 if (_latestCommands.Count > 0 && Interlocked.CompareExchange(ref _isProcessing, 1, 0) == 0) { @@ -239,7 +240,7 @@ public void Dispose() _logger.LogError(ex, "Error during final flush on dispose"); } } - + _shutdownCts.Cancel(); _shutdownCts.Dispose(); _flushTimer?.Dispose(); diff --git a/src/Aevatar.CQRS/ElasticIndexingService.cs b/src/Aevatar.CQRS/ElasticIndexingService.cs index eecc143c4..b2f62b804 100644 --- a/src/Aevatar.CQRS/ElasticIndexingService.cs +++ b/src/Aevatar.CQRS/ElasticIndexingService.cs @@ -99,7 +99,7 @@ private async Task CreateIndexAsync(string indexName) wh if (propType == typeof(string)) { props.Text(propertyName); - // props.Keyword(propertyName, k => k.IgnoreAbove(256)); + // props.Keyword(propertyName, k => k.IgnoreAbove(256)); } else if (propType == typeof(short) || propType == typeof(int) || propType == typeof(long)) { @@ -196,7 +196,8 @@ public async Task SaveOrUpdateStateIndexBatchAsync(IEnumerable Index = indexName, Script = new Script { - Source = "if (ctx.op == 'create' || ctx._source.version == null || params.version > ctx._source.version) { ctx._source = params.doc; } else { ctx.op = 'noop'; }", + Source = + "if (ctx.op == 'create' || ctx._source.version == null || params.version > ctx._source.version) { ctx._source = params.doc; } else { ctx.op = 'noop'; }", Params = new Dictionary { ["version"] = document["version"], diff --git a/src/Aevatar.CQRS/ElasticIndexingServiceExtensions.cs b/src/Aevatar.CQRS/ElasticIndexingServiceExtensions.cs index b38069e82..f64801dc4 100644 --- a/src/Aevatar.CQRS/ElasticIndexingServiceExtensions.cs +++ b/src/Aevatar.CQRS/ElasticIndexingServiceExtensions.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Logging; using System; using System.Linq; -using System.Threading.Tasks; using Aevatar.CQRS; namespace Aevatar; @@ -38,4 +37,4 @@ public static IServiceCollection UseElasticIndexingWithMetrics(this IServiceColl )); return services; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.CQRS/MetricsElasticIndexingService.cs b/src/Aevatar.CQRS/MetricsElasticIndexingService.cs index 6530e73a2..6a640b711 100644 --- a/src/Aevatar.CQRS/MetricsElasticIndexingService.cs +++ b/src/Aevatar.CQRS/MetricsElasticIndexingService.cs @@ -21,12 +21,12 @@ public class MetricsElasticIndexingService : IIndexingService private readonly IIndexingService _inner; private readonly ILogger _logger; private readonly ActivitySource _activitySource; - + // Metrics for SaveOrUpdateStateIndexBatchAsync private readonly Histogram _bulkDurationHistogram; private readonly Counter _bulkSuccessCounter; private readonly Counter _bulkFailCounter; - + // Metrics for CheckExistOrCreateStateIndex private readonly Histogram _checkOrCreateDurationHistogram; private readonly Counter _checkOrCreateSuccessCounter; @@ -48,22 +48,34 @@ public MetricsElasticIndexingService(IIndexingService inner, ILogger("es.bulk.duration", "ms", "ElasticSearch bulk operation duration"); - _bulkSuccessCounter = meter.CreateCounter("es.bulk.success", "count", "ElasticSearch bulk operations succeeded"); - _bulkFailCounter = meter.CreateCounter("es.bulk.failure", "count", "ElasticSearch bulk operations failed"); - _checkOrCreateDurationHistogram = meter.CreateHistogram("es.check_create.duration", "ms", "ElasticSearch check or create index operation duration"); - _checkOrCreateSuccessCounter = meter.CreateCounter("es.check_create.success", "count", "ElasticSearch check or create index operations succeeded"); - _checkOrCreateFailCounter = meter.CreateCounter("es.check_create.failure", "count", "ElasticSearch check or create index operations failed"); + _bulkDurationHistogram = + meter.CreateHistogram("es.bulk.duration", "ms", "ElasticSearch bulk operation duration"); + _bulkSuccessCounter = + meter.CreateCounter("es.bulk.success", "count", "ElasticSearch bulk operations succeeded"); + _bulkFailCounter = + meter.CreateCounter("es.bulk.failure", "count", "ElasticSearch bulk operations failed"); + + _checkOrCreateDurationHistogram = meter.CreateHistogram("es.check_create.duration", "ms", + "ElasticSearch check or create index operation duration"); + _checkOrCreateSuccessCounter = meter.CreateCounter("es.check_create.success", "count", + "ElasticSearch check or create index operations succeeded"); + _checkOrCreateFailCounter = meter.CreateCounter("es.check_create.failure", "count", + "ElasticSearch check or create index operations failed"); - _getDocumentsDurationHistogram = meter.CreateHistogram("es.get_documents.duration", "ms", "ElasticSearch get documents operation duration"); - _getDocumentsSuccessCounter = meter.CreateCounter("es.get_documents.success", "count", "ElasticSearch get documents operations succeeded"); - _getDocumentsFailCounter = meter.CreateCounter("es.get_documents.failure", "count", "ElasticSearch get documents operations failed"); + _getDocumentsDurationHistogram = meter.CreateHistogram("es.get_documents.duration", "ms", + "ElasticSearch get documents operation duration"); + _getDocumentsSuccessCounter = meter.CreateCounter("es.get_documents.success", "count", + "ElasticSearch get documents operations succeeded"); + _getDocumentsFailCounter = meter.CreateCounter("es.get_documents.failure", "count", + "ElasticSearch get documents operations failed"); - _queryLuceneDurationHistogram = meter.CreateHistogram("es.query_lucene.duration", "ms", "ElasticSearch Lucene query operation duration"); - _queryLuceneSuccessCounter = meter.CreateCounter("es.query_lucene.success", "count", "ElasticSearch Lucene query operations succeeded"); - _queryLuceneFailCounter = meter.CreateCounter("es.query_lucene.failure", "count", "ElasticSearch Lucene query operations failed"); + _queryLuceneDurationHistogram = meter.CreateHistogram("es.query_lucene.duration", "ms", + "ElasticSearch Lucene query operation duration"); + _queryLuceneSuccessCounter = meter.CreateCounter("es.query_lucene.success", "count", + "ElasticSearch Lucene query operations succeeded"); + _queryLuceneFailCounter = meter.CreateCounter("es.query_lucene.failure", "count", + "ElasticSearch Lucene query operations failed"); } public async Task SaveOrUpdateStateIndexBatchAsync(IEnumerable commands) @@ -77,7 +89,8 @@ public async Task SaveOrUpdateStateIndexBatchAsync(IEnumerable _bulkSuccessCounter.Add(1); _bulkDurationHistogram.Record(stopwatch.ElapsedMilliseconds); activity?.SetTag("es.bulk.success", 1); - _logger.LogInformation("[ES-Bulk] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, activity?.SpanId); + _logger.LogInformation("[ES-Bulk] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, + activity?.SpanId); } catch (Exception ex) { @@ -85,7 +98,8 @@ public async Task SaveOrUpdateStateIndexBatchAsync(IEnumerable _bulkFailCounter.Add(1); activity?.SetTag("exception", true); activity?.SetTag("exception.message", ex.Message); - _logger.LogError(ex, "[ES-Bulk-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, activity?.SpanId); + _logger.LogError(ex, "[ES-Bulk-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, + activity?.SpanId); throw; } finally @@ -105,7 +119,8 @@ public async Task CheckExistOrCreateStateIndex(T stateBase) where T : StateBa _checkOrCreateDurationHistogram.Record(stopwatch.Elapsed.TotalMilliseconds); _checkOrCreateSuccessCounter.Add(1); activity?.SetTag("es.check_create.success", 1); - _logger.LogInformation("[ES-CheckOrCreate] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, activity?.SpanId); + _logger.LogInformation("[ES-CheckOrCreate] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, + activity?.SpanId); } catch (Exception ex) { @@ -114,7 +129,8 @@ public async Task CheckExistOrCreateStateIndex(T stateBase) where T : StateBa _checkOrCreateFailCounter.Add(1); activity?.SetTag("exception", true); activity?.SetTag("exception.message", ex.Message); - _logger.LogError(ex, "[ES-CheckOrCreate-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, activity?.SpanId); + _logger.LogError(ex, "[ES-CheckOrCreate-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, + activity?.SpanId); throw; } finally @@ -123,7 +139,8 @@ public async Task CheckExistOrCreateStateIndex(T stateBase) where T : StateBa } } - public async Task GetStateIndexDocumentsAsync(string stateName, Action> query, int skip = 0, int limit = 1000) + public async Task GetStateIndexDocumentsAsync(string stateName, Action> query, + int skip = 0, int limit = 1000) { using var activity = _activitySource.StartActivity("GetStateIndexDocumentsAsync", ActivityKind.Client); var stopwatch = Stopwatch.StartNew(); @@ -134,7 +151,8 @@ public async Task GetStateIndexDocumentsAsync(string stateName, Action GetStateIndexDocumentsAsync(string stateName, Action>> QueryWithLuceneAsy _queryLuceneDurationHistogram.Record(stopwatch.Elapsed.TotalMilliseconds); _queryLuceneSuccessCounter.Add(1); activity?.SetTag("es.query_lucene.success", 1); - _logger.LogInformation("[ES-LuceneQuery] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, activity?.SpanId); + _logger.LogInformation("[ES-LuceneQuery] traceId:{traceId} spanId:{spanId} success", activity?.TraceId, + activity?.SpanId); return result; } catch (Exception ex) @@ -174,7 +194,8 @@ public async Task>> QueryWithLuceneAsy _queryLuceneFailCounter.Add(1); activity?.SetTag("exception", true); activity?.SetTag("exception.message", ex.Message); - _logger.LogError(ex, "[ES-LuceneQuery-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, activity?.SpanId); + _logger.LogError(ex, "[ES-LuceneQuery-Error] traceId:{traceId} spanId:{spanId}", activity?.TraceId, + activity?.SpanId); throw; } finally @@ -182,4 +203,4 @@ public async Task>> QueryWithLuceneAsy activity?.SetTag("es.query_lucene.elapsedMs", stopwatch.ElapsedMilliseconds); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.CQRS/Options/ProjectorBatchOptions.cs b/src/Aevatar.CQRS/Options/ProjectorBatchOptions.cs index 907153b92..f328ed2eb 100644 --- a/src/Aevatar.CQRS/Options/ProjectorBatchOptions.cs +++ b/src/Aevatar.CQRS/Options/ProjectorBatchOptions.cs @@ -6,37 +6,37 @@ public class ProjectorBatchOptions /// 默认批处理大小 /// public int BatchSize { get; set; } = 15; - + /// /// 批处理超时时间(秒) /// public int BatchTimeoutSeconds { get; set; } = 1; - + /// /// 最大批处理大小(当队列积压时可用) /// public int MaxBatchSize { get; set; } = 100; - + /// /// 最小批处理大小(即使在内存压力大时也保证的处理数量) /// public int MinBatchSize { get; set; } = 5; - + /// /// 高内存水位线,超过此值时将减小批大小(字节) /// public long HighMemoryThreshold { get; set; } = 1024 * 1024 * 1024; // 1GB - + /// /// 最大重试次数 /// public int MaxRetryCount { get; set; } = 3; - + /// /// 重试基础延迟(秒) /// public int RetryBaseDelaySeconds { get; set; } = 2; - + /// /// 最大重试延迟(秒) /// diff --git a/src/Aevatar.DbMigrator/DbMigratorHostedService.cs b/src/Aevatar.DbMigrator/DbMigratorHostedService.cs index 1d48ef623..f80462a97 100644 --- a/src/Aevatar.DbMigrator/DbMigratorHostedService.cs +++ b/src/Aevatar.DbMigrator/DbMigratorHostedService.cs @@ -25,30 +25,28 @@ public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime, public async Task StartAsync(CancellationToken cancellationToken) { - using (var application = await AbpApplicationFactory.CreateAsync(options => - { + using var application = await AbpApplicationFactory.CreateAsync(options => + { options.Services.AddSingleton(); options.Services.ReplaceConfiguration(_configuration); options.UseAutofac(); options.Services.AddLogging(c => c.AddSerilog()); options.AddDataMigrationEnvironment(); - })) - { - await application.InitializeAsync(); + }); + await application.InitializeAsync(); - await application - .ServiceProvider - .GetRequiredService() - .MigrateAsync(); + await application + .ServiceProvider + .GetRequiredService() + .MigrateAsync(); - await application.ShutdownAsync(); + await application.ShutdownAsync(); - _hostApplicationLifetime.StopApplication(); - } + _hostApplicationLifetime.StopApplication(); } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/AevatarGlobalFeatureConfigurator.cs b/src/Aevatar.Domain.Shared/AevatarGlobalFeatureConfigurator.cs index 7bc207d13..155639116 100644 --- a/src/Aevatar.Domain.Shared/AevatarGlobalFeatureConfigurator.cs +++ b/src/Aevatar.Domain.Shared/AevatarGlobalFeatureConfigurator.cs @@ -8,15 +8,6 @@ public static class AevatarGlobalFeatureConfigurator public static void Configure() { - OneTimeRunner.Run(() => - { - /* You can configure (enable/disable) global features of the used modules here. - * - * YOU CAN SAFELY DELETE THIS CLASS AND REMOVE ITS USAGES IF YOU DON'T NEED TO IT! - * - * Please refer to the documentation to lear more about the Global Features System: - * https://docs.abp.io/en/abp/latest/Global-Features - */ - }); + OneTimeRunner.Run(() => { }); } -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Creator/CreatorGAgentState.cs b/src/Aevatar.Domain.Shared/Agents/Creator/CreatorGAgentState.cs index bacb835f3..fc222f89b 100644 --- a/src/Aevatar.Domain.Shared/Agents/Creator/CreatorGAgentState.cs +++ b/src/Aevatar.Domain.Shared/Agents/Creator/CreatorGAgentState.cs @@ -17,13 +17,12 @@ public class CreatorGAgentState : GroupAgentState [Id(5)] public string Properties { get; set; } [Id(6)] public GrainId BusinessAgentGrainId { get; set; } [Id(7)] public List EventInfoList { get; set; } = new(); - [Id(8)] public DateTime CreateTime { get; set; } + [Id(8)] public DateTime CreateTime { get; set; } } - [GenerateSerializer] public class EventDescription { [Id(0)] public Type EventType { get; set; } [Id(1)] public string Description { get; set; } -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/CreatorAgentGEvent.cs b/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/CreatorAgentGEvent.cs index d1782dda2..22a47a73c 100644 --- a/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/CreatorAgentGEvent.cs +++ b/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/CreatorAgentGEvent.cs @@ -2,7 +2,4 @@ namespace Aevatar.Agents.Creator.GEvents; -public class CreatorAgentGEvent : StateLogEventBase -{ - -} \ No newline at end of file +public class CreatorAgentGEvent : StateLogEventBase; \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/DeleteAgentGEvent.cs b/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/DeleteAgentGEvent.cs index a357d1367..6057c4772 100644 --- a/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/DeleteAgentGEvent.cs +++ b/src/Aevatar.Domain.Shared/Agents/Creator/GEvents/DeleteAgentGEvent.cs @@ -1,6 +1,3 @@ namespace Aevatar.Agents.Creator.GEvents; -public class DeleteAgentGEvent : CreatorAgentGEvent -{ - -} \ No newline at end of file +public class DeleteAgentGEvent : CreatorAgentGEvent; \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Group/GroupAgentState.cs b/src/Aevatar.Domain.Shared/Agents/Group/GroupAgentState.cs index fd64bec8e..408744139 100644 --- a/src/Aevatar.Domain.Shared/Agents/Group/GroupAgentState.cs +++ b/src/Aevatar.Domain.Shared/Agents/Group/GroupAgentState.cs @@ -6,5 +6,5 @@ namespace Aevatar.Agents.Group; [GenerateSerializer] public class GroupAgentState : StateBase { - [Id(0)] public int RegisteredAgents { get; set; } = 0; + [Id(0)] public int RegisteredAgents { get; set; } = 0; } \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Group/GroupGEvent.cs b/src/Aevatar.Domain.Shared/Agents/Group/GroupGEvent.cs index 9dc7ff956..45fc6ad59 100644 --- a/src/Aevatar.Domain.Shared/Agents/Group/GroupGEvent.cs +++ b/src/Aevatar.Domain.Shared/Agents/Group/GroupGEvent.cs @@ -2,7 +2,4 @@ namespace Aevatar.Agents.Group; -public class GroupGEvent : StateLogEventBase -{ - -} \ No newline at end of file +public class GroupGEvent : StateLogEventBase; \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Agents/Publisher/PublishingGEvent.cs b/src/Aevatar.Domain.Shared/Agents/Publisher/PublishingGEvent.cs index ad9a7c888..a26e8e2ec 100644 --- a/src/Aevatar.Domain.Shared/Agents/Publisher/PublishingGEvent.cs +++ b/src/Aevatar.Domain.Shared/Agents/Publisher/PublishingGEvent.cs @@ -2,7 +2,4 @@ namespace Aevatar.Agents.Publisher; -public class PublishingGEvent : StateLogEventBase -{ - -} \ No newline at end of file +public class PublishingGEvent : StateLogEventBase; \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Code/GEvents/CodeAgentGEvent.cs b/src/Aevatar.Domain.Shared/Code/GEvents/CodeAgentGEvent.cs index 20c08b06f..5faa1c36a 100644 --- a/src/Aevatar.Domain.Shared/Code/GEvents/CodeAgentGEvent.cs +++ b/src/Aevatar.Domain.Shared/Code/GEvents/CodeAgentGEvent.cs @@ -3,8 +3,9 @@ using Orleans; namespace Aevatar.Code.GEvents; + [GenerateSerializer] public class CodeAgentGEvent : StateLogEventBase { - [Id(0)] public override Guid Id { get; set; } = Guid.NewGuid(); + [Id(0)] public override Guid Id { get; set; } = Guid.NewGuid(); } \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Dapr/CommonConstants.cs b/src/Aevatar.Domain.Shared/Dapr/CommonConstants.cs index 0e13d8317..0400fc8b9 100644 --- a/src/Aevatar.Domain.Shared/Dapr/CommonConstants.cs +++ b/src/Aevatar.Domain.Shared/Dapr/CommonConstants.cs @@ -9,11 +9,10 @@ public static class CommonConstants public const string TwitterTopic = "Twitter"; public const string TelegramTopic = "Telegram"; public const string GptTopic = "Gpt"; - + public const string CommonTopic = "CommonTopic"; - + public const string StreamNamespace = "AINamespace"; public const string StreamProvider = "Aevatar"; public static Guid StreamGuid = Guid.NewGuid(); - } \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Options/HostDeployOptions.cs b/src/Aevatar.Domain.Shared/Options/HostDeployOptions.cs index 664ed582d..2973136f5 100644 --- a/src/Aevatar.Domain.Shared/Options/HostDeployOptions.cs +++ b/src/Aevatar.Domain.Shared/Options/HostDeployOptions.cs @@ -3,9 +3,8 @@ namespace Aevatar.Options; public class HostDeployOptions { public string HostSiloImageName { get; set; } - + public string HostClientImageName { get; set; } - + public string DockerImagePrefix { get; set; } - } \ No newline at end of file diff --git a/src/Aevatar.Domain.Shared/Util/AESCipher.cs b/src/Aevatar.Domain.Shared/Util/AESCipher.cs index c075e5612..617e18528 100644 --- a/src/Aevatar.Domain.Shared/Util/AESCipher.cs +++ b/src/Aevatar.Domain.Shared/Util/AESCipher.cs @@ -11,32 +11,29 @@ public class AESCipher public AESCipher(string password) { - this.salt = GenerateRandomSalt(); + salt = GenerateRandomSalt(); this.password = password; } private byte[] GenerateRandomSalt() { byte[] salt = new byte[16]; // 128 bits - using (var rng = RandomNumberGenerator.Create()) - { - rng.GetBytes(salt); - } + using var rng = RandomNumberGenerator.Create(); + rng.GetBytes(salt); + return salt; } private byte[] CreateKeyFromPassword() { - using (var kdf = new Rfc2898DeriveBytes(password, salt, 100000)) // 100,000 iterations - { - return kdf.GetBytes(32); // AES-256 requires a 32-byte key - } + using var kdf = new Rfc2898DeriveBytes(password, salt, 100000); + return kdf.GetBytes(32); // AES-256 requires a 32-byte key } public string Encrypt(string plainText) { byte[] key = CreateKeyFromPassword(); - + using (var aes = Aes.Create()) { aes.Key = key; @@ -46,13 +43,14 @@ public string Encrypt(string plainText) using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV)) using (var ms = new MemoryStream()) { - ms.Write(salt, 0, salt.Length); + ms.Write(salt, 0, salt.Length); ms.Write(aes.IV, 0, aes.IV.Length); using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) using (var sw = new StreamWriter(cs)) { sw.Write(plainText); } + return Convert.ToBase64String(ms.ToArray()); } } @@ -65,24 +63,20 @@ public string Decrypt(string cipherText) Array.Copy(fullCipher, 0, salt, 0, salt.Length); // 提取盐值 byte[] key = CreateKeyFromPassword(); - using (var aes = Aes.Create()) - { - aes.Key = key; - aes.Mode = CipherMode.CBC; + using var aes = Aes.Create(); + aes.Key = key; + aes.Mode = CipherMode.CBC; - byte[] iv = new byte[aes.IV.Length]; - Array.Copy(fullCipher, salt.Length, iv, 0, iv.Length); + byte[] iv = new byte[aes.IV.Length]; + Array.Copy(fullCipher, salt.Length, iv, 0, iv.Length); - var cipher = new byte[fullCipher.Length - salt.Length - iv.Length]; - Array.Copy(fullCipher, salt.Length + iv.Length, cipher, 0, cipher.Length); + var cipher = new byte[fullCipher.Length - salt.Length - iv.Length]; + Array.Copy(fullCipher, salt.Length + iv.Length, cipher, 0, cipher.Length); - using (var decryptor = aes.CreateDecryptor(aes.Key, iv)) - using (var ms = new MemoryStream(cipher)) - using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) - using (var sr = new StreamReader(cs)) - { - return sr.ReadToEnd(); - } - } + using var decryptor = aes.CreateDecryptor(aes.Key, iv); + using var ms = new MemoryStream(cipher); + using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); + using var sr = new StreamReader(cs); + return sr.ReadToEnd(); } } \ No newline at end of file diff --git a/src/Aevatar.Domain/AINameContest/ContestAgentsDto.cs b/src/Aevatar.Domain/AINameContest/ContestAgentsDto.cs index b7ab6d618..fdf1f770f 100644 --- a/src/Aevatar.Domain/AINameContest/ContestAgentsDto.cs +++ b/src/Aevatar.Domain/AINameContest/ContestAgentsDto.cs @@ -41,7 +41,6 @@ public class ContestAgentsDto public List HostAgentList { get; set; } } - public class Network { public List ConstentList { get; set; } @@ -50,9 +49,7 @@ public class Network public List HostList { get; set; } public string CallbackAddress { get; set; } public string Name { get; set; } - public string Round { get; set; } - } public class NetworksDto @@ -70,13 +67,11 @@ public class AgentReponse [GenerateSerializer] public class AgentResponse { - [Id(0)] public List ContestantAgentList { get; set; } = new List(); + [Id(0)] public List ContestantAgentList { get; set; } = new List(); [Id(1)] public List JudgeAgentList { get; set; } = new List(); [Id(2)] public List HostAgentList { get; set; } = new List(); - } - public class GroupDetail { public string GroupId { get; set; } @@ -88,7 +83,6 @@ public class GroupResponse public List GroupDetails { get; set; } = new List(); } - public class GroupDto { public List GroupIdList { get; set; } = new List(); diff --git a/src/Aevatar.Domain/AINameContest/NameContestOptions.cs b/src/Aevatar.Domain/AINameContest/NameContestOptions.cs index ecdcc76fb..cbac2949c 100644 --- a/src/Aevatar.Domain/AINameContest/NameContestOptions.cs +++ b/src/Aevatar.Domain/AINameContest/NameContestOptions.cs @@ -5,6 +5,6 @@ namespace Aevatar.Options; public class NameContestOptions { public Dictionary CreativeGAgent { get; set; } - + public Dictionary JudgeGAgent { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Domain/AevatarConsts.cs b/src/Aevatar.Domain/AevatarConsts.cs index 95d219825..d23432a07 100644 --- a/src/Aevatar.Domain/AevatarConsts.cs +++ b/src/Aevatar.Domain/AevatarConsts.cs @@ -5,7 +5,7 @@ public static class AevatarConsts public const string DbTablePrefix = "App"; public const string DbSchema = null; - + public const string AdminRoleName = "admin"; public const string OrganizationTypeKey = "OrganizationType"; public const string OrganizationRoleKey = "OrganizationRole"; @@ -14,8 +14,7 @@ public static class AevatarConsts public const string SecurityStampClaimType = "security_stamp"; public const string MemberStatusKey = "MemberStatus"; public const string MemberInvitationInfoKey = "MemberInvitationInfo"; - + public const string OrganizationOwnerRoleName = "Owner"; public const string OrganizationReaderRoleName = "Reader"; - -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain/Agent/AgentTypeDto.cs b/src/Aevatar.Domain/Agent/AgentTypeDto.cs index 31437a62b..75e90592f 100644 --- a/src/Aevatar.Domain/Agent/AgentTypeDto.cs +++ b/src/Aevatar.Domain/Agent/AgentTypeDto.cs @@ -28,7 +28,7 @@ public class Configuration public class AgentTypeData { public string? FullName { get; set; } - public Configuration? InitializationData { get; set; } + public Configuration? InitializationData { get; set; } } public class PropertyData diff --git a/src/Aevatar.Domain/ApiRequests/IApiRequestSnapshotRepository.cs b/src/Aevatar.Domain/ApiRequests/IApiRequestSnapshotRepository.cs index ea9b51b61..94b5e51f1 100644 --- a/src/Aevatar.Domain/ApiRequests/IApiRequestSnapshotRepository.cs +++ b/src/Aevatar.Domain/ApiRequests/IApiRequestSnapshotRepository.cs @@ -3,7 +3,4 @@ namespace Aevatar.ApiRequests; -public interface IApiRequestSnapshotRepository : IRepository -{ - -} \ No newline at end of file +public interface IApiRequestSnapshotRepository : IRepository; \ No newline at end of file diff --git a/src/Aevatar.Domain/Cqrs/CreateTransactionGEventDto.cs b/src/Aevatar.Domain/Cqrs/CreateTransactionGEventDto.cs index d166cf05c..c030f33e7 100644 --- a/src/Aevatar.Domain/Cqrs/CreateTransactionGEventDto.cs +++ b/src/Aevatar.Domain/Cqrs/CreateTransactionGEventDto.cs @@ -6,11 +6,10 @@ public class CreateTransactionGEventDto : BaseEventDto { public Guid Id { get; set; } public string ChainId { get; set; } - public string SenderName{ get; set; } + public string SenderName { get; set; } public string ContractAddress { get; set; } public string MethodName { get; set; } public string Param { get; set; } - public bool IsSuccess { get; set; } - + public bool IsSuccess { get; set; } public string TransactionId { get; set; } -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain/Notification/INotificationRepository.cs b/src/Aevatar.Domain/Notification/INotificationRepository.cs index 05cc76ea4..c858495fb 100644 --- a/src/Aevatar.Domain/Notification/INotificationRepository.cs +++ b/src/Aevatar.Domain/Notification/INotificationRepository.cs @@ -1,10 +1,6 @@ using System; -using Aevatar.ApiKey; using Volo.Abp.Domain.Repositories; namespace Aevatar.Notification; -public interface INotificationRepository: IRepository -{ - -} \ No newline at end of file +public interface INotificationRepository : IRepository; \ No newline at end of file diff --git a/src/Aevatar.Domain/Notification/NotificationInfo.cs b/src/Aevatar.Domain/Notification/NotificationInfo.cs index 159141b21..a5d78f5d4 100644 --- a/src/Aevatar.Domain/Notification/NotificationInfo.cs +++ b/src/Aevatar.Domain/Notification/NotificationInfo.cs @@ -7,8 +7,7 @@ namespace Aevatar.Notification; public class NotificationInfo : FullAuditedAggregateRoot { public NotificationTypeEnum Type { get; set; } - - public Dictionary Input { get; set; } + public Dictionary Input { get; set; } public string Content { get; set; } public Guid Receiver { get; set; } public NotificationStatusEnum Status { get; set; } diff --git a/src/Aevatar.Domain/OpenIddict/OpenIddictDataSeedContributor.cs b/src/Aevatar.Domain/OpenIddict/OpenIddictDataSeedContributor.cs index fe21405ec..0139c9134 100644 --- a/src/Aevatar.Domain/OpenIddict/OpenIddictDataSeedContributor.cs +++ b/src/Aevatar.Domain/OpenIddict/OpenIddictDataSeedContributor.cs @@ -47,7 +47,7 @@ public OpenIddictDataSeedContributor( IPermissionDataSeeder permissionDataSeeder, IdentityUserManager identityUserManager, IOptionsSnapshot userOptions, - IStringLocalizer l , + IStringLocalizer l, IPermissionManager permissionManager, IdentityRoleManager roleManager) { @@ -76,12 +76,15 @@ private async Task CreateScopesAsync() { if (await _openIddictScopeRepository.FindByNameAsync("Aevatar") == null) { - await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor { - Name = "Aevatar", DisplayName = "Aevatar API", Resources = { "Aevatar" } + await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor + { + Name = "Aevatar", + DisplayName = "Aevatar API", + Resources = { "Aevatar" } }); } } - + private async Task SeedAdminUserAsync() { var adminUser = await _identityUserManager.FindByNameAsync("admin"); @@ -92,15 +95,18 @@ private async Task SeedAdminUserAsync() var result = await _identityUserManager.ResetPasswordAsync(adminUser, token, adminPassword); if (!result.Succeeded) { - throw new Exception("Failed to set admin password: " + result.Errors.Select(e => e.Description).Aggregate((errors, error) => errors + ", " + error)); + throw new Exception("Failed to set admin password: " + result.Errors.Select(e => e.Description) + .Aggregate((errors, error) => errors + ", " + error)); } + await SeedPermissionsFromConfigurationAsync(); } } private async Task SeedPermissionsFromConfigurationAsync() { - var permissionMappings = _configuration.GetSection("PermissionMappings").Get>>(); + var permissionMappings = + _configuration.GetSection("PermissionMappings").Get>>(); if (permissionMappings == null) return; int count = 0; foreach (var mapping in permissionMappings) @@ -114,10 +120,11 @@ private async Task SeedPermissionsFromConfigurationAsync() var identityRole = new IdentityRole(Guid.NewGuid(), roleName); identityRole.IsPublic = true; identityRole.IsStatic = true; - if (count == 0 ) + if (count == 0) { identityRole.IsDefault = true; } + count++; var result = await _roleManager.CreateAsync(identityRole); if (!result.Succeeded) @@ -126,13 +133,14 @@ private async Task SeedPermissionsFromConfigurationAsync() $"{string.Join(", ", result.Errors.Select(e => e.Description))}"); } } + foreach (var permission in permissions) { await _permissionManager.SetAsync( permission, - RolePermissionValueProvider.ProviderName , + RolePermissionValueProvider.ProviderName, roleName, - true + true ); } } @@ -140,7 +148,8 @@ await _permissionManager.SetAsync( private async Task CreateApplicationsAsync() { - var commonScopes = new List { + var commonScopes = new List + { OpenIddictConstants.Permissions.Scopes.Address, OpenIddictConstants.Permissions.Scopes.Email, OpenIddictConstants.Permissions.Scopes.Phone, @@ -169,7 +178,7 @@ await CreateApplicationAsync( clientUri: swaggerRootUrl ); } - + var authServerClientId = configurationSection["AevatarAuthServer:ClientId"]; if (!authServerClientId.IsNullOrWhiteSpace()) { @@ -227,7 +236,8 @@ private async Task CreateApplicationAsync( var client = await _openIddictApplicationRepository.FindByClientIdAsync(name); - var application = new AbpApplicationDescriptor { + var application = new AbpApplicationDescriptor + { ClientId = name, ClientType = type, ClientSecret = secret, @@ -256,7 +266,8 @@ private async Task CreateApplicationAsync( application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout); } - var buildInGrantTypes = new[] { + var buildInGrantTypes = new[] + { OpenIddictConstants.GrantTypes.Implicit, OpenIddictConstants.GrantTypes.Password, OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.ClientCredentials, OpenIddictConstants.GrantTypes.DeviceCode, OpenIddictConstants.GrantTypes.RefreshToken @@ -329,7 +340,8 @@ private async Task CreateApplicationAsync( } } - var buildInScopes = new[] { + var buildInScopes = new[] + { OpenIddictConstants.Permissions.Scopes.Address, OpenIddictConstants.Permissions.Scopes.Email, OpenIddictConstants.Permissions.Scopes.Phone, OpenIddictConstants.Permissions.Scopes.Profile, OpenIddictConstants.Permissions.Scopes.Roles @@ -398,8 +410,10 @@ await _permissionDataSeeder.SeedAsync( if (!HasSameRedirectUris(client, application)) { - client.RedirectUris = JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); - client.PostLogoutRedirectUris = JsonSerializer.Serialize(application.PostLogoutRedirectUris.Select(q => q.ToString().TrimEnd('/'))); + client.RedirectUris = + JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); + client.PostLogoutRedirectUris = + JsonSerializer.Serialize(application.PostLogoutRedirectUris.Select(q => q.ToString().TrimEnd('/'))); await _applicationManager.UpdateAsync(client.ToModel()); } @@ -413,11 +427,13 @@ await _permissionDataSeeder.SeedAsync( private bool HasSameRedirectUris(OpenIddictApplication existingClient, AbpApplicationDescriptor application) { - return existingClient.RedirectUris == JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); + return existingClient.RedirectUris == + JsonSerializer.Serialize(application.RedirectUris.Select(q => q.ToString().TrimEnd('/'))); } private bool HasSameScopes(OpenIddictApplication existingClient, AbpApplicationDescriptor application) { - return existingClient.Permissions == JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString().TrimEnd('/'))); + return existingClient.Permissions == + JsonSerializer.Serialize(application.Permissions.Select(q => q.ToString().TrimEnd('/'))); } -} +} \ No newline at end of file diff --git a/src/Aevatar.Domain/Plugins/IPluginRepository.cs b/src/Aevatar.Domain/Plugins/IPluginRepository.cs index 1c20b03f7..524b38932 100644 --- a/src/Aevatar.Domain/Plugins/IPluginRepository.cs +++ b/src/Aevatar.Domain/Plugins/IPluginRepository.cs @@ -3,7 +3,4 @@ namespace Aevatar.Plugins; -public interface IPluginRepository : IRepository -{ - -} \ No newline at end of file +public interface IPluginRepository : IRepository; \ No newline at end of file diff --git a/src/Aevatar.Domain/Plugins/Plugin.cs b/src/Aevatar.Domain/Plugins/Plugin.cs index 51d444bad..3bef704d5 100644 --- a/src/Aevatar.Domain/Plugins/Plugin.cs +++ b/src/Aevatar.Domain/Plugins/Plugin.cs @@ -3,11 +3,11 @@ namespace Aevatar.Plugins; -public class Plugin: FullAuditedAggregateRoot +public class Plugin : FullAuditedAggregateRoot { public Guid ProjectId { get; set; } public string Name { get; set; } - + public Plugin() { diff --git a/src/Aevatar.Domain/Properties/AssemblyInfo.cs b/src/Aevatar.Domain/Properties/AssemblyInfo.cs index 275f21758..3fe10d4cf 100644 --- a/src/Aevatar.Domain/Properties/AssemblyInfo.cs +++ b/src/Aevatar.Domain/Properties/AssemblyInfo.cs @@ -1,3 +1,3 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleToAttribute("Aevatar.Domain.Tests")] -[assembly:InternalsVisibleToAttribute("Aevatar.TestBase")] +[assembly: InternalsVisibleToAttribute("Aevatar.Domain.Tests")] +[assembly: InternalsVisibleToAttribute("Aevatar.TestBase")] \ No newline at end of file diff --git a/src/Aevatar.Domain/Subscription/CreateSubscriptionDto.cs b/src/Aevatar.Domain/Subscription/CreateSubscriptionDto.cs index d56dacb9e..239f03032 100644 --- a/src/Aevatar.Domain/Subscription/CreateSubscriptionDto.cs +++ b/src/Aevatar.Domain/Subscription/CreateSubscriptionDto.cs @@ -6,6 +6,6 @@ namespace Aevatar.Subscription; public class CreateSubscriptionDto { public Guid AgentId { get; set; } - public List EventTypes { get; set; } + public List EventTypes { get; set; } public string CallbackUrl { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Domain/Subscription/EventPushRequest.cs b/src/Aevatar.Domain/Subscription/EventPushRequest.cs index cea1e5150..3aa353167 100644 --- a/src/Aevatar.Domain/Subscription/EventPushRequest.cs +++ b/src/Aevatar.Domain/Subscription/EventPushRequest.cs @@ -1,17 +1,16 @@ using System; using System.Collections.Generic; using Aevatar.Agent; -using Orleans; namespace Aevatar.Subscription; + public class EventPushRequest { - public Guid AgentId { get; set; } - public Guid EventId { get; set; } - public string EventType { get; set; } - public DateTime Timestamp { get; set; } - public string Payload { get; set; } - public AgentDto AgentData { get; set; } - public Dictionary Metadata { get; set; } -} - + public Guid AgentId { get; set; } + public Guid EventId { get; set; } + public string EventType { get; set; } + public DateTime Timestamp { get; set; } + public string Payload { get; set; } + public AgentDto AgentData { get; set; } + public Dictionary Metadata { get; set; } +} \ No newline at end of file diff --git a/src/Aevatar.Domain/Subscription/EventTypeDto.cs b/src/Aevatar.Domain/Subscription/EventTypeDto.cs index 540d9d28f..1ff36a7ee 100644 --- a/src/Aevatar.Domain/Subscription/EventTypeDto.cs +++ b/src/Aevatar.Domain/Subscription/EventTypeDto.cs @@ -11,7 +11,7 @@ public class EventDescriptionDto public class EventProperty { - public string Name { get; set; } + public string Name { get; set; } public string Type { get; set; } public string Description { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Domain/Subscription/PublishEventDto.cs b/src/Aevatar.Domain/Subscription/PublishEventDto.cs index 613bbc317..0a12c32e1 100644 --- a/src/Aevatar.Domain/Subscription/PublishEventDto.cs +++ b/src/Aevatar.Domain/Subscription/PublishEventDto.cs @@ -6,6 +6,6 @@ namespace Aevatar.Subscription; public class PublishEventDto { public Guid AgentId { get; set; } - public string EventType { get; set; } + public string EventType { get; set; } public Dictionary EventProperties { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.Domain/User/IdentityUserExtension.cs b/src/Aevatar.Domain/User/IdentityUserExtension.cs index 1fc954098..df1d94293 100644 --- a/src/Aevatar.Domain/User/IdentityUserExtension.cs +++ b/src/Aevatar.Domain/User/IdentityUserExtension.cs @@ -4,14 +4,15 @@ namespace Aevatar.User; -public class IdentityUserExtension: FullAuditedAggregateRoot +public class IdentityUserExtension : FullAuditedAggregateRoot { public Guid UserId { get; set; } + /// /// EOA Address or CA Address /// public string WalletAddress { get; set; } - + public IdentityUserExtension(Guid id) { Id = id; diff --git a/src/Aevatar.Domain/Webhook/DestroyWebhookDto.cs b/src/Aevatar.Domain/Webhook/DestroyWebhookDto.cs index c77333fb6..dbab20d6e 100644 --- a/src/Aevatar.Domain/Webhook/DestroyWebhookDto.cs +++ b/src/Aevatar.Domain/Webhook/DestroyWebhookDto.cs @@ -1,10 +1,8 @@ -using Microsoft.AspNetCore.Http; - namespace Aevatar.Webhook; public class DestroyWebhookDto { - public string WebhookId{ get; set; } - public string Version{ get; set; } + public string WebhookId { get; set; } + public string Version { get; set; } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi.Host/AevatarHttpApiHostModule.cs b/src/Aevatar.HttpApi.Host/AevatarHttpApiHostModule.cs index 3aed8ea2c..df762988e 100644 --- a/src/Aevatar.HttpApi.Host/AevatarHttpApiHostModule.cs +++ b/src/Aevatar.HttpApi.Host/AevatarHttpApiHostModule.cs @@ -28,7 +28,6 @@ using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.Libs; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; -using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.BackgroundWorkers; @@ -38,7 +37,6 @@ using Volo.Abp.Modularity; using Volo.Abp.Swashbuckle; using Volo.Abp.Threading; -using Volo.Abp.VirtualFileSystem; namespace Aevatar; @@ -69,7 +67,6 @@ public override void ConfigureServices(ServiceConfigurationContext context) ConfigureAuthentication(context, configuration); ConfigureBundles(); - // ConfigureUrls(configuration); ConfigureConventionalControllers(); ConfigureVirtualFileSystem(context); ConfigureAutoResponseWrapper(context); @@ -77,7 +74,6 @@ public override void ConfigureServices(ServiceConfigurationContext context) ConfigureDataProtection(context, configuration, hostingEnvironment); ConfigCache(context, configuration); ConfigureCors(context, configuration); - //context.Services.AddDaprClient(); context.Services.AddMvc(options => { options.Filters.Add(new IgnoreAntiforgeryTokenAttribute()); }) .AddNewtonsoftJson(); @@ -95,7 +91,7 @@ private void ConfigureCors(ServiceConfigurationContext context, IConfiguration c .WithOrigins(configuration["App:CorsOrigins"]? .Split(",", StringSplitOptions.RemoveEmptyEntries) .Select(o => o.RemovePostFix("/")) - .ToArray() ?? Array.Empty()) + .ToArray() ?? []) .WithAbpExposedHeaders() .SetIsOriginAllowedToAllowWildcardSubdomains() .AllowAnyHeader() @@ -134,20 +130,21 @@ private void ConfigureAuthentication(ServiceConfigurationContext context, IConfi options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); options.Audience = "Aevatar"; options.MapInboundClaims = false; - + options.Events = new JwtBearerEvents { - OnTokenValidated = async tokenValidatedContext => + OnTokenValidated = async tokenValidatedContext => { var userId = tokenValidatedContext.Principal.FindFirst(JwtRegisteredClaimNames.Sub)?.Value; - var securityStamp = tokenValidatedContext.Principal.FindFirst(AevatarConsts.SecurityStampClaimType) + var securityStamp = tokenValidatedContext.Principal + .FindFirst(AevatarConsts.SecurityStampClaimType) ?.Value; if (!userId.IsNullOrWhiteSpace() && !securityStamp.IsNullOrWhiteSpace()) { var userManager = tokenValidatedContext.HttpContext.RequestServices .GetRequiredService(); var user = await userManager.FindByIdAsync(userId); - + if (user == null || user.SecurityStamp != securityStamp) { tokenValidatedContext.Fail("Token is no longer valid."); @@ -162,6 +159,7 @@ private void ConfigureAuthentication(ServiceConfigurationContext context, IConfi // Read the token out of the query string messageReceivedContext.Token = accessToken; } + return Task.CompletedTask; } }; @@ -185,21 +183,6 @@ private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) if (hostingEnvironment.IsDevelopment()) { - // Configure(options => - // { - // options.FileSets.ReplaceEmbeddedByPhysical( - // Path.Combine(hostingEnvironment.ContentRootPath, - // $"..{Path.DirectorySeparatorChar}Aevatar.Domain.Shared")); - // options.FileSets.ReplaceEmbeddedByPhysical( - // Path.Combine(hostingEnvironment.ContentRootPath, - // $"..{Path.DirectorySeparatorChar}Aevatar.Domain")); - // options.FileSets.ReplaceEmbeddedByPhysical( - // Path.Combine(hostingEnvironment.ContentRootPath, - // $"..{Path.DirectorySeparatorChar}Aevatar.Application.Contracts")); - // options.FileSets.ReplaceEmbeddedByPhysical( - // Path.Combine(hostingEnvironment.ContentRootPath, - // $"..{Path.DirectorySeparatorChar}Aevatar.Application")); - // }); } } @@ -235,7 +218,7 @@ private static void ConfigureSwaggerServices(ServiceConfigurationContext context { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, - new string[] { } + [] } }); } @@ -250,7 +233,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex app.UseCorrelationId(); app.UseStaticFiles(); app.UseRouting(); - + app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); @@ -269,14 +252,12 @@ public override void OnApplicationInitialization(ApplicationInitializationContex c.OAuthScopes("Aevatar"); }); app.UseHealthChecks("/health"); - + app.UseAuditing(); app.UseAbpSerilogEnrichers(); app.UseConfiguredEndpoints(); var statePermissionProvider = context.ServiceProvider.GetRequiredService(); AsyncHelper.RunSync(async () => await statePermissionProvider.SaveAllStatePermissionAsync()); - - AsyncHelper.RunSync(() => context.AddBackgroundWorkerAsync()); } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi.Host/Extensions/OrleansClientExtension.cs b/src/Aevatar.HttpApi.Host/Extensions/OrleansClientExtension.cs index faf8fbcea..4fe06d7e8 100644 --- a/src/Aevatar.HttpApi.Host/Extensions/OrleansClientExtension.cs +++ b/src/Aevatar.HttpApi.Host/Extensions/OrleansClientExtension.cs @@ -46,7 +46,7 @@ public static IHostBuilder UseOrleansClientConfiguration(this IHostBuilder hostB }) .AddActivityPropagation() .UseAevatar(); - + var streamProvider = config.GetSection("OrleansStream:Provider").Get(); Log.Information("Stream Provider: {streamProvider}", streamProvider); if (string.Equals("kafka", streamProvider, StringComparison.CurrentCultureIgnoreCase)) @@ -74,6 +74,7 @@ public static IHostBuilder UseOrleansClientConfiguration(this IHostBuilder hostB ReplicationFactor = replicationFactor }); } + Log.Information("Kafka Options: {@options}", options); }) .AddJson() diff --git a/src/Aevatar.HttpApi/AevatarHttpApiModule.cs b/src/Aevatar.HttpApi/AevatarHttpApiModule.cs index 899327c56..8f9743668 100644 --- a/src/Aevatar.HttpApi/AevatarHttpApiModule.cs +++ b/src/Aevatar.HttpApi/AevatarHttpApiModule.cs @@ -20,7 +20,7 @@ namespace Aevatar; typeof(AbpPermissionManagementHttpApiModule), typeof(AevatarDeveloperLoggerModule), typeof(AbpAspNetCoreSignalRModule) - )] +)] public class AevatarHttpApiModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) @@ -38,10 +38,7 @@ private void ConfigureLocalization() typeof(AbpUiResource) ); }); - - Configure(options => - { - options.Conventions.Add(new ApplicationDescription()); - }); + + Configure(options => { options.Conventions.Add(new ApplicationDescription()); }); } -} +} \ No newline at end of file diff --git a/src/Aevatar.HttpApi/ApplicationDescription.cs b/src/Aevatar.HttpApi/ApplicationDescription.cs index fffb824e7..8e13b94cc 100644 --- a/src/Aevatar.HttpApi/ApplicationDescription.cs +++ b/src/Aevatar.HttpApi/ApplicationDescription.cs @@ -5,7 +5,7 @@ namespace Aevatar; -public class ApplicationDescription: IApplicationModelConvention +public class ApplicationDescription : IApplicationModelConvention { public ApplicationDescription() { @@ -13,6 +13,6 @@ public ApplicationDescription() public void Apply(ApplicationModel application) { - application.Controllers.RemoveAll(x=>x.ControllerType == typeof(AccountController)); + application.Controllers.RemoveAll(x => x.ControllerType == typeof(AccountController)); } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Controllers/AccountController.cs b/src/Aevatar.HttpApi/Controllers/AccountController.cs index 05adb9e70..9f13415c1 100644 --- a/src/Aevatar.HttpApi/Controllers/AccountController.cs +++ b/src/Aevatar.HttpApi/Controllers/AccountController.cs @@ -19,14 +19,14 @@ public AccountController(IAccountService accountService) { _accountService = accountService; } - + [HttpPost] [Route("register")] public virtual Task RegisterAsync(AevatarRegisterDto input) { return _accountService.RegisterAsync(input); } - + [HttpPost] [Route("send-register-code")] public virtual Task SendRegisterCodeAsync(SendRegisterCodeDto input) diff --git a/src/Aevatar.HttpApi/Controllers/AppIdController.cs b/src/Aevatar.HttpApi/Controllers/AppIdController.cs index 79027a535..dcfd7d9b7 100644 --- a/src/Aevatar.HttpApi/Controllers/AppIdController.cs +++ b/src/Aevatar.HttpApi/Controllers/AppIdController.cs @@ -26,7 +26,8 @@ public class AppIdController : AevatarController private readonly IOrganizationPermissionChecker _organizationPermission; private readonly IProjectService _projectService; - public AppIdController(IProjectAppIdService appIdService, IdentityUserManager identityUserManager, IOrganizationPermissionChecker organizationPermission, IProjectService projectService) + public AppIdController(IProjectAppIdService appIdService, IdentityUserManager identityUserManager, + IOrganizationPermissionChecker organizationPermission, IProjectService projectService) { _appIdService = appIdService; _identityUserManager = identityUserManager; @@ -40,7 +41,7 @@ public async Task CreateApiKey(CreateAppIdDto createDto) { // check projectId await _projectService.GetAsync(createDto.ProjectId); - + await _organizationPermission.AuthenticateAsync(createDto.ProjectId, AevatarPermissions.ApiKeys.Create); await _appIdService.CreateAsync(createDto.ProjectId, createDto.Name, CurrentUser.Id); } diff --git a/src/Aevatar.HttpApi/Controllers/HostController.cs b/src/Aevatar.HttpApi/Controllers/HostController.cs index a1c5a3d7c..5b2e07af7 100644 --- a/src/Aevatar.HttpApi/Controllers/HostController.cs +++ b/src/Aevatar.HttpApi/Controllers/HostController.cs @@ -22,21 +22,19 @@ public class HostController private readonly KubernetesOptions _kubernetesOptions; public HostController( - ILogService logService, + ILogService logService, IOptionsSnapshot kubernetesOptions - ) + ) { _logService = logService; _kubernetesOptions = kubernetesOptions.Value; } - + [HttpGet("log")] - public async Task> GetLatestRealTimeLogs(string appId,HostTypeEnum hostType,int offset) + public async Task> GetLatestRealTimeLogs(string appId, HostTypeEnum hostType, int offset) { - var indexName = _logService.GetHostLogIndexAliasName(_kubernetesOptions.AppNameSpace, appId + "-"+hostType.ToString().ToLower(), "1"); + var indexName = _logService.GetHostLogIndexAliasName(_kubernetesOptions.AppNameSpace, + appId + "-" + hostType.ToString().ToLower(), "1"); return await _logService.GetHostLatestLogAsync(indexName, offset); } - - - } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Controllers/NotificationController.cs b/src/Aevatar.HttpApi/Controllers/NotificationController.cs index 5f51730ab..d25b54ffd 100644 --- a/src/Aevatar.HttpApi/Controllers/NotificationController.cs +++ b/src/Aevatar.HttpApi/Controllers/NotificationController.cs @@ -95,13 +95,13 @@ public async Task> GetOrganizationVisitInfo(int pageI { return await _notificationService.GetOrganizationVisitInfo((Guid)CurrentUser.Id!, pageIndex, pageSize); } - + [HttpGet("unread-count")] public async Task GetUnreadCountAsync() { return await _notificationService.GetUnreadCountAsync(CurrentUser.Id.Value); } - + [HttpPost("read")] public async Task ReadAsync(ReadNotificationDto input) { diff --git a/src/Aevatar.HttpApi/Controllers/OrganizationController.cs b/src/Aevatar.HttpApi/Controllers/OrganizationController.cs index 546a6ac78..637d0d595 100644 --- a/src/Aevatar.HttpApi/Controllers/OrganizationController.cs +++ b/src/Aevatar.HttpApi/Controllers/OrganizationController.cs @@ -66,7 +66,8 @@ public async Task DeleteAsync(Guid id) [HttpGet] [Route("{organizationId}/members")] - public async Task> GetMemberListAsync(Guid organizationId, GetOrganizationMemberListDto input) + public async Task> GetMemberListAsync(Guid organizationId, + GetOrganizationMemberListDto input) { await _permissionChecker.AuthenticateAsync(organizationId, AevatarPermissions.Members.Default); return await _organizationService.GetMemberListAsync(organizationId, input); @@ -85,15 +86,15 @@ public async Task SetMemberAsync(Guid organizationId, SetOrganizationMemberDto i public async Task SetMemberRoleAsync(Guid organizationId, SetOrganizationMemberRoleDto input) { await _permissionChecker.AuthenticateAsync(organizationId, AevatarPermissions.Members.Manage); - + if (input.UserId == CurrentUser.Id) { throw new UserFriendlyException("Unable to set your own role."); } - + await _organizationService.SetMemberRoleAsync(organizationId, input); } - + [HttpGet] [Route("{organizationId}/permissions")] public async Task> GetPermissionsListAsync(Guid organizationId) diff --git a/src/Aevatar.HttpApi/Controllers/OrganizationPermissionController.cs b/src/Aevatar.HttpApi/Controllers/OrganizationPermissionController.cs index 075720a0d..6e91f4ff0 100644 --- a/src/Aevatar.HttpApi/Controllers/OrganizationPermissionController.cs +++ b/src/Aevatar.HttpApi/Controllers/OrganizationPermissionController.cs @@ -32,7 +32,7 @@ public OrganizationPermissionController( public virtual async Task GetAsync(Guid organizationId, string providerName, string providerKey) { - await _permissionChecker.AuthenticateAsync(organizationId,AevatarPermissions.Roles.Default); + await _permissionChecker.AuthenticateAsync(organizationId, AevatarPermissions.Roles.Default); return await _organizationPermissionService.GetAsync(organizationId, providerName, providerKey); } @@ -40,7 +40,7 @@ public virtual async Task GetAsync(Guid organization public virtual async Task UpdateAsync(Guid organizationId, string providerName, string providerKey, UpdatePermissionsDto input) { - await _permissionChecker.AuthenticateAsync(organizationId,AevatarPermissions.Roles.Edit); + await _permissionChecker.AuthenticateAsync(organizationId, AevatarPermissions.Roles.Edit); await _organizationPermissionService.UpdateAsync(organizationId, providerName, providerKey, input); } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Controllers/OrganizationRoleController.cs b/src/Aevatar.HttpApi/Controllers/OrganizationRoleController.cs index c78513a2f..a08f0f3c5 100644 --- a/src/Aevatar.HttpApi/Controllers/OrganizationRoleController.cs +++ b/src/Aevatar.HttpApi/Controllers/OrganizationRoleController.cs @@ -40,7 +40,7 @@ public async Task> GetRoleListAsync(Guid organiza return await _organizationRoleService.GetListAsync(organizationId); } - + [HttpPost] public virtual async Task CreateAsync(Guid organizationId, IdentityRoleCreateDto input) { @@ -63,5 +63,4 @@ public virtual async Task DeleteAsync(Guid organizationId, Guid id) await _permissionChecker.AuthenticateAsync(organizationId, AevatarPermissions.Roles.Delete); await _organizationRoleService.DeleteAsync(organizationId, id); } - } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Controllers/ProjectController.cs b/src/Aevatar.HttpApi/Controllers/ProjectController.cs index 2db9c16cb..7a27556d5 100644 --- a/src/Aevatar.HttpApi/Controllers/ProjectController.cs +++ b/src/Aevatar.HttpApi/Controllers/ProjectController.cs @@ -68,7 +68,8 @@ public async Task DeleteAsync(Guid id) [HttpGet] [Route("{projectId}/members")] - public async Task> GetMemberListAsync(Guid projectId, GetOrganizationMemberListDto input) + public async Task> GetMemberListAsync(Guid projectId, + GetOrganizationMemberListDto input) { await _permissionChecker.AuthenticateAsync(projectId, AevatarPermissions.Members.Default); return await _projectService.GetMemberListAsync(projectId, input); @@ -87,15 +88,15 @@ public async Task SetMemberAsync(Guid projectId, SetOrganizationMemberDto input) public async Task SetMemberRoleAsync(Guid projectId, SetOrganizationMemberRoleDto input) { await _permissionChecker.AuthenticateAsync(projectId, AevatarPermissions.Members.Manage); - + if (input.UserId == CurrentUser.Id) { throw new UserFriendlyException("Unable to set your own role."); } - + await _projectService.SetMemberRoleAsync(projectId, input); } - + [HttpGet] [Route("{projectId}/permissions")] public async Task> GetPermissionsListAsync(Guid projectId) diff --git a/src/Aevatar.HttpApi/Controllers/ProjectPermissionController.cs b/src/Aevatar.HttpApi/Controllers/ProjectPermissionController.cs index e4fce4bb2..d04650e66 100644 --- a/src/Aevatar.HttpApi/Controllers/ProjectPermissionController.cs +++ b/src/Aevatar.HttpApi/Controllers/ProjectPermissionController.cs @@ -33,7 +33,7 @@ public ProjectPermissionController( public virtual async Task GetAsync(Guid projectId, string providerName, string providerKey) { - await _permissionChecker.AuthenticateAsync(projectId,AevatarPermissions.Roles.Default); + await _permissionChecker.AuthenticateAsync(projectId, AevatarPermissions.Roles.Default); return await _projectPermissionService.GetAsync(projectId, providerName, providerKey); } @@ -41,7 +41,7 @@ public virtual async Task GetAsync(Guid projectId, s public virtual async Task UpdateAsync(Guid projectId, string providerName, string providerKey, UpdatePermissionsDto input) { - await _permissionChecker.AuthenticateAsync(projectId,AevatarPermissions.Roles.Default); + await _permissionChecker.AuthenticateAsync(projectId, AevatarPermissions.Roles.Default); await _projectPermissionService.UpdateAsync(projectId, providerName, providerKey, input); } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Controllers/ProjectRoleController.cs b/src/Aevatar.HttpApi/Controllers/ProjectRoleController.cs index 40f8ee775..bca078e86 100644 --- a/src/Aevatar.HttpApi/Controllers/ProjectRoleController.cs +++ b/src/Aevatar.HttpApi/Controllers/ProjectRoleController.cs @@ -9,7 +9,6 @@ using Volo.Abp.Application.Dtos; using Volo.Abp.Authorization; using Volo.Abp.Identity; -using Volo.Abp.PermissionManagement; namespace Aevatar.Controllers; @@ -40,7 +39,7 @@ public async Task> GetRoleListAsync(Guid projectI return await _organizationRoleService.GetListAsync(projectId); } - + [HttpPost] public virtual async Task CreateAsync(Guid projectId, IdentityRoleCreateDto input) { diff --git a/src/Aevatar.HttpApi/Controllers/SubscriptionController.cs b/src/Aevatar.HttpApi/Controllers/SubscriptionController.cs index d78fb3c23..faadb1e04 100644 --- a/src/Aevatar.HttpApi/Controllers/SubscriptionController.cs +++ b/src/Aevatar.HttpApi/Controllers/SubscriptionController.cs @@ -16,7 +16,7 @@ public class SubscriptionController : AevatarController private readonly ILogger _logger; public SubscriptionController( - SubscriptionAppService subscriptionAppService, + SubscriptionAppService subscriptionAppService, ILogger logger) { _subscriptionAppService = subscriptionAppService; @@ -24,31 +24,31 @@ public SubscriptionController( } [HttpGet("events/{guid}")] - [Authorize(Policy = AevatarPermissions.EventManagement.View)] + [Authorize(Policy = AevatarPermissions.EventManagement.View)] public async Task> GetAvailableEventsAsync(Guid guid) { - _logger.LogInformation("Get Available Events, id: {id}", guid); + _logger.LogInformation("Get Available Events, id: {id}", guid); return await _subscriptionAppService.GetAvailableEventsAsync(guid); } [HttpPost] - [Authorize(Policy = AevatarPermissions.SubscriptionManagent.CreateSubscription)] + [Authorize(Policy = AevatarPermissions.SubscriptionManagent.CreateSubscription)] public async Task SubscribeAsync([FromBody] CreateSubscriptionDto input) { return await _subscriptionAppService.SubscribeAsync(input); } [HttpDelete("{subscriptionId:guid}")] - [Authorize(Policy = AevatarPermissions.SubscriptionManagent.CancelSubscription)] + [Authorize(Policy = AevatarPermissions.SubscriptionManagent.CancelSubscription)] public async Task CancelSubscriptionAsync(Guid subscriptionId) { await _subscriptionAppService.CancelSubscriptionAsync(subscriptionId); } [HttpGet("{subscriptionId:guid}")] - [Authorize(Policy = AevatarPermissions.SubscriptionManagent.ViewSubscriptionStatus)] + [Authorize(Policy = AevatarPermissions.SubscriptionManagent.ViewSubscriptionStatus)] public async Task GetSubscriptionStatusAsync(Guid subscriptionId) { return await _subscriptionAppService.GetSubscriptionAsync(subscriptionId); } -} +} \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Handler/AevatarAuthorizationMiddlewareResultHandler.cs b/src/Aevatar.HttpApi/Handler/AevatarAuthorizationMiddlewareResultHandler.cs index fa51fcaad..1efe2c1df 100644 --- a/src/Aevatar.HttpApi/Handler/AevatarAuthorizationMiddlewareResultHandler.cs +++ b/src/Aevatar.HttpApi/Handler/AevatarAuthorizationMiddlewareResultHandler.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Security.Claims; using System.Threading.Tasks; using Aevatar.Core.Abstractions.Extensions; using Aevatar.PermissionManagement; @@ -10,8 +9,6 @@ using Microsoft.Extensions.Logging; using OpenIddict.Abstractions; using Orleans.Runtime; -using Volo.Abp.PermissionManagement; -using Volo.Abp.Security.Claims; namespace Aevatar.Handler; @@ -25,32 +22,35 @@ public AevatarAuthorizationMiddlewareResultHandler(ILogger c.Value).ToArray(); var clientId = user.FindFirst(OpenIddictConstants.Claims.ClientId)?.Value; - + { RequestContext.Set("CurrentUser", new UserContext { - UserId = !userId.IsNullOrEmpty() ? userId.ToGuid(): Guid.Empty, + UserId = !userId.IsNullOrEmpty() ? userId.ToGuid() : Guid.Empty, Roles = roles, - ClientId= clientId, + ClientId = clientId, }); } } + await _defaultHandler.HandleAsync(next, context, policy, authorizeResult); } } \ No newline at end of file diff --git a/src/Aevatar.HttpApi/Hubs/SignalRUserIdProvider.cs b/src/Aevatar.HttpApi/Hubs/SignalRUserIdProvider.cs index b99a86f61..ed9e31fe1 100644 --- a/src/Aevatar.HttpApi/Hubs/SignalRUserIdProvider.cs +++ b/src/Aevatar.HttpApi/Hubs/SignalRUserIdProvider.cs @@ -4,14 +4,14 @@ namespace Aevatar.Hubs; -public class SignalRUserIdProvider: IUserIdProvider, ISingletonDependency +public class SignalRUserIdProvider : IUserIdProvider, ISingletonDependency { public string? GetUserId(HubConnectionContext connection) { - var userId =connection.User?.FindFirst("sub")?.Value; + var userId = connection.User?.FindFirst("sub")?.Value; if (string.IsNullOrEmpty(userId)) { - userId =connection.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value; + userId = connection.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value; } return userId; diff --git a/src/Aevatar.MongoDB/ApiKeys/ProjectAppIdMongoRepository.cs b/src/Aevatar.MongoDB/ApiKeys/ProjectAppIdMongoRepository.cs index 086a66e6c..456c3d4c7 100644 --- a/src/Aevatar.MongoDB/ApiKeys/ProjectAppIdMongoRepository.cs +++ b/src/Aevatar.MongoDB/ApiKeys/ProjectAppIdMongoRepository.cs @@ -13,8 +13,8 @@ namespace Aevatar.ApiKeys; -public class ProjectAppIdMongoRepository : MongoDbRepository, IProjectAppIdRepository, - ITransientDependency +public class ProjectAppIdMongoRepository : MongoDbRepository, + IProjectAppIdRepository, ITransientDependency { public ProjectAppIdMongoRepository(IMongoDbContextProvider dbContextProvider) : base( dbContextProvider) @@ -35,12 +35,11 @@ public async Task> GetProjectAppIds(APIKeyPaged .Take(requestDto.MaxResultCount) .Skip(requestDto.SkipCount).ToListAsync(); - if (queryResponse != null) { result = queryResponse; } - + return new PagedResultDto(result.Count, result.AsReadOnly()); } diff --git a/src/Aevatar.MongoDB/Properties/AssemblyInfo.cs b/src/Aevatar.MongoDB/Properties/AssemblyInfo.cs index 206cb7ad8..f3a4f27ad 100644 --- a/src/Aevatar.MongoDB/Properties/AssemblyInfo.cs +++ b/src/Aevatar.MongoDB/Properties/AssemblyInfo.cs @@ -1,2 +1,2 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleToAttribute("Aevatar.MongoDB.Tests")] +[assembly: InternalsVisibleToAttribute("Aevatar.MongoDB.Tests")] diff --git a/src/Aevatar.Silo/Extensions/OrleansHostExtension.cs b/src/Aevatar.Silo/Extensions/OrleansHostExtension.cs index caa6af158..dda4c41b3 100644 --- a/src/Aevatar.Silo/Extensions/OrleansHostExtension.cs +++ b/src/Aevatar.Silo/Extensions/OrleansHostExtension.cs @@ -30,7 +30,7 @@ public static class OrleansHostExtension { // Delegate for environment variable access, allows for mocking in tests public static Func GetEnvironmentVariable { get; set; } = Environment.GetEnvironmentVariable; - + public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder) { return hostBuilder.UseOrleans((context, siloBuilder) => @@ -53,21 +53,22 @@ public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder : int.Parse(GetEnvironmentVariable("AevatarOrleans__SiloPort")); var gatewayPort = isRunningInKubernetes ? configSection.GetValue("GatewayPort") - :int.Parse(GetEnvironmentVariable("AevatarOrleans__GatewayPort")); - + : int.Parse(GetEnvironmentVariable("AevatarOrleans__GatewayPort")); + // Read the silo name pattern from environment variable or configuration var siloNamePattern = isRunningInKubernetes ? GetEnvironmentVariable("SILO_NAME_PATTERN") : GetEnvironmentVariable("AevatarOrleans__SILO_NAME_PATTERN"); - + // Register StateProjectionInitializer when SiloNamePattern is "Projector" - if (string.IsNullOrEmpty(siloNamePattern) || string.Compare(siloNamePattern, "Projector", StringComparison.OrdinalIgnoreCase) == 0) + if (string.IsNullOrEmpty(siloNamePattern) || + string.Compare(siloNamePattern, "Projector", StringComparison.OrdinalIgnoreCase) == 0) { // Register our StateProjectionInitializer as a startup task // This will run during silo startup at ServiceLifecycleStage.ApplicationServices (default) siloBuilder.AddStartupTask(); } - + siloBuilder .ConfigureEndpoints(advertisedIP: IPAddress.Parse(advertisedIP), siloPort: siloPort, @@ -111,15 +112,16 @@ public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder options.SupportedNamespacePrefixes.Add("Autofac.Core"); }) .AddActivityPropagation() - // .UsePluginGAgents() .UseDashboard(options => { options.Username = configSection.GetValue("DashboardUserName"); options.Password = configSection.GetValue("DashboardPassword"); - options.Host = isRunningInKubernetes ? "*" - : GetEnvironmentVariable("AevatarOrleans__DashboardIp"); - options.Port = isRunningInKubernetes ? configSection.GetValue("DashboardPort") - : int.Parse(GetEnvironmentVariable("AevatarOrleans__DashboardPort")); + options.Host = isRunningInKubernetes + ? "*" + : GetEnvironmentVariable("AevatarOrleans__DashboardIp"); + options.Port = isRunningInKubernetes + ? configSection.GetValue("DashboardPort") + : int.Parse(GetEnvironmentVariable("AevatarOrleans__DashboardPort")); options.HostSelf = true; options.CounterUpdateIntervalMs = configSection.GetValue("DashboardCounterUpdateIntervalMs"); @@ -138,7 +140,7 @@ public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Debug).AddConsole(); }) .Configure(options => { - options.SiloName = $"{siloNamePattern}-{Guid.NewGuid().ToString("N").Substring(0, 6)}"; + options.SiloName = $"{siloNamePattern}-{Guid.NewGuid().ToString("N").Substring(0, 6)}"; }); var eventSourcingProvider = configuration.GetSection("OrleansEventSourcing:Provider").Get(); @@ -196,19 +198,16 @@ public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder .RegisterHub(); }).ConfigureServices((context, services) => { - // services.Configure(context.Configuration.GetSection("AIServices:AzureOpenAI")); - // services.Configure(context.Configuration.GetSection("AIServices:DeepSeek")); services.Configure(context.Configuration.GetSection("VectorStores:Qdrant")); - + // Register the SiloNamePatternPlacement director services.AddPlacementDirector(); - + services.Configure(context.Configuration); services.Configure( context.Configuration.GetSection("AIServices:AzureOpenAIEmbeddings")); services.Configure(context.Configuration.GetSection("Rag")); services.AddSingleton(typeof(HubLifetimeManager<>), typeof(OrleansHubLifetimeManager<>)); - // services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSemanticKernel() diff --git a/src/Aevatar.Silo/Grains/Activation/IProjectionGrainActivator.cs b/src/Aevatar.Silo/Grains/Activation/IProjectionGrainActivator.cs index b42446b6b..ced2b7849 100644 --- a/src/Aevatar.Silo/Grains/Activation/IProjectionGrainActivator.cs +++ b/src/Aevatar.Silo/Grains/Activation/IProjectionGrainActivator.cs @@ -1,13 +1,12 @@ -namespace Aevatar.Silo.Grains.Activation +namespace Aevatar.Silo.Grains.Activation; + +/// +/// Interface for projection grain activator +/// +public interface IProjectionGrainActivator { /// - /// Interface for projection grain activator + /// Activates a projection grain for the given state type /// - public interface IProjectionGrainActivator - { - /// - /// Activates a projection grain for the given state type - /// - Task ActivateProjectionGrainAsync(Type stateType, CancellationToken cancellationToken); - } -} \ No newline at end of file + Task ActivateProjectionGrainAsync(Type stateType, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Aevatar.Silo/Grains/Activation/ProjectionGrainActivator.cs b/src/Aevatar.Silo/Grains/Activation/ProjectionGrainActivator.cs index 78836ee80..a302fa384 100644 --- a/src/Aevatar.Silo/Grains/Activation/ProjectionGrainActivator.cs +++ b/src/Aevatar.Silo/Grains/Activation/ProjectionGrainActivator.cs @@ -3,58 +3,57 @@ using Aevatar.Silo.IdGeneration; using Microsoft.Extensions.Logging; -namespace Aevatar.Silo.Grains.Activation +namespace Aevatar.Silo.Grains.Activation; + +/// +/// Default implementation of IProjectionGrainActivator +/// +public class ProjectionGrainActivator : IProjectionGrainActivator { - /// - /// Default implementation of IProjectionGrainActivator - /// - public class ProjectionGrainActivator : IProjectionGrainActivator + private readonly IGrainFactory _grainFactory; + private readonly IDeterministicIdGenerator _idGenerator; + private readonly ILogger _logger; + + public ProjectionGrainActivator( + IGrainFactory grainFactory, + IDeterministicIdGenerator idGenerator, + ILogger logger) { - private readonly IGrainFactory _grainFactory; - private readonly IDeterministicIdGenerator _idGenerator; - private readonly ILogger _logger; - - public ProjectionGrainActivator( - IGrainFactory grainFactory, - IDeterministicIdGenerator idGenerator, - ILogger logger) - { - _grainFactory = grainFactory; - _idGenerator = idGenerator; - _logger = logger; - } + _grainFactory = grainFactory; + _idGenerator = idGenerator; + _logger = logger; + } + + public async Task ActivateProjectionGrainAsync(Type stateType, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); - public async Task ActivateProjectionGrainAsync(Type stateType, CancellationToken cancellationToken) + try { - cancellationToken.ThrowIfCancellationRequested(); - - try - { - _logger.LogInformation("Activating StateProjectionGrain for {StateType}", stateType.Name); - - // Get the generic StateProjectionGrain type with this StateBase type - var grainType = typeof(IProjectionGrain<>).MakeGenericType(stateType); - - - // Get the grain and activate it - for (int i = 0; i < AevatarCoreConstants.DefaultNumOfProjectorPerAgentType; i++) - { - // Create a deterministic GUID based on the state type name - var grainId = _idGenerator.CreateDeterministicGuid(stateType.FullName + i.ToString()); - RequestContext.Set("id", i); - var grain = _grainFactory.GetGrain(grainType, grainId).Cast(grainType); - var method = grainType.GetMethod("ActivateAsync"); - await (Task)method?.Invoke(grain, null)!; - - _logger.LogInformation("Successfully activated StateProjectionGrain for {StateType} with ID {GrainId}", - stateType.Name, grainId); - } - } - catch (Exception ex) + _logger.LogInformation("Activating StateProjectionGrain for {StateType}", stateType.Name); + + // Get the generic StateProjectionGrain type with this StateBase type + var grainType = typeof(IProjectionGrain<>).MakeGenericType(stateType); + + // Get the grain and activate it + for (int i = 0; i < AevatarCoreConstants.DefaultNumOfProjectorPerAgentType; i++) { - _logger.LogError(ex, "Error activating StateProjectionGrain for {StateType}", stateType.Name); - throw; + // Create a deterministic GUID based on the state type name + var grainId = _idGenerator.CreateDeterministicGuid(stateType.FullName + i.ToString()); + RequestContext.Set("id", i); + var grain = _grainFactory.GetGrain(grainType, grainId).Cast(grainType); + var method = grainType.GetMethod("ActivateAsync"); + await (Task)method?.Invoke(grain, null)!; + + _logger.LogInformation( + "Successfully activated StateProjectionGrain for {StateType} with ID {GrainId}", + stateType.Name, grainId); } } + catch (Exception ex) + { + _logger.LogError(ex, "Error activating StateProjectionGrain for {StateType}", stateType.Name); + throw; + } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.Silo/IdGeneration/IDeterministicIdGenerator.cs b/src/Aevatar.Silo/IdGeneration/IDeterministicIdGenerator.cs index 2c5ae2d85..1b57953d9 100644 --- a/src/Aevatar.Silo/IdGeneration/IDeterministicIdGenerator.cs +++ b/src/Aevatar.Silo/IdGeneration/IDeterministicIdGenerator.cs @@ -1,13 +1,12 @@ -namespace Aevatar.Silo.IdGeneration +namespace Aevatar.Silo.IdGeneration; + +/// +/// Interface for generating deterministic IDs +/// +public interface IDeterministicIdGenerator { /// - /// Interface for generating deterministic IDs + /// Creates a deterministic GUID based on a string input /// - public interface IDeterministicIdGenerator - { - /// - /// Creates a deterministic GUID based on a string input - /// - Guid CreateDeterministicGuid(string input); - } -} \ No newline at end of file + Guid CreateDeterministicGuid(string input); +} \ No newline at end of file diff --git a/src/Aevatar.Silo/IdGeneration/MD5DeterministicIdGenerator.cs b/src/Aevatar.Silo/IdGeneration/MD5DeterministicIdGenerator.cs index e3c0b1730..76c729a0e 100644 --- a/src/Aevatar.Silo/IdGeneration/MD5DeterministicIdGenerator.cs +++ b/src/Aevatar.Silo/IdGeneration/MD5DeterministicIdGenerator.cs @@ -1,29 +1,26 @@ using System.Text; using System.Security.Cryptography; -namespace Aevatar.Silo.IdGeneration +namespace Aevatar.Silo.IdGeneration; + +/// +/// Default implementation of IDeterministicIdGenerator using MD5 +/// +public class MD5DeterministicIdGenerator : IDeterministicIdGenerator { - /// - /// Default implementation of IDeterministicIdGenerator using MD5 - /// - public class MD5DeterministicIdGenerator : IDeterministicIdGenerator + public Guid CreateDeterministicGuid(string input) { - public Guid CreateDeterministicGuid(string input) + if (string.IsNullOrEmpty(input)) { - if (string.IsNullOrEmpty(input)) - { - throw new ArgumentException("Input cannot be null or empty", nameof(input)); - } - - // Use a simple and consistent way to convert the type name to a GUID - using (var md5 = MD5.Create()) - { - // Get MD5 hash of the input string - byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input)); - - // MD5 produces a 16-byte hash which is exactly the size of a GUID - return new Guid(hashBytes); - } + throw new ArgumentException("Input cannot be null or empty", nameof(input)); } + + // Use a simple and consistent way to convert the type name to a GUID + using var md5 = MD5.Create(); + // Get MD5 hash of the input string + var hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input)); + + // MD5 produces a 16-byte hash which is exactly the size of a GUID + return new Guid(hashBytes); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.Silo/Observability/GrainStorageDecoratorExtensions.cs b/src/Aevatar.Silo/Observability/GrainStorageDecoratorExtensions.cs index f7d61bbeb..ea5ed3948 100644 --- a/src/Aevatar.Silo/Observability/GrainStorageDecoratorExtensions.cs +++ b/src/Aevatar.Silo/Observability/GrainStorageDecoratorExtensions.cs @@ -2,116 +2,114 @@ using Microsoft.Extensions.Logging; using Orleans.Storage; -namespace Aevatar.Silo.Observability +namespace Aevatar.Silo.Observability; + +/// +/// Extension methods for registering grain storage decorators +/// +public static class GrainStorageDecoratorExtensions { /// - /// Extension methods for registering grain storage decorators + /// Replaces the default IGrainStorage implementation with a MetricsGrainStorage decorator /// - public static class GrainStorageDecoratorExtensions + /// The service collection + /// The service collection for chaining + public static IServiceCollection ReplaceDefaultImplementation(this IServiceCollection services) { - /// - /// Replaces the default IGrainStorage implementation with a MetricsGrainStorage decorator - /// - /// The service collection - /// The service collection for chaining - public static IServiceCollection ReplaceDefaultImplementation(this IServiceCollection services) - { - var originalDescriptor = services.FirstOrDefault( - sd => - !sd.IsKeyedService && - sd.ServiceType == typeof(IGrainStorage)); - - if (originalDescriptor == null) - return services; - - // Remove the original registration - services.Remove(originalDescriptor); - - Func innerFactory = null; - - if (originalDescriptor.ImplementationFactory != null) - { - innerFactory = (sp) => (IGrainStorage)originalDescriptor.ImplementationFactory(sp); - } - else if (originalDescriptor.ImplementationInstance != null) - { - innerFactory = (sp) => (IGrainStorage)originalDescriptor.ImplementationInstance; - } - else - { - innerFactory = (sp) => - (IGrainStorage)sp.GetRequiredService(originalDescriptor.ImplementationType); - } - - // Add the decorator with the original key - services.AddSingleton((sp) => - new MetricsGrainStorage( - innerFactory(sp), - sp.GetRequiredService>())); - + var originalDescriptor = services.FirstOrDefault(sd => + !sd.IsKeyedService && + sd.ServiceType == typeof(IGrainStorage)); + + if (originalDescriptor == null) return services; - } - /// - /// Replaces a keyed IGrainStorage implementation with a MetricsGrainStorage decorator - /// - /// The service collection - /// The key name of the service to replace - /// The service collection for chaining - public static IServiceCollection ReplaceKeyedImplementation(this IServiceCollection services, string name) + // Remove the original registration + services.Remove(originalDescriptor); + + Func innerFactory = null; + + if (originalDescriptor.ImplementationFactory != null) + { + innerFactory = (sp) => (IGrainStorage)originalDescriptor.ImplementationFactory(sp); + } + else if (originalDescriptor.ImplementationInstance != null) + { + innerFactory = (sp) => (IGrainStorage)originalDescriptor.ImplementationInstance; + } + else { - var originalDescriptor = services.FirstOrDefault(sd => - sd.ServiceKey?.ToString() == name && - sd.ServiceType == typeof(IGrainStorage)); - - if (originalDescriptor == null) - return services; - - // Remove the original registration - services.Remove(originalDescriptor); - - Func innerFactory = null; - - if (originalDescriptor.KeyedImplementationFactory != null) - { - innerFactory = (sp, key) => (IGrainStorage)originalDescriptor.KeyedImplementationFactory(sp, key); - } - else if (originalDescriptor.KeyedImplementationInstance != null) - { - innerFactory = (sp, key) => (IGrainStorage)originalDescriptor.KeyedImplementationInstance; - } - else - { - innerFactory = (sp, key) => - (IGrainStorage)sp.GetRequiredService(originalDescriptor.KeyedImplementationType); - } - - // Add the decorator with the original key - services.AddKeyedSingleton(name, (sp, key) => - new MetricsGrainStorage( - innerFactory(sp, key), - sp.GetRequiredService>())); - + innerFactory = (sp) => + (IGrainStorage)sp.GetRequiredService(originalDescriptor.ImplementationType); + } + + // Add the decorator with the original key + services.AddSingleton((sp) => + new MetricsGrainStorage( + innerFactory(sp), + sp.GetRequiredService>())); + + return services; + } + + /// + /// Replaces a keyed IGrainStorage implementation with a MetricsGrainStorage decorator + /// + /// The service collection + /// The key name of the service to replace + /// The service collection for chaining + public static IServiceCollection ReplaceKeyedImplementation(this IServiceCollection services, string name) + { + var originalDescriptor = services.FirstOrDefault(sd => + sd.ServiceKey?.ToString() == name && + sd.ServiceType == typeof(IGrainStorage)); + + if (originalDescriptor == null) return services; + + // Remove the original registration + services.Remove(originalDescriptor); + + Func innerFactory = null; + + if (originalDescriptor.KeyedImplementationFactory != null) + { + innerFactory = (sp, key) => (IGrainStorage)originalDescriptor.KeyedImplementationFactory(sp, key); + } + else if (originalDescriptor.KeyedImplementationInstance != null) + { + innerFactory = (sp, key) => (IGrainStorage)originalDescriptor.KeyedImplementationInstance; + } + else + { + innerFactory = (sp, key) => + (IGrainStorage)sp.GetRequiredService(originalDescriptor.KeyedImplementationType); } - /// - /// Wraps all registered IGrainStorage implementations with MetricsGrainStorage decorators - /// - /// The service collection - /// The service collection for chaining - public static IServiceCollection UseGrainStorageWithMetrics(this IServiceCollection services) + // Add the decorator with the original key + services.AddKeyedSingleton(name, (sp, key) => + new MetricsGrainStorage( + innerFactory(sp, key), + sp.GetRequiredService>())); + + return services; + } + + /// + /// Wraps all registered IGrainStorage implementations with MetricsGrainStorage decorators + /// + /// The service collection + /// The service collection for chaining + public static IServiceCollection UseGrainStorageWithMetrics(this IServiceCollection services) + { + var allKeys = services.Where(s => s.IsKeyedService && s.ServiceType == typeof(IGrainStorage)) + .Select(s => s.ServiceKey.ToString()).ToList(); + + foreach (var key in allKeys) { - var allKeys = services.Where(s => s.IsKeyedService && s.ServiceType == typeof(IGrainStorage)) - .Select(s => s.ServiceKey.ToString()).ToList(); - - foreach (var key in allKeys) - { - services.ReplaceKeyedImplementation(key); - } - - services.ReplaceDefaultImplementation(); - return services; + services.ReplaceKeyedImplementation(key); } + + services.ReplaceDefaultImplementation(); + return services; } -} +} \ No newline at end of file diff --git a/src/Aevatar.Silo/Observability/MetricsGrainStorage.cs b/src/Aevatar.Silo/Observability/MetricsGrainStorage.cs index ec57685e1..3dd80fc50 100644 --- a/src/Aevatar.Silo/Observability/MetricsGrainStorage.cs +++ b/src/Aevatar.Silo/Observability/MetricsGrainStorage.cs @@ -2,196 +2,195 @@ using Microsoft.Extensions.Logging; using Orleans.Storage; -namespace Aevatar.Silo.Observability +namespace Aevatar.Silo.Observability; + +/// +/// A decorator for IGrainStorage that collects performance metrics +/// +public class MetricsGrainStorage : IGrainStorage { - /// - /// A decorator for IGrainStorage that collects performance metrics - /// - public class MetricsGrainStorage : IGrainStorage + private readonly IGrainStorage _inner; + private readonly ILogger _logger; + private readonly Meter _meter; + private readonly Histogram _readDurationHistogram; + private readonly Histogram _writeDurationHistogram; + private readonly Histogram _clearDurationHistogram; + private readonly Counter _readCounter; + private readonly Counter _writeCounter; + private readonly Counter _clearCounter; + private readonly Counter _readErrorCounter; + private readonly Counter _writeErrorCounter; + private readonly Counter _clearErrorCounter; + + private const string MeterName = "Aevatar.Storage"; + + public MetricsGrainStorage( + IGrainStorage inner, + ILogger logger) + { + _inner = inner; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + // Initialize metrics + _meter = new Meter(MeterName, "1.0.0"); + + // Create histograms for operation durations + _readDurationHistogram = _meter.CreateHistogram( + name: "aevatar_grain_storage_read_duration", + unit: "ms", + description: "Duration of grain state read operations"); + + _writeDurationHistogram = _meter.CreateHistogram( + name: "aevatar_grain_storage_write_duration", + unit: "ms", + description: "Duration of grain state write operations"); + + _clearDurationHistogram = _meter.CreateHistogram( + name: "aevatar_grain_storage_clear_duration", + unit: "ms", + description: "Duration of grain state clear operations"); + + // Create counters for operation counts + _readCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_read_count", + unit: "operations", + description: "Number of grain state read operations"); + + _writeCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_write_count", + unit: "operations", + description: "Number of grain state write operations"); + + _clearCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_clear_count", + unit: "operations", + description: "Number of grain state clear operations"); + + // Create counters for error counts + _readErrorCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_read_errors", + unit: "errors", + description: "Number of errors during grain state read operations"); + + _writeErrorCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_write_errors", + unit: "errors", + description: "Number of errors during grain state write operations"); + + _clearErrorCounter = _meter.CreateCounter( + name: "aevatar_grain_storage_clear_errors", + unit: "errors", + description: "Number of errors during grain state clear operations"); + } + + public async Task ReadStateAsync(string stateName, GrainId grainId, IGrainState grainState) { - private readonly IGrainStorage _inner; - private readonly ILogger _logger; - private readonly Meter _meter; - private readonly Histogram _readDurationHistogram; - private readonly Histogram _writeDurationHistogram; - private readonly Histogram _clearDurationHistogram; - private readonly Counter _readCounter; - private readonly Counter _writeCounter; - private readonly Counter _clearCounter; - private readonly Counter _readErrorCounter; - private readonly Counter _writeErrorCounter; - private readonly Counter _clearErrorCounter; - - private const string MeterName = "Aevatar.Storage"; - - public MetricsGrainStorage( - IGrainStorage inner, - ILogger logger) + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + try { - _inner = inner; - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - - // Initialize metrics - _meter = new Meter(MeterName, "1.0.0"); - - // Create histograms for operation durations - _readDurationHistogram = _meter.CreateHistogram( - name: "aevatar_grain_storage_read_duration", - unit: "ms", - description: "Duration of grain state read operations"); - - _writeDurationHistogram = _meter.CreateHistogram( - name: "aevatar_grain_storage_write_duration", - unit: "ms", - description: "Duration of grain state write operations"); - - _clearDurationHistogram = _meter.CreateHistogram( - name: "aevatar_grain_storage_clear_duration", - unit: "ms", - description: "Duration of grain state clear operations"); - - // Create counters for operation counts - _readCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_read_count", - unit: "operations", - description: "Number of grain state read operations"); - - _writeCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_write_count", - unit: "operations", - description: "Number of grain state write operations"); - - _clearCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_clear_count", - unit: "operations", - description: "Number of grain state clear operations"); - - // Create counters for error counts - _readErrorCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_read_errors", - unit: "errors", - description: "Number of errors during grain state read operations"); - - _writeErrorCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_write_errors", - unit: "errors", - description: "Number of errors during grain state write operations"); - - _clearErrorCounter = _meter.CreateCounter( - name: "aevatar_grain_storage_clear_errors", - unit: "errors", - description: "Number of errors during grain state clear operations"); - } + // Increment operation counter + _readCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + await _inner.ReadStateAsync(stateName, grainId, grainState); + + stopwatch.Stop(); + var duration = stopwatch.ElapsedMilliseconds; - public async Task ReadStateAsync(string stateName, GrainId grainId, IGrainState grainState) + // Record duration metric + _readDurationHistogram.Record(duration, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + _logger.LogTrace("Read state for grain {GrainId} completed in {Duration}ms", + grainId.ToString(), duration); + } + catch (Exception ex) { - var stopwatch = System.Diagnostics.Stopwatch.StartNew(); - - try - { - // Increment operation counter - _readCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - await _inner.ReadStateAsync(stateName, grainId, grainState); - - stopwatch.Stop(); - var duration = stopwatch.ElapsedMilliseconds; - - // Record duration metric - _readDurationHistogram.Record(duration, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - _logger.LogTrace("Read state for grain {GrainId} completed in {Duration}ms", - grainId.ToString(), duration); - } - catch (Exception ex) - { - // Increment error counter - _readErrorCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName), - new KeyValuePair("errorType", ex.GetType().Name)); - - _logger.LogError(ex, "Error reading state for grain {GrainId}", grainId); - throw; - } + // Increment error counter + _readErrorCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName), + new KeyValuePair("errorType", ex.GetType().Name)); + + _logger.LogError(ex, "Error reading state for grain {GrainId}", grainId); + throw; } + } + + public async Task WriteStateAsync(string stateName, GrainId grainId, IGrainState grainState) + { + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); - public async Task WriteStateAsync(string stateName, GrainId grainId, IGrainState grainState) + try { - var stopwatch = System.Diagnostics.Stopwatch.StartNew(); - - try - { - // Increment operation counter - _writeCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - await _inner.WriteStateAsync(stateName, grainId, grainState); - - stopwatch.Stop(); - var duration = stopwatch.ElapsedMilliseconds; - - // Record duration metric - _writeDurationHistogram.Record(duration, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - _logger.LogTrace("Write state for grain {GrainId} completed in {Duration}ms", - grainId.ToString(), duration); - } - catch (Exception ex) - { - // Increment error counter - _writeErrorCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName), - new KeyValuePair("errorType", ex.GetType().Name)); - - _logger.LogError(ex, "Error writing state for grain {GrainId}", grainId); - throw; - } + // Increment operation counter + _writeCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + await _inner.WriteStateAsync(stateName, grainId, grainState); + + stopwatch.Stop(); + var duration = stopwatch.ElapsedMilliseconds; + + // Record duration metric + _writeDurationHistogram.Record(duration, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + _logger.LogTrace("Write state for grain {GrainId} completed in {Duration}ms", + grainId.ToString(), duration); } + catch (Exception ex) + { + // Increment error counter + _writeErrorCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName), + new KeyValuePair("errorType", ex.GetType().Name)); - public async Task ClearStateAsync(string stateName, GrainId grainId, IGrainState grainState) + _logger.LogError(ex, "Error writing state for grain {GrainId}", grainId); + throw; + } + } + + public async Task ClearStateAsync(string stateName, GrainId grainId, IGrainState grainState) + { + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + try + { + // Increment operation counter + _clearCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + await _inner.ClearStateAsync(stateName, grainId, grainState); + + stopwatch.Stop(); + var duration = stopwatch.ElapsedMilliseconds; + + // Record duration metric + _clearDurationHistogram.Record(duration, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName)); + + _logger.LogTrace("Clear state for grain {GrainId} completed in {Duration}ms", + grainId.ToString(), duration); + } + catch (Exception ex) { - var stopwatch = System.Diagnostics.Stopwatch.StartNew(); - - try - { - // Increment operation counter - _clearCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - await _inner.ClearStateAsync(stateName, grainId, grainState); - - stopwatch.Stop(); - var duration = stopwatch.ElapsedMilliseconds; - - // Record duration metric - _clearDurationHistogram.Record(duration, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName)); - - _logger.LogTrace("Clear state for grain {GrainId} completed in {Duration}ms", - grainId.ToString(), duration); - } - catch (Exception ex) - { - // Increment error counter - _clearErrorCounter.Add(1, - new KeyValuePair("grainType", typeof(T).Name), - new KeyValuePair("stateName", stateName), - new KeyValuePair("errorType", ex.GetType().Name)); - - _logger.LogError(ex, "Error clearing state for grain {GrainId}", grainId); - throw; - } + // Increment error counter + _clearErrorCounter.Add(1, + new KeyValuePair("grainType", typeof(T).Name), + new KeyValuePair("stateName", stateName), + new KeyValuePair("errorType", ex.GetType().Name)); + + _logger.LogError(ex, "Error clearing state for grain {GrainId}", grainId); + throw; } } -} +} \ No newline at end of file diff --git a/src/Aevatar.Silo/SiloModule.cs b/src/Aevatar.Silo/SiloModule.cs index 66ec5573e..a2c78f53a 100644 --- a/src/Aevatar.Silo/SiloModule.cs +++ b/src/Aevatar.Silo/SiloModule.cs @@ -33,20 +33,17 @@ public override void ConfigureServices(ServiceConfigurationContext context) Configure(options => { options.AddMaps(); }); context.Services.AddHostedService(); var configuration = context.Services.GetConfiguration(); - //add dependencies here - context.Services.AddSerilog(loggerConfiguration => {}, + // Add dependencies here + context.Services.AddSerilog(_ => { }, true, writeToProviders: true); context.Services.AddHttpClient(); context.Services.AddSignalR().AddOrleans(); - Configure(options => - { - options.IsDynamicPermissionStoreEnabled = true; - }); - + Configure(options => { options.IsDynamicPermissionStoreEnabled = true; }); + context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); - + context.Services.Configure(context.Services.GetConfiguration().GetSection("Host")); context.Services.Configure(configuration); } diff --git a/src/Aevatar.Silo/Startup/StateProjectionInitializer.cs b/src/Aevatar.Silo/Startup/StateProjectionInitializer.cs index e509957af..a0b28562e 100644 --- a/src/Aevatar.Silo/Startup/StateProjectionInitializer.cs +++ b/src/Aevatar.Silo/Startup/StateProjectionInitializer.cs @@ -3,57 +3,56 @@ using Aevatar.Silo.TypeDiscovery; using Microsoft.Extensions.Logging; -namespace Aevatar.Silo.Startup +namespace Aevatar.Silo.Startup; + +/// +/// Startup task that initializes all StateProjectionGrains when the silo starts +/// +public class StateProjectionInitializer : IStartupTask { - /// - /// Startup task that initializes all StateProjectionGrains when the silo starts - /// - public class StateProjectionInitializer : IStartupTask + private readonly IStateTypeDiscoverer _typeDiscoverer; + private readonly IProjectionGrainActivator _grainActivator; + private readonly ILogger _logger; + + public StateProjectionInitializer( + IStateTypeDiscoverer typeDiscoverer, + IProjectionGrainActivator grainActivator, + ILogger logger) { - private readonly IStateTypeDiscoverer _typeDiscoverer; - private readonly IProjectionGrainActivator _grainActivator; - private readonly ILogger _logger; + _typeDiscoverer = typeDiscoverer; + _grainActivator = grainActivator; + _logger = logger; + } - public StateProjectionInitializer( - IStateTypeDiscoverer typeDiscoverer, - IProjectionGrainActivator grainActivator, - ILogger logger) - { - _typeDiscoverer = typeDiscoverer; - _grainActivator = grainActivator; - _logger = logger; - } + public async Task Execute(CancellationToken cancellationToken) + { + _logger.LogInformation("Starting to initialize StateProjectionGrains..."); - public async Task Execute(CancellationToken cancellationToken) + try { - _logger.LogInformation("Starting to initialize StateProjectionGrains..."); - - try + // Get all types that inherit from StateBase + var stateBaseTypes = _typeDiscoverer.GetAllInheritedTypesOf(typeof(StateBase)); + _logger.LogInformation("Found {Count} StateBase inherited types", stateBaseTypes.Count); + + // For each StateBase type, get the corresponding StateProjectionGrain and activate it + foreach (var stateType in stateBaseTypes) { - // Get all types that inherit from StateBase - var stateBaseTypes = _typeDiscoverer.GetAllInheritedTypesOf(typeof(StateBase)); - _logger.LogInformation("Found {Count} StateBase inherited types", stateBaseTypes.Count); - - // For each StateBase type, get the corresponding StateProjectionGrain and activate it - foreach (var stateType in stateBaseTypes) + try { - try - { - await _grainActivator.ActivateProjectionGrainAsync(stateType, cancellationToken); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error activating StateProjectionGrain for {StateType}", stateType.Name); - } + await _grainActivator.ActivateProjectionGrainAsync(stateType, cancellationToken); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error activating StateProjectionGrain for {StateType}", stateType.Name); } - - _logger.LogInformation("Completed initializing StateProjectionGrains"); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error during StateProjectionGrains initialization"); - throw; // Rethrow to fail the silo startup if initialization fails } + + _logger.LogInformation("Completed initializing StateProjectionGrains"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error during StateProjectionGrains initialization"); + throw; // Rethrow to fail the silo startup if initialization fails } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.Silo/TypeDiscovery/IStateTypeDiscoverer.cs b/src/Aevatar.Silo/TypeDiscovery/IStateTypeDiscoverer.cs index 56c8ddd94..aa9784b2e 100644 --- a/src/Aevatar.Silo/TypeDiscovery/IStateTypeDiscoverer.cs +++ b/src/Aevatar.Silo/TypeDiscovery/IStateTypeDiscoverer.cs @@ -1,13 +1,12 @@ -namespace Aevatar.Silo.TypeDiscovery +namespace Aevatar.Silo.TypeDiscovery; + +/// +/// Interface for discovering state types in assemblies +/// +public interface IStateTypeDiscoverer { /// - /// Interface for discovering state types in assemblies + /// Gets all non-abstract types that inherit from the specified base type /// - public interface IStateTypeDiscoverer - { - /// - /// Gets all non-abstract types that inherit from the specified base type - /// - List GetAllInheritedTypesOf(Type baseType); - } -} \ No newline at end of file + List GetAllInheritedTypesOf(Type baseType); +} \ No newline at end of file diff --git a/src/Aevatar.Silo/TypeDiscovery/StateTypeDiscoverer.cs b/src/Aevatar.Silo/TypeDiscovery/StateTypeDiscoverer.cs index 4e0c6ceac..f802533e8 100644 --- a/src/Aevatar.Silo/TypeDiscovery/StateTypeDiscoverer.cs +++ b/src/Aevatar.Silo/TypeDiscovery/StateTypeDiscoverer.cs @@ -1,55 +1,54 @@ using Microsoft.Extensions.Logging; -namespace Aevatar.Silo.TypeDiscovery +namespace Aevatar.Silo.TypeDiscovery; + +/// +/// Default implementation of IStateTypeDiscoverer +/// +public class StateTypeDiscoverer : IStateTypeDiscoverer { - /// - /// Default implementation of IStateTypeDiscoverer - /// - public class StateTypeDiscoverer : IStateTypeDiscoverer + private readonly ILogger _logger; + + public StateTypeDiscoverer(ILogger logger) { - private readonly ILogger _logger; + _logger = logger; + } - public StateTypeDiscoverer(ILogger logger) - { - _logger = logger; - } + public List GetAllInheritedTypesOf(Type baseType) + { + var result = new List(); + + // Get all loaded assemblies + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - public List GetAllInheritedTypesOf(Type baseType) + foreach (var assembly in assemblies) { - var result = new List(); - - // Get all loaded assemblies - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - foreach (var assembly in assemblies) + try { - try + // Skip system assemblies + if (assembly.FullName != null && (assembly.FullName.StartsWith("System.") || + assembly.FullName.StartsWith("Microsoft.") || + assembly.FullName.StartsWith("mscorlib"))) { - // Skip system assemblies - if (assembly.FullName != null && (assembly.FullName.StartsWith("System.") || - assembly.FullName.StartsWith("Microsoft.") || - assembly.FullName.StartsWith("mscorlib"))) - { - continue; - } - - // Get all types that inherit from the base type - var types = assembly.GetTypes() - .Where(t => baseType.IsAssignableFrom(t) && - t != baseType && - !t.IsAbstract && - !t.IsInterface) - .ToList(); - - result.AddRange(types); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Error getting types from assembly {AssemblyName}", assembly.FullName); + continue; } + + // Get all types that inherit from the base type + var types = assembly.GetTypes() + .Where(t => baseType.IsAssignableFrom(t) && + t != baseType && + !t.IsAbstract && + !t.IsInterface) + .ToList(); + + result.AddRange(types); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Error getting types from assembly {AssemblyName}", assembly.FullName); } - - return result; } + + return result; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Aevatar.WebHook.Deploy/IHostDeployManager.cs b/src/Aevatar.WebHook.Deploy/IHostDeployManager.cs index fb36addc0..1563a8d2a 100644 --- a/src/Aevatar.WebHook.Deploy/IHostDeployManager.cs +++ b/src/Aevatar.WebHook.Deploy/IHostDeployManager.cs @@ -4,12 +4,11 @@ public interface IHostDeployManager { Task CreateNewWebHookAsync(string appId, string version, string imageName); Task DestroyWebHookAsync(string appId, string version); - Task RestartWebHookAsync(string appId,string version); - + Task RestartWebHookAsync(string appId, string version); + Task CreateHostAsync(string appId, string version, string corsUrls); Task DestroyHostAsync(string appId, string version); - Task RestartHostAsync(string appId,string version); + Task RestartHostAsync(string appId, string version); public Task UpdateDockerImageAsync(string appId, string version, string newImage); - } \ No newline at end of file diff --git a/src/Aevatar.Worker/Dapr/DaprTestWorker.cs b/src/Aevatar.Worker/Dapr/DaprTestWorker.cs index 4b2499a63..438d52a10 100644 --- a/src/Aevatar.Worker/Dapr/DaprTestWorker.cs +++ b/src/Aevatar.Worker/Dapr/DaprTestWorker.cs @@ -9,13 +9,12 @@ namespace Aevatar.Worker.Dapr; public class DaprTestWorker : AsyncPeriodicBackgroundWorkerBase { private readonly IDaprProvider _daprProvider; + public DaprTestWorker( AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory, IDaprProvider daprProvider - ) : base( - timer, - serviceScopeFactory) + ) : base(timer, serviceScopeFactory) { _daprProvider = daprProvider; Timer.Period = 10000; //10 seconds diff --git a/src/Aevatar.Worker/Program.cs b/src/Aevatar.Worker/Program.cs index ea0574d6d..da68a6885 100644 --- a/src/Aevatar.Worker/Program.cs +++ b/src/Aevatar.Worker/Program.cs @@ -7,60 +7,59 @@ using Serilog.Events; using Serilog.Sinks.OpenTelemetry; -namespace Aevatar.Worker +namespace Aevatar.Worker; + +public class Program { - public class Program + public static async Task Main(string[] args) { - public static async Task Main(string[] args) + ConfigureLogger(); + + try { - ConfigureLogger(); - - try - { - Log.Information("Starting Worker."); - var builder = WebApplication.CreateBuilder(args); - builder.Host - .AddAppSettingsSecretsJson() - .UseOrleansClientConfiguration() - .ConfigureDefaults(args) - .UseAutofac() - .UseSerilog(); - await builder.AddApplicationAsync(); - var app = builder.Build(); - await app.InitializeApplicationAsync(); - await app.RunAsync(); - await CreateHostBuilder(args).RunConsoleAsync(); - return 0; - } - catch (Exception ex) - { - Log.Fatal(ex, "Host terminated unexpectedly!"); - return 1; - } - finally - { - Log.CloseAndFlush(); - } + Log.Information("Starting Worker."); + var builder = WebApplication.CreateBuilder(args); + builder.Host + .AddAppSettingsSecretsJson() + .UseOrleansClientConfiguration() + .ConfigureDefaults(args) + .UseAutofac() + .UseSerilog(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + await CreateHostBuilder(args).RunConsoleAsync(); + return 0; } - - private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) - .ConfigureAppConfiguration(build => { build.AddJsonFile("appsettings.secrets.json", optional: true); }) - .ConfigureServices((hostContext, services) => { services.AddApplication(); }) - .UseAutofac() - .UseSerilog(); - - private static void ConfigureLogger(LoggerConfiguration? loggerConfiguration = null) + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally { - var configuration = new ConfigurationBuilder() - .AddJsonFile("appsettings.json") - .Build(); - Log.Logger = (loggerConfiguration ?? new LoggerConfiguration()) - .ReadFrom.Configuration(configuration) - .MinimumLevel.Information() - .MinimumLevel.Override("Microsoft", LogEventLevel.Information) - .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) - .Enrich.FromLogContext() - .CreateLogger(); + Log.CloseAndFlush(); } } + + private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .ConfigureAppConfiguration(build => { build.AddJsonFile("appsettings.secrets.json", optional: true); }) + .ConfigureServices((hostContext, services) => { services.AddApplication(); }) + .UseAutofac() + .UseSerilog(); + + private static void ConfigureLogger(LoggerConfiguration? loggerConfiguration = null) + { + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + Log.Logger = (loggerConfiguration ?? new LoggerConfiguration()) + .ReadFrom.Configuration(configuration) + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .Enrich.FromLogContext() + .CreateLogger(); + } } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/Account/AccountServiceTests.cs b/test/Aevatar.Application.Tests/Account/AccountServiceTests.cs index 9f5e6b9ed..8304bfe3b 100644 --- a/test/Aevatar.Application.Tests/Account/AccountServiceTests.cs +++ b/test/Aevatar.Application.Tests/Account/AccountServiceTests.cs @@ -14,13 +14,13 @@ public abstract class AccountServiceTests : AevatarApplicationTe where TStartupModule : IAbpModule { private readonly IAccountService _accountService; - private readonly IDistributedCache _registerCode; + private readonly IDistributedCache _registerCode; private readonly IdentityUserManager _identityUserManager; protected AccountServiceTests() { _accountService = GetRequiredService(); - _registerCode = GetRequiredService>(); + _registerCode = GetRequiredService>(); _identityUserManager = GetRequiredService(); } @@ -31,7 +31,7 @@ public async Task Register_Test() var user = await _identityUserManager.FindByEmailAsync(email); user.ShouldBeNull(); - + await _accountService.SendRegisterCodeAsync(new SendRegisterCodeDto { Email = email, @@ -63,25 +63,26 @@ await _accountService.SendRegisterCodeAsync(new SendRegisterCodeDto EmailAddress = email, UserName = "Tester" }; - - await Should.ThrowAsync(async ()=> await _accountService.RegisterAsync(registerInput)); + + await Should.ThrowAsync(async () => await _accountService.RegisterAsync(registerInput)); registerInput.Code = code; await _accountService.RegisterAsync(registerInput); - + user = await _identityUserManager.FindByEmailAsync(email); user.UserName.ShouldBe(registerInput.UserName); user.Email.ShouldBe(registerInput.EmailAddress); var checkPassword = await _identityUserManager.CheckPasswordAsync(user, registerInput.Password); checkPassword.ShouldBeTrue(); - - await Should.ThrowAsync(async ()=> await _accountService.SendRegisterCodeAsync(new SendRegisterCodeDto - { - Email = email, - AppName = "Aevatar", - UserName = "Tester" - })); + + await Should.ThrowAsync(async () => await _accountService.SendRegisterCodeAsync( + new SendRegisterCodeDto + { + Email = email, + AppName = "Aevatar", + UserName = "Tester" + })); } [Fact] @@ -95,19 +96,20 @@ await _accountService.SendPasswordResetCodeAsync(new SendPasswordResetCodeDto Email = user.Email, AppName = "Aevatar" }); - - var verifyResult = await _accountService.VerifyPasswordResetTokenAsync(new VerifyPasswordResetTokenInput() + + var verifyResult = await _accountService.VerifyPasswordResetTokenAsync(new VerifyPasswordResetTokenInput() { UserId = user.Id, ResetToken = "wrong token", }); verifyResult.ShouldBeFalse(); - - await Should.ThrowAsync(async ()=> await _accountService.ResetPasswordAsync(new ResetPasswordDto() - { - UserId = user.Id, - Password = "Abc@123", - ResetToken = "wrong token" - })); + + await Should.ThrowAsync(async () => await _accountService.ResetPasswordAsync( + new ResetPasswordDto + { + UserId = user.Id, + Password = "Abc@123", + ResetToken = "wrong token" + })); } } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/AevatarApplicationTestModule.cs b/test/Aevatar.Application.Tests/AevatarApplicationTestModule.cs index 3c0218ad2..0bb3476de 100644 --- a/test/Aevatar.Application.Tests/AevatarApplicationTestModule.cs +++ b/test/Aevatar.Application.Tests/AevatarApplicationTestModule.cs @@ -2,28 +2,19 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Aevatar.CQRS.Handler; -using Aevatar.Kubernetes.Manager; -using Aevatar.Options; -using Aevatar.SignalR; -using Aevatar.Mock; using Aevatar.SignalR; using Aevatar.SignalR.SignalRMessage; using Aevatar.WebHook.Deploy; using Elastic.Clients.Elasticsearch; using Elastic.Clients.Elasticsearch.Ingest; using Elastic.Transport; -using MediatR; using Microsoft.Extensions.DependencyInjection; -using MongoDB.Driver.Core.Configuration; using Moq; using Volo.Abp.AutoMapper; using Volo.Abp.Emailing; using Volo.Abp.EventBus; -using Volo.Abp.Identity; using Volo.Abp.Modularity; using ChatConfigOptions = Aevatar.Options.ChatConfigOptions; -using Moq; namespace Aevatar; @@ -56,10 +47,8 @@ public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddTransient(); context.Services.AddSingleton(); - - context.Services.AddTransient(o=>Moq.Mock.Of()); - + context.Services.AddTransient(o => Moq.Mock.Of()); AddMock(context.Services); } diff --git a/test/Aevatar.Application.Tests/ApiRequests/ApiRequestServiceTests.cs b/test/Aevatar.Application.Tests/ApiRequests/ApiRequestServiceTests.cs index 20b64f5d5..2ed7d2b5a 100644 --- a/test/Aevatar.Application.Tests/ApiRequests/ApiRequestServiceTests.cs +++ b/test/Aevatar.Application.Tests/ApiRequests/ApiRequestServiceTests.cs @@ -57,7 +57,7 @@ await _identityUserManager.CreateAsync( DomainName = "App" }; var project1 = await _projectService.CreateAsync(createProjectInput); - + var createProjectInput2 = new CreateProjectDto() { OrganizationId = organization.Id, @@ -69,19 +69,19 @@ await _identityUserManager.CreateAsync( await _projectAppIdService.CreateAsync(project1.Id, "TestKey1", _currentUser.Id); var apps = await _projectAppIdService.GetApiKeysAsync(project1.Id); var appId1 = apps[0].AppId; - + await _projectAppIdService.CreateAsync(project2.Id, "TestKey2", _currentUser.Id); apps = await _projectAppIdService.GetApiKeysAsync(project2.Id); var appId2 = apps[0].AppId; var startTime = new DateTime(2025, 1, 1, 10, 0, 0, DateTimeKind.Utc); - + await _apiRequestProvider.IncreaseRequestAsync(appId1, startTime.AddMinutes(1).AddSeconds(1)); await _apiRequestProvider.IncreaseRequestAsync(appId1, startTime.AddHours(2).AddMinutes(2).AddSeconds(2)); await _apiRequestProvider.IncreaseRequestAsync(appId2, startTime.AddHours(2).AddMinutes(3).AddSeconds(3)); await _apiRequestProvider.FlushAsync(); - + await _apiRequestProvider.IncreaseRequestAsync(appId1, startTime.AddMinutes(11).AddSeconds(1)); await _apiRequestProvider.IncreaseRequestAsync(appId1, startTime.AddHours(2).AddMinutes(12).AddSeconds(2)); await _apiRequestProvider.IncreaseRequestAsync(appId2, startTime.AddHours(2).AddMinutes(13).AddSeconds(3)); @@ -94,33 +94,33 @@ await _identityUserManager.CreateAsync( StartTime = DateTimeHelper.ToUnixTimeMilliseconds(startTime), EndTime = DateTimeHelper.ToUnixTimeMilliseconds(DateTime.UtcNow) }); - + apiRequests.Items.Count.ShouldBe(2); apiRequests.Items[0].Count.ShouldBe(2); apiRequests.Items[0].Time.ShouldBe(DateTimeHelper.ToUnixTimeMilliseconds(startTime)); apiRequests.Items[1].Count.ShouldBe(4); apiRequests.Items[1].Time.ShouldBe(DateTimeHelper.ToUnixTimeMilliseconds(startTime.AddHours(2))); - + apiRequests = await _apiRequestService.GetListAsync(new GetApiRequestDto { OrganizationId = project1.Id, StartTime = DateTimeHelper.ToUnixTimeMilliseconds(startTime), EndTime = DateTimeHelper.ToUnixTimeMilliseconds(DateTime.UtcNow) }); - + apiRequests.Items.Count.ShouldBe(2); apiRequests.Items[0].Count.ShouldBe(2); apiRequests.Items[0].Time.ShouldBe(DateTimeHelper.ToUnixTimeMilliseconds(startTime)); apiRequests.Items[1].Count.ShouldBe(2); apiRequests.Items[1].Time.ShouldBe(DateTimeHelper.ToUnixTimeMilliseconds(startTime.AddHours(2))); - + apiRequests = await _apiRequestService.GetListAsync(new GetApiRequestDto { OrganizationId = project2.Id, StartTime = DateTimeHelper.ToUnixTimeMilliseconds(startTime), EndTime = DateTimeHelper.ToUnixTimeMilliseconds(DateTime.UtcNow) }); - + apiRequests.Items.Count.ShouldBe(1); apiRequests.Items[0].Count.ShouldBe(2); apiRequests.Items[0].Time.ShouldBe(DateTimeHelper.ToUnixTimeMilliseconds(startTime.AddHours(2))); diff --git a/test/Aevatar.Application.Tests/GAgent/SubscriptionGAgentTests.cs b/test/Aevatar.Application.Tests/GAgent/SubscriptionGAgentTests.cs index 7c9c7e64f..37ac7abf3 100644 --- a/test/Aevatar.Application.Tests/GAgent/SubscriptionGAgentTests.cs +++ b/test/Aevatar.Application.Tests/GAgent/SubscriptionGAgentTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using Aevatar.Application.Grains.Subscription; using Aevatar.Domain.Grains.Subscription; @@ -14,6 +13,7 @@ public class SubscriptionGAgentTests : AevatarApplicationGrainsTestBase { private readonly IClusterClient _clusterClient; private readonly ITestOutputHelper _output; + public SubscriptionGAgentTests(ITestOutputHelper output) { _clusterClient = GetRequiredService(); @@ -23,21 +23,18 @@ public SubscriptionGAgentTests(ITestOutputHelper output) [Fact] public async Task AddSubscriptionTest() { - var eventSubscription = await _clusterClient.GetGrain(Guid.NewGuid()).SubscribeAsync( + var eventSubscription = await _clusterClient.GetGrain(Guid.NewGuid()).SubscribeAsync( new SubscribeEventInputDto { AgentId = Guid.NewGuid(), - EventTypes = new List() - { - "Created", "Updated" - }, + EventTypes = ["Created", "Updated"], CallbackUrl = "http://127.0.0.1" }); - eventSubscription.AgentId.ShouldNotBe(Guid.Empty); - eventSubscription.CallbackUrl.ShouldNotBeNullOrEmpty(); - eventSubscription.Status.ShouldBe("Active"); + eventSubscription.AgentId.ShouldNotBe(Guid.Empty); + eventSubscription.CallbackUrl.ShouldNotBeNullOrEmpty(); + eventSubscription.Status.ShouldBe("Active"); } - + [Fact] public async Task CancelSubscriptionTest() { @@ -49,17 +46,11 @@ await _clusterClient.GetGrain(subscriptionId).SubscribeAsyn new SubscribeEventInputDto { AgentId = Guid.NewGuid(), - EventTypes = new List() - { - "Created", "Updated" - }, + EventTypes = ["Created", "Updated"], CallbackUrl = "http://127.0.0.1" }); await _clusterClient.GetGrain(subscriptionId).UnsubscribeAsync(); subscription = await _clusterClient.GetGrain(subscriptionId).GetStateAsync(); subscription.Status.ShouldBe("Cancelled"); } - - - } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/Mock/ChatConfigOptions.cs b/test/Aevatar.Application.Tests/Mock/ChatConfigOptions.cs index 4349d047c..f4ddc5b35 100644 --- a/test/Aevatar.Application.Tests/Mock/ChatConfigOptions.cs +++ b/test/Aevatar.Application.Tests/Mock/ChatConfigOptions.cs @@ -4,5 +4,4 @@ public class ChatConfigOptions { public string Model { get; set; } public string APIKey { get; set; } - } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/Notification/NotificationTests.cs b/test/Aevatar.Application.Tests/Notification/NotificationTests.cs index 242e0cefb..27014436a 100644 --- a/test/Aevatar.Application.Tests/Notification/NotificationTests.cs +++ b/test/Aevatar.Application.Tests/Notification/NotificationTests.cs @@ -40,7 +40,7 @@ public NotificationTests() [Fact] public virtual async Task CreatNotification_Test() { - var response =await CreatNotificationAsync(); + var response = await CreatNotificationAsync(); response.ShouldNotBe(Guid.Empty); } @@ -56,7 +56,7 @@ public async Task WithdrawAsync_Test() Status = NotificationStatusEnum.None, CreationTime = DateTime.Now, CreatorId = _creator, - },true, _cancellation); + }, true, _cancellation); var response = await _notificationService.WithdrawAsync(_creator, notificationInfo.Id); response.ShouldBeTrue(); } @@ -66,12 +66,13 @@ public async Task ResponseAsync_Test() { await CreatNotificationAsync(); var notification = await _notificationRepository.FirstAsync(cancellationToken: _cancellation); - - var response = await _notificationService.Response(notification.Id, notification.Receiver, NotificationStatusEnum.Agree); + + var response = + await _notificationService.Response(notification.Id, notification.Receiver, NotificationStatusEnum.Agree); response.ShouldBeTrue(); } - + private async Task CreatNotificationAsync() { var owner = new IdentityUser(_currentUser.Id!.Value, "owner", "owner@email.io"); diff --git a/test/Aevatar.Application.Tests/Options/ChatConfigOptions.cs b/test/Aevatar.Application.Tests/Options/ChatConfigOptions.cs index c8a58dbb9..0aaf87349 100644 --- a/test/Aevatar.Application.Tests/Options/ChatConfigOptions.cs +++ b/test/Aevatar.Application.Tests/Options/ChatConfigOptions.cs @@ -4,5 +4,4 @@ public class ChatConfigOptions { public string Model { get; set; } public string APIKey { get; set; } - } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/Origanzations/OrganizationPermissionServiceTests.cs b/test/Aevatar.Application.Tests/Origanzations/OrganizationPermissionServiceTests.cs index 3395ef48b..219ad4858 100644 --- a/test/Aevatar.Application.Tests/Origanzations/OrganizationPermissionServiceTests.cs +++ b/test/Aevatar.Application.Tests/Origanzations/OrganizationPermissionServiceTests.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using System.Threading.Tasks; using Aevatar.Organizations; @@ -47,23 +46,24 @@ await _identityUserManager.CreateAsync( var permissions = await _organizationPermissionService.GetAsync(organization.Id, "R", OrganizationRoleHelper.GetRoleName(organization.Id, AevatarConsts.OrganizationReaderRoleName)); permissions.Groups.Count.ShouldBe(1); - permissions.Groups[0].Permissions.First(o=>o.Name == AevatarPermissions.Members.Manage).IsGranted.ShouldBeFalse(); + permissions.Groups[0].Permissions.First(o => o.Name == AevatarPermissions.Members.Manage).IsGranted + .ShouldBeFalse(); await _organizationPermissionService.UpdateAsync(organization.Id, "R", OrganizationRoleHelper.GetRoleName(organization.Id, AevatarConsts.OrganizationReaderRoleName), new UpdatePermissionsDto { - Permissions = new[] - { + Permissions = + [ new UpdatePermissionDto { Name = AevatarPermissions.Members.Manage, IsGranted = true } - } + ] }); } - + [Fact] public async Task Permission_ModifyOwner_Test() { @@ -78,15 +78,20 @@ await _identityUserManager.CreateAsync( DisplayName = "Test" }; var organization = await _organizationService.CreateAsync(createInput); - + await Should.ThrowAsync(async () => - await _organizationPermissionService.UpdateAsync(organization.Id, "R", OrganizationRoleHelper.GetRoleName(organization.Id,AevatarConsts.OrganizationOwnerRoleName), new UpdatePermissionsDto - { - Permissions = new []{new UpdatePermissionDto + await _organizationPermissionService.UpdateAsync(organization.Id, "R", + OrganizationRoleHelper.GetRoleName(organization.Id, AevatarConsts.OrganizationOwnerRoleName), + new UpdatePermissionsDto { - Name = AevatarPermissions.Organizations.Default, - IsGranted = false - }} - })); + Permissions = + [ + new UpdatePermissionDto + { + Name = AevatarPermissions.Organizations.Default, + IsGranted = false + } + ] + })); } } \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/Origanzations/OrganizationRoleServiceTests.cs b/test/Aevatar.Application.Tests/Origanzations/OrganizationRoleServiceTests.cs index ff4aa46a6..0124e9cda 100644 --- a/test/Aevatar.Application.Tests/Origanzations/OrganizationRoleServiceTests.cs +++ b/test/Aevatar.Application.Tests/Origanzations/OrganizationRoleServiceTests.cs @@ -24,7 +24,7 @@ public abstract class OrganizationRoleServiceTests : AevatarAppl private readonly IdentityRoleManager _roleManager; private readonly IPermissionManager _permissionManager; private readonly IOrganizationRoleService _organizationRoleService; - + protected OrganizationRoleServiceTests() { _organizationUnitManager = GetRequiredService(); @@ -36,7 +36,7 @@ protected OrganizationRoleServiceTests() _permissionManager = GetRequiredService(); _organizationRoleService = GetRequiredService(); } - + [Fact] public async Task Role_Test() { @@ -60,12 +60,12 @@ await _identityUserManager.CreateAsync( Name = "Dev" }; var role = await _organizationRoleService.CreateAsync(organization.Id, createRoleInput); - + roles = await _organizationRoleService.GetListAsync(organization.Id); roles.Items.Count.ShouldBe(3); roles.Items.First(o => o.Id == role.Id).Name.ShouldBe(OrganizationRoleHelper.GetRoleName(organization.Id, createRoleInput.Name)); - + var updateRoleInput = new IdentityRoleUpdateDto { Name = "Dev-2" @@ -97,7 +97,7 @@ await _identityUserManager.CreateAsync( DisplayName = "Test" }; var organization = await _organizationService.CreateAsync(createInput); - + var roles = await _organizationRoleService.GetListAsync(organization.Id); var ownerRole = roles.Items.First(o => o.Name.EndsWith(AevatarConsts.OrganizationOwnerRoleName)); @@ -106,11 +106,11 @@ await Should.ThrowAsync(async () => { Name = "NewName" })); - + await Should.ThrowAsync(async () => await _organizationRoleService.DeleteAsync(organization.Id, ownerRole.Id)); } - + [Fact] public async Task Role_WrongOrganization_Test() { @@ -126,7 +126,7 @@ await _identityUserManager.CreateAsync( }; var organization = await _organizationService.CreateAsync(createInput); var wrongOrganizationId = Guid.NewGuid(); - + var roles = await _organizationRoleService.GetListAsync(organization.Id); var readerRole = roles.Items.First(o => o.Name.EndsWith(AevatarConsts.OrganizationReaderRoleName)); @@ -135,7 +135,7 @@ await Should.ThrowAsync(async () => { Name = "NewName" })); - + await Should.ThrowAsync(async () => await _organizationRoleService.DeleteAsync(wrongOrganizationId, readerRole.Id)); } diff --git a/test/Aevatar.Application.Tests/Origanzations/OrganizationServiceTests.cs b/test/Aevatar.Application.Tests/Origanzations/OrganizationServiceTests.cs index cfad6c739..f256c7410 100644 --- a/test/Aevatar.Application.Tests/Origanzations/OrganizationServiceTests.cs +++ b/test/Aevatar.Application.Tests/Origanzations/OrganizationServiceTests.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Aevatar.Organizations; using Aevatar.Permissions; -using Aevatar.Projects; using Shouldly; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; @@ -103,10 +102,10 @@ await _identityUserManager.CreateAsync( var user = await _identityUserManager.GetByIdAsync(_currentUser.Id.Value); var isInRole = await _identityUserManager.IsInRoleAsync(user, ownerRole.Name); isInRole.ShouldBeTrue(); - + isInRole = await _identityUserManager.IsInRoleAsync(user, readerRole.Name); isInRole.ShouldBeFalse(); - + user.IsInOrganizationUnit(organization.Id).ShouldBeTrue(); } @@ -131,7 +130,7 @@ await _identityUserManager.CreateAsync( DisplayName = "Test New" }; await _organizationService.UpdateAsync(organization.Id, updateInput); - + organization = await _organizationService.GetAsync(organization.Id); organization.DisplayName.ShouldBe(updateInput.DisplayName); } @@ -150,7 +149,7 @@ await _identityUserManager.CreateAsync( DisplayName = "Test" }; var organization = await _organizationService.CreateAsync(createInput); - + var roles = await _organizationService.GetRoleListAsync(organization.Id); await _organizationService.DeleteAsync(organization.Id); @@ -162,11 +161,11 @@ await Should.ThrowAsync(async () => { await Should.ThrowAsync(async () => await _roleManager.GetByIdAsync(role.Id)); } - + var user = await _identityUserManager.GetByIdAsync(_currentUser.Id.Value); user.IsInOrganizationUnit(organization.Id).ShouldBeFalse(); } - + [Fact] public async Task Organization_SetMember_Test() { @@ -178,11 +177,11 @@ public async Task Organization_SetMember_Test() DisplayName = "Test" }; var organization = await _organizationService.CreateAsync(createInput); - + var roles = await _organizationService.GetRoleListAsync(organization.Id); var ownerRole = roles.Items.First(o => o.Name.EndsWith("Owner")); var readerRole = roles.Items.First(o => o.Name.EndsWith("Reader")); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(1); @@ -202,10 +201,10 @@ public async Task Organization_SetMember_Test() Join = true, RoleId = readerRole.Id }); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(2); - + members = await _organizationService.GetMemberListAsync(organization.Id, new GetOrganizationMemberListDto()); members.Items.Count.ShouldBe(2); @@ -220,20 +219,20 @@ public async Task Organization_SetMember_Test() UserId = readerUser.Id, RoleId = ownerRole.Id }); - + members = await _organizationService.GetMemberListAsync(organization.Id, new GetOrganizationMemberListDto()); members.Items.Count.ShouldBe(2); readerMember = members.Items.First(o => o.Id == readerUser.Id); readerMember.RoleId.ShouldBe(ownerRole.Id); readerMember.Status.ShouldBe(MemberStatus.Joined); - + await _organizationService.SetMemberAsync(organization.Id, new SetOrganizationMemberDto { Email = readerUser.Email, Join = false }); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(1); @@ -244,7 +243,7 @@ public async Task Organization_SetMember_Test() readerUser = await _identityUserManager.GetByIdAsync(readerUser.Id); readerUser.IsInOrganizationUnit(organization.Id).ShouldBeFalse(); } - + [Fact] public async Task Organization_DeletePendingMember_Test() { @@ -256,11 +255,11 @@ public async Task Organization_DeletePendingMember_Test() DisplayName = "Test" }; var organization = await _organizationService.CreateAsync(createInput); - + var roles = await _organizationService.GetRoleListAsync(organization.Id); var ownerRole = roles.Items.First(o => o.Name.EndsWith("Owner")); var readerRole = roles.Items.First(o => o.Name.EndsWith("Reader")); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(1); @@ -280,10 +279,10 @@ public async Task Organization_DeletePendingMember_Test() Join = true, RoleId = readerRole.Id }); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(2); - + members = await _organizationService.GetMemberListAsync(organization.Id, new GetOrganizationMemberListDto()); members.Items.Count.ShouldBe(2); @@ -292,13 +291,13 @@ public async Task Organization_DeletePendingMember_Test() readerMember.Email.ShouldBe(readerUser.Email); readerMember.RoleId.ShouldBe(null); readerMember.Status.ShouldBe(MemberStatus.Inviting); - + await _organizationService.SetMemberAsync(organization.Id, new SetOrganizationMemberDto { Email = readerUser.Email, Join = false }); - + organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(1); diff --git a/test/Aevatar.Application.Tests/Plugins/PluginServiceTests.cs b/test/Aevatar.Application.Tests/Plugins/PluginServiceTests.cs index ea2084845..3263153e8 100644 --- a/test/Aevatar.Application.Tests/Plugins/PluginServiceTests.cs +++ b/test/Aevatar.Application.Tests/Plugins/PluginServiceTests.cs @@ -1,10 +1,7 @@ using System; -using System.Linq; using System.Threading.Tasks; -using Aevatar.Plugins; using Shouldly; using Volo.Abp.Domain.Entities; -using Volo.Abp.Domain.Repositories; using Volo.Abp.Identity; using Volo.Abp.Modularity; using Volo.Abp.Users; @@ -100,4 +97,4 @@ await _identityUserManager.CreateAsync( await Should.ThrowAsync(async () => await _pluginRepository.GetAsync(plugin.Id)); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/test/Aevatar.Application.Tests/ProjectApiKey/ProjectApiKey_Test.cs b/test/Aevatar.Application.Tests/ProjectApiKey/ProjectApiKey_Test.cs index e16d97460..fdc3095b6 100644 --- a/test/Aevatar.Application.Tests/ProjectApiKey/ProjectApiKey_Test.cs +++ b/test/Aevatar.Application.Tests/ProjectApiKey/ProjectApiKey_Test.cs @@ -27,7 +27,7 @@ public abstract class ProjectApiKeyTests : AevatarApplicationTes public ProjectApiKeyTests() { _projectAppIdService = GetRequiredService(); - _identityUserManager =GetRequiredService(); + _identityUserManager = GetRequiredService(); _currentUser = GetRequiredService(); _principalAccessor = GetRequiredService(); } @@ -36,7 +36,7 @@ public ProjectApiKeyTests() public async Task CreateApiKeyTest() { await _identityUserManager.CreateAsync(new IdentityUser(_currentUser.Id!.Value, "A", "2222@gmail.com")); - + await _projectAppIdService.CreateAsync(_projectId, _firstApiKeyName, _currentUser.Id!.Value); } @@ -45,7 +45,7 @@ public async Task CreateApiKeyTest() public async Task CreateApiKeyExistTest() { await _projectAppIdService.CreateAsync(_projectId, _firstApiKeyName, _currentUser.Id!.Value); - + await Assert.ThrowsAsync(async () => await _projectAppIdService.CreateAsync(_projectId, _firstApiKeyName, _currentUser.Id!.Value)); } @@ -53,13 +53,13 @@ await Assert.ThrowsAsync(async () => [Fact] public async Task UpdateApiKeyNameTest() { - using(_principalAccessor.Change(new [] - { - new Claim(AbpClaimTypes.UserId, _currentUser.Id!.Value.ToString()), - new Claim(AbpClaimTypes.UserName, _currentUser.UserName!), - new Claim(AbpClaimTypes.Email, _currentUser.Email!), - new Claim(AbpClaimTypes.Role, AevatarConsts.AdminRoleName) - })) + using (_principalAccessor.Change(new[] + { + new Claim(AbpClaimTypes.UserId, _currentUser.Id!.Value.ToString()), + new Claim(AbpClaimTypes.UserName, _currentUser.UserName!), + new Claim(AbpClaimTypes.Email, _currentUser.Email!), + new Claim(AbpClaimTypes.Role, AevatarConsts.AdminRoleName) + })) { await _identityUserManager.CreateAsync(new IdentityUser(_currentUser.Id!.Value, "A", "2222@gmail.com")); await _projectAppIdService.CreateAsync(_projectId, _firstApiKeyName, _currentUser.Id!.Value); @@ -73,13 +73,13 @@ public async Task UpdateApiKeyNameTest() [Fact] public async Task UpdateApiKeyNameExistTest() { - using(_principalAccessor.Change(new [] - { - new Claim(AbpClaimTypes.UserId, _currentUser.Id!.Value.ToString()), - new Claim(AbpClaimTypes.UserName, _currentUser.UserName!), - new Claim(AbpClaimTypes.Email, _currentUser.Email!), - new Claim(AbpClaimTypes.Role, AevatarConsts.AdminRoleName) - })) + using (_principalAccessor.Change(new[] + { + new Claim(AbpClaimTypes.UserId, _currentUser.Id!.Value.ToString()), + new Claim(AbpClaimTypes.UserName, _currentUser.UserName!), + new Claim(AbpClaimTypes.Email, _currentUser.Email!), + new Claim(AbpClaimTypes.Role, AevatarConsts.AdminRoleName) + })) { await _identityUserManager.CreateAsync(new IdentityUser(_currentUser.Id!.Value, "A", "2222@gmail.com")); await _projectAppIdService.CreateAsync(_projectId, _firstApiKeyName, _currentUser.Id!.Value); diff --git a/test/Aevatar.Application.Tests/Projects/ProjectServiceTests.cs b/test/Aevatar.Application.Tests/Projects/ProjectServiceTests.cs index 1c6f50343..c5ef72144 100644 --- a/test/Aevatar.Application.Tests/Projects/ProjectServiceTests.cs +++ b/test/Aevatar.Application.Tests/Projects/ProjectServiceTests.cs @@ -47,7 +47,7 @@ await _identityUserManager.CreateAsync( _currentUser.Id.Value, "test", "test@email.io")); - + var createOrganizationInput = new CreateOrganizationDto { DisplayName = "Test Organization" @@ -124,7 +124,7 @@ await _identityUserManager.CreateAsync( _currentUser.Id.Value, "test", "test@email.io")); - + var createOrganizationInput = new CreateOrganizationDto { DisplayName = "Test Organization" @@ -145,7 +145,7 @@ await _identityUserManager.CreateAsync( DomainName = "App New" }; await _projectService.UpdateAsync(project.Id, updateInput); - + project = await _projectService.GetProjectAsync(project.Id); project.DisplayName.ShouldBe(updateInput.DisplayName); project.DomainName.ShouldBe(updateInput.DomainName); @@ -159,7 +159,7 @@ await _identityUserManager.CreateAsync( _currentUser.Id.Value, "test", "test@email.io")); - + var createOrganizationInput = new CreateOrganizationDto { DisplayName = "Test Organization" @@ -173,7 +173,7 @@ await _identityUserManager.CreateAsync( DomainName = "App" }; var project = await _projectService.CreateAsync(createProjectInput); - + var roles = await _projectService.GetRoleListAsync(project.Id); await _projectService.DeleteAsync(project.Id); @@ -206,11 +206,11 @@ public async Task Project_SetMember_Test() DomainName = "App" }; var project = await _projectService.CreateAsync(createProjectInput); - + var roles = await _projectService.GetRoleListAsync(project.Id); var ownerRole = roles.Items.First(o => o.Name.EndsWith("Owner")); var readerRole = roles.Items.First(o => o.Name.EndsWith("Reader")); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(0); @@ -227,10 +227,10 @@ public async Task Project_SetMember_Test() Join = true, RoleId = readerRole.Id }); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(1); - + members = await _projectService.GetMemberListAsync(project.Id, new GetOrganizationMemberListDto()); members.Items.Count.ShouldBe(1); @@ -243,18 +243,18 @@ public async Task Project_SetMember_Test() UserId = readerUser.Id, RoleId = ownerRole.Id }); - + members = await _projectService.GetMemberListAsync(project.Id, new GetOrganizationMemberListDto()); members.Items.Count.ShouldBe(1); members.Items[0].RoleId.ShouldBe(ownerRole.Id); - + await _projectService.SetMemberAsync(project.Id, new SetOrganizationMemberDto { Email = readerUser.Email, Join = false }); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(0); @@ -265,7 +265,7 @@ public async Task Project_SetMember_Test() readerUser = await _identityUserManager.GetByIdAsync(readerUser.Id); readerUser.IsInOrganizationUnit(project.Id).ShouldBeFalse(); } - + [Fact] public async Task Organization_Delete_WithProject_Test() { @@ -274,7 +274,7 @@ await _identityUserManager.CreateAsync( _currentUser.Id.Value, "test", "test@email.io")); - + var createOrganizationInput = new CreateOrganizationDto { DisplayName = "Test Organization" @@ -288,7 +288,7 @@ await _identityUserManager.CreateAsync( DomainName = "App" }; var project = await _projectService.CreateAsync(createProjectInput); - + var organizationRoles = await _organizationService.GetRoleListAsync(organization.Id); var projectRoles = await _projectService.GetRoleListAsync(project.Id); @@ -301,10 +301,10 @@ await Should.ThrowAsync(async () => { await Should.ThrowAsync(async () => await _roleManager.GetByIdAsync(role.Id)); } - + var user = await _identityUserManager.GetByIdAsync(_currentUser.Id.Value); user.IsInOrganizationUnit(organization.Id).ShouldBeFalse(); - + await Should.ThrowAsync(async () => await _projectService.GetProjectAsync(project.Id)); @@ -313,13 +313,13 @@ await Should.ThrowAsync(async () => await Should.ThrowAsync(async () => await _roleManager.GetByIdAsync(role.Id)); } } - + [Fact] public async Task Organization_DeleteMember_WithProject_Test() { var owner = new IdentityUser(_currentUser.Id.Value, "owner", "owner@email.io"); await _identityUserManager.CreateAsync(owner); - + var reader = new IdentityUser(Guid.NewGuid(), "reader", "reader@email.io"); await _identityUserManager.CreateAsync(reader); @@ -336,7 +336,7 @@ public async Task Organization_DeleteMember_WithProject_Test() DomainName = "App" }; var project = await _projectService.CreateAsync(createProjectInput); - + var roles = await _projectService.GetRoleListAsync(project.Id); var ownerRole = roles.Items.First(o => o.Name.EndsWith("Owner")); var readerRole = roles.Items.First(o => o.Name.EndsWith("Reader")); @@ -347,26 +347,27 @@ public async Task Organization_DeleteMember_WithProject_Test() Join = true, RoleId = ownerRole.Id }); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(1); - + await _projectService.SetMemberAsync(project.Id, new SetOrganizationMemberDto { Email = reader.Email, Join = true, RoleId = readerRole.Id }); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(2); - - await Should.ThrowAsync(async () => await _organizationService.SetMemberAsync(organization.Id, new SetOrganizationMemberDto - { - Email = owner.Email, - Join = false - })); - + + await Should.ThrowAsync(async () => await _organizationService.SetMemberAsync( + organization.Id, new SetOrganizationMemberDto + { + Email = owner.Email, + Join = false + })); + await _organizationService.SetMemberAsync(organization.Id, new SetOrganizationMemberDto { Email = reader.Email, @@ -375,11 +376,10 @@ public async Task Organization_DeleteMember_WithProject_Test() organization = await _organizationService.GetAsync(organization.Id); organization.MemberCount.ShouldBe(1); - + project = await _projectService.GetProjectAsync(project.Id); project.MemberCount.ShouldBe(1); - owner = await _identityUserManager.GetByIdAsync(reader.Id); owner.IsInOrganizationUnit(organization.Id).ShouldBeFalse(); owner.IsInOrganizationUnit(project.Id).ShouldBeFalse(); diff --git a/test/Aevatar.Application.Tests/Webhook/WebHookTest.cs b/test/Aevatar.Application.Tests/Webhook/WebHookTest.cs index 4c09e0066..0583f9f4e 100644 --- a/test/Aevatar.Application.Tests/Webhook/WebHookTest.cs +++ b/test/Aevatar.Application.Tests/Webhook/WebHookTest.cs @@ -5,7 +5,6 @@ using Shouldly; using Volo.Abp.Modularity; using Xunit; -using Volo.Abp; using Aevatar.Webhook.Extensions; using Microsoft.CodeAnalysis; @@ -178,7 +177,8 @@ private static byte[] CreateValidDll(string name) name, new[] { syntaxTree }, references, - new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary) + new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind + .DynamicallyLinkedLibrary) ); using var ms = new System.IO.MemoryStream(); var result = compilation.Emit(ms); @@ -193,5 +193,4 @@ private static byte[] CreateFakeDll(string name, string[] refs) // Only returns an empty byte array. In real scenarios, use Roslyn or similar to generate a valid DLL. Here for structural test only. return new byte[1]; } - } \ No newline at end of file diff --git a/test/Aevatar.Cqrs.Tests/AevatarCqrsTestModule.cs b/test/Aevatar.Cqrs.Tests/AevatarCqrsTestModule.cs index 64de99efc..527c936cb 100644 --- a/test/Aevatar.Cqrs.Tests/AevatarCqrsTestModule.cs +++ b/test/Aevatar.Cqrs.Tests/AevatarCqrsTestModule.cs @@ -1,10 +1,8 @@ using Aevatar.CQRS; using Aevatar.CQRS.Handler; using Aevatar.Mock; -using Aevatar.Options; using Aevatar.Service; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.AutoMapper; using Volo.Abp.EventBus; using Volo.Abp.Modularity; diff --git a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentState.cs b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentState.cs index 402373915..06478c647 100644 --- a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentState.cs +++ b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentState.cs @@ -1,17 +1,16 @@ using Aevatar.Core.Abstractions; namespace Aevatar.GAgent.Dto; + [GenerateSerializer] -public class CqrsTestAgentState :StateBase +public class CqrsTestAgentState : StateBase { - [Id(0)] public Guid Id { get; set; } - [Id(1)] public string AgentName { get; set; } - [Id(2)] public int AgentCount { get; set; } - [Id(3)] public string GroupId { get; set; } - - [Id(4)] public List AgentIds { get; set; } - - [Id(5)] public Dictionary AgentTypeDictionary { get; set; } + [Id(0)] public Guid Id { get; set; } + [Id(1)] public string AgentName { get; set; } + [Id(2)] public int AgentCount { get; set; } + [Id(3)] public string GroupId { get; set; } + [Id(4)] public List AgentIds { get; set; } + [Id(5)] public Dictionary AgentTypeDictionary { get; set; } } \ No newline at end of file diff --git a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentStateDto.cs b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentStateDto.cs index 1e4f18ed0..85a832a3e 100644 --- a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentStateDto.cs +++ b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestAgentStateDto.cs @@ -1,16 +1,15 @@ using Aevatar.Agents.Creator.Models; namespace Aevatar.Cqrs.Tests.Cqrs.Dto; -public class CqrsTestAgentStateDto :BaseStateDto -{ - public string Id { get; set; } - public string AgentName { get; set; } - public int AgentCount { get; set; } - public string GroupId { get; set; } - - public string AgentIds { get; set; } - public string AgentTypeDictionary { get; set; } +public class CqrsTestAgentStateDto : BaseStateDto +{ + public string Id { get; set; } + public string AgentName { get; set; } + public int AgentCount { get; set; } + public string GroupId { get; set; } + public string AgentIds { get; set; } + public string AgentTypeDictionary { get; set; } } \ No newline at end of file diff --git a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestCreateAgentGEvent.cs b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestCreateAgentGEvent.cs index a3b61557b..eb44becd4 100644 --- a/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestCreateAgentGEvent.cs +++ b/test/Aevatar.Cqrs.Tests/Cqrs/Dto/CqrsTestCreateAgentGEvent.cs @@ -1,8 +1,9 @@ using Aevatar.Core.Abstractions; namespace Aevatar.GAgent.Dto; + [GenerateSerializer] -public class CqrsTestCreateAgentGEvent: StateLogEventBase +public class CqrsTestCreateAgentGEvent : StateLogEventBase { [Id(0)] public Guid Id { get; set; } [Id(1)] public string UserAddress { get; set; } @@ -10,4 +11,4 @@ public class CqrsTestCreateAgentGEvent: StateLogEventBase [Id(3)] public string Name { get; set; } [Id(4)] public string BusinessAgentId { get; set; } [Id(5)] public string Properties { get; set; } -} +} \ No newline at end of file diff --git a/test/Aevatar.Cqrs.Tests/Cqrs/MetricsElasticIndexingServiceTest.cs b/test/Aevatar.Cqrs.Tests/Cqrs/MetricsElasticIndexingServiceTest.cs index 5c68a7861..6414a7dfc 100644 --- a/test/Aevatar.Cqrs.Tests/Cqrs/MetricsElasticIndexingServiceTest.cs +++ b/test/Aevatar.Cqrs.Tests/Cqrs/MetricsElasticIndexingServiceTest.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; using System.Diagnostics.Metrics; -using System.Threading.Tasks; using Aevatar; using Aevatar.CQRS; using Aevatar.CQRS.Dto; @@ -75,7 +72,8 @@ public async Task SaveOrUpdateStateIndexBatchAsync_Should_LogError_On_Exception( var mockLogger = new Mock>(); var metricsService = new MetricsElasticIndexingService(mockInner.Object, mockLogger.Object); var commands = new List(); - await Assert.ThrowsAsync(() => metricsService.SaveOrUpdateStateIndexBatchAsync(commands)); + await Assert.ThrowsAsync(() => + metricsService.SaveOrUpdateStateIndexBatchAsync(commands)); mockLogger.Verify(l => l.Log( LogLevel.Error, It.IsAny(), @@ -128,7 +126,8 @@ public async Task CheckExistOrCreateStateIndex_Should_LogError_On_Exception() .ThrowsAsync(new InvalidOperationException("test error")); var mockLogger = new Mock>(); var metricsService = new MetricsElasticIndexingService(mockInner.Object, mockLogger.Object); - await Assert.ThrowsAsync(() => metricsService.CheckExistOrCreateStateIndex(new MockStateBase())); + await Assert.ThrowsAsync(() => + metricsService.CheckExistOrCreateStateIndex(new MockStateBase())); mockLogger.Verify(l => l.Log( LogLevel.Error, It.IsAny(), @@ -142,10 +141,10 @@ public async Task GetStateIndexDocumentsAsync_Should_Record_Metrics_And_Trace() { var mockInner = new Mock(); mockInner.Setup(x => x.GetStateIndexDocumentsAsync( - It.IsAny(), - It.IsAny>>(), - It.IsAny(), - It.IsAny())) + It.IsAny(), + It.IsAny>>(), + It.IsAny(), + It.IsAny())) .ReturnsAsync("result"); var mockLogger = new Mock>(); var metricsService = new MetricsElasticIndexingService(mockInner.Object, mockLogger.Object); @@ -172,7 +171,9 @@ public async Task GetStateIndexDocumentsAsync_Should_Record_Metrics_And_Trace() listener.Start(); var result = await metricsService.GetStateIndexDocumentsAsync("test", q => { }); listener.Dispose(); - mockInner.Verify(x => x.GetStateIndexDocumentsAsync("test", It.IsAny>>(), 0, 1000), Times.Once); + mockInner.Verify( + x => x.GetStateIndexDocumentsAsync("test", It.IsAny>>(), 0, 1000), + Times.Once); Assert.Equal("result", result); Assert.True(observedDuration.HasValue && observedDuration.Value >= 0); Assert.True(observedSuccess > 0); @@ -183,14 +184,15 @@ public async Task GetStateIndexDocumentsAsync_Should_LogError_On_Exception() { var mockInner = new Mock(); mockInner.Setup(x => x.GetStateIndexDocumentsAsync( - It.IsAny(), - It.IsAny>>(), - It.IsAny(), - It.IsAny())) + It.IsAny(), + It.IsAny>>(), + It.IsAny(), + It.IsAny())) .ThrowsAsync(new InvalidOperationException("test error")); var mockLogger = new Mock>(); var metricsService = new MetricsElasticIndexingService(mockInner.Object, mockLogger.Object); - await Assert.ThrowsAsync(() => metricsService.GetStateIndexDocumentsAsync("test", q => { })); + await Assert.ThrowsAsync(() => + metricsService.GetStateIndexDocumentsAsync("test", q => { })); mockLogger.Verify(l => l.Log( LogLevel.Error, It.IsAny(), @@ -244,7 +246,8 @@ public async Task QueryWithLuceneAsync_Should_LogError_On_Exception() .ThrowsAsync(new InvalidOperationException("test error")); var mockLogger = new Mock>(); var metricsService = new MetricsElasticIndexingService(mockInner.Object, mockLogger.Object); - await Assert.ThrowsAsync(() => metricsService.QueryWithLuceneAsync(new LuceneQueryDto())); + await Assert.ThrowsAsync(() => + metricsService.QueryWithLuceneAsync(new LuceneQueryDto())); mockLogger.Verify(l => l.Log( LogLevel.Error, It.IsAny(), @@ -252,4 +255,4 @@ public async Task QueryWithLuceneAsync_Should_LogError_On_Exception() It.IsAny(), It.IsAny>()), Times.AtLeastOnce); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/AevatarMongoDbTestModule.cs b/test/Aevatar.MongoDB.Tests/MongoDb/AevatarMongoDbTestModule.cs index 064089891..28338b08e 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/AevatarMongoDbTestModule.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/AevatarMongoDbTestModule.cs @@ -1,5 +1,4 @@ -using System; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Data; using Volo.Abp.Modularity; @@ -17,7 +16,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); var useMongoDbFixture = configuration["TestingEnvironment"] != "MongoDB"; - + Configure(options => { if (useMongoDbFixture) @@ -35,10 +34,10 @@ public override void ConfigureServices(ServiceConfigurationContext context) } } }); - + Configure(options => { options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; }); } -} +} \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Notification/MongoDBNotificationTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Notification/MongoDBNotificationTests.cs index 50fe0cbc5..6d2596a9f 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Notification/MongoDBNotificationTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Notification/MongoDBNotificationTests.cs @@ -4,7 +4,4 @@ namespace Aevatar.MongoDB.Applications.Notification; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDbNotificationTests : NotificationTests -{ - -} \ No newline at end of file +public class MongoDbNotificationTests : NotificationTests; \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationPermissionServiceTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationPermissionServiceTests.cs index b442ea1cc..e3372690f 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationPermissionServiceTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationPermissionServiceTests.cs @@ -1,11 +1,7 @@ -using Aevatar.MongoDB; using Aevatar.Origanzations; using Xunit; namespace Aevatar.MongoDB.Applications.Organizations; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDBOrganizationPermissionServiceTests : OrganizationPermissionServiceTests -{ - -} \ No newline at end of file +public class MongoDBOrganizationPermissionServiceTests : OrganizationPermissionServiceTests; \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationRoleServiceTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationRoleServiceTests.cs index a6de940f8..5e04a81c4 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationRoleServiceTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Organizations/MongoDBOrganizationRoleServiceTests.cs @@ -1,11 +1,7 @@ -using Aevatar.MongoDB; using Aevatar.Origanzations; using Xunit; namespace Aevatar.MongoDB.Applications.Organizations; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDBOrganizationRoleServiceTests : OrganizationRoleServiceTests -{ - -} \ No newline at end of file +public class MongoDBOrganizationRoleServiceTests : OrganizationRoleServiceTests; \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Plugins/MongoDBPluginServiceTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Plugins/MongoDBPluginServiceTests.cs index 2de5bfe7c..f06b1e0c4 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Plugins/MongoDBPluginServiceTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/Plugins/MongoDBPluginServiceTests.cs @@ -1,11 +1,7 @@ -using Aevatar.MongoDB; using Aevatar.Plugins; using Xunit; namespace Aevatar.MongoDB.Applications.Plugins; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDBPluginServiceTests : PluginServiceTests -{ - -} \ No newline at end of file +public class MongoDBPluginServiceTests : PluginServiceTests; \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/ProjectApiKey/MongoDbProjectApiKeyTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/ProjectApiKey/MongoDbProjectApiKeyTests.cs index 0090ce85c..d84e09227 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/ProjectApiKey/MongoDbProjectApiKeyTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/ProjectApiKey/MongoDbProjectApiKeyTests.cs @@ -4,7 +4,4 @@ namespace Aevatar.MongoDB.Applications.ProjectApiKey; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDbProjectApiKeyTests : ProjectApiKeyTests -{ - -} \ No newline at end of file +public class MongoDbProjectApiKeyTests : ProjectApiKeyTests; \ No newline at end of file diff --git a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/WebHook/MongoDBWebHookTests.cs b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/WebHook/MongoDBWebHookTests.cs index 5a13b222b..8b52a79d3 100644 --- a/test/Aevatar.MongoDB.Tests/MongoDb/Applications/WebHook/MongoDBWebHookTests.cs +++ b/test/Aevatar.MongoDB.Tests/MongoDb/Applications/WebHook/MongoDBWebHookTests.cs @@ -4,7 +4,4 @@ namespace Aevatar.MongoDB.Applications.WebHook; [Collection(AevatarTestConsts.CollectionDefinitionName)] -public class MongoDBWebHookTests : WebHookTests -{ - -} \ No newline at end of file +public class MongoDBWebHookTests : WebHookTests; \ No newline at end of file diff --git a/test/Aevatar.Orleans.TestBase/AevatarOrleansTestBase.cs b/test/Aevatar.Orleans.TestBase/AevatarOrleansTestBase.cs index 2d7a1f18f..8486bed2a 100644 --- a/test/Aevatar.Orleans.TestBase/AevatarOrleansTestBase.cs +++ b/test/Aevatar.Orleans.TestBase/AevatarOrleansTestBase.cs @@ -1,17 +1,15 @@ using Orleans.TestingHost; using Volo.Abp.Modularity; -using Xunit.Abstractions; - namespace Aevatar; -public abstract class AevatarOrleansTestBase : +public abstract class AevatarOrleansTestBase : AevatarTestBase where TStartupModule : IAbpModule { protected readonly TestCluster Cluster; - protected AevatarOrleansTestBase() + protected AevatarOrleansTestBase() { Cluster = GetRequiredService().Cluster; } diff --git a/test/Aevatar.TestBase/AevatarTestBase.cs b/test/Aevatar.TestBase/AevatarTestBase.cs index dc96285c3..c0fd56ce0 100644 --- a/test/Aevatar.TestBase/AevatarTestBase.cs +++ b/test/Aevatar.TestBase/AevatarTestBase.cs @@ -18,30 +18,30 @@ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationO { options.UseAutofac(); } - + protected override void BeforeAddApplication(IServiceCollection services) { var builder = new ConfigurationBuilder(); - + // 基础配置文件 builder.AddJsonFile("appsettings.json", optional: false); - + // 根据环境变量加载不同的配置 string env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Testing"; builder.AddJsonFile($"appsettings.{env}.json", optional: true); - + // MongoDB特定配置,只在需要时加载 if (ShouldUseMongoDB()) { builder.AddJsonFile("appsettings.MongoDB.json", optional: true); } - + // 秘钥配置 builder.AddJsonFile("appsettings.secrets.json", optional: true); - + // 环境变量 builder.AddEnvironmentVariables(); - + services.ReplaceConfiguration(builder.Build()); } @@ -62,17 +62,13 @@ protected virtual Task WithUnitOfWorkAsync(Func func) protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) { - using (var scope = ServiceProvider.CreateScope()) - { - var uowManager = scope.ServiceProvider.GetRequiredService(); + using var scope = ServiceProvider.CreateScope(); + var uowManager = scope.ServiceProvider.GetRequiredService(); - using (var uow = uowManager.Begin(options)) - { - await action(); + using var uow = uowManager.Begin(options); + await action(); - await uow.CompleteAsync(); - } - } + await uow.CompleteAsync(); } protected virtual Task WithUnitOfWorkAsync(Func> func) @@ -80,18 +76,15 @@ protected virtual Task WithUnitOfWorkAsync(Func> return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); } - protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, + Func> func) { - using (var scope = ServiceProvider.CreateScope()) - { - var uowManager = scope.ServiceProvider.GetRequiredService(); - - using (var uow = uowManager.Begin(options)) - { - var result = await func(); - await uow.CompleteAsync(); - return result; - } - } + using var scope = ServiceProvider.CreateScope(); + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using var uow = uowManager.Begin(options); + var result = await func(); + await uow.CompleteAsync(); + return result; } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit.Tests/Grains/HelloTimers.cs b/test/OrleansTestKit.Tests/Grains/HelloTimers.cs index 0d67f32d9..b0aa0431a 100644 --- a/test/OrleansTestKit.Tests/Grains/HelloTimers.cs +++ b/test/OrleansTestKit.Tests/Grains/HelloTimers.cs @@ -20,8 +20,9 @@ public override Task OnActivateAsync(CancellationToken cancellationToken) _timer1 = RegisterTimer(_ => OnTimer1(), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); _timer2 = RegisterTimer(_ => OnTimer2(), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); - _grainTimer0 = this.RegisterGrainTimer((_, c) => OnGrainTimer0(c), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); - + _grainTimer0 = + this.RegisterGrainTimer((_, c) => OnGrainTimer0(c), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + return base.OnActivateAsync(cancellationToken); } @@ -99,4 +100,4 @@ public HelloTimersState() public bool GrainTimer0Fired { get; set; } public bool GrainTimer0Cancelled { get; set; } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit.Tests/Grains/PingGrain.cs b/test/OrleansTestKit.Tests/Grains/PingGrain.cs index 8205f0f81..022959a89 100644 --- a/test/OrleansTestKit.Tests/Grains/PingGrain.cs +++ b/test/OrleansTestKit.Tests/Grains/PingGrain.cs @@ -13,8 +13,8 @@ public Task Ping() public Task PingCompound() { - var pong = (IPongCompound)GrainFactory.GetGrain(typeof(IPongCompound),44, keyExtension: "Test"); + var pong = (IPongCompound)GrainFactory.GetGrain(typeof(IPongCompound), 44, keyExtension: "Test"); return pong.Pong(); } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit.Tests/Tests/PersistentStreamWithinGrainStateTests.cs b/test/OrleansTestKit.Tests/Tests/PersistentStreamWithinGrainStateTests.cs index 197ce72be..8d6fe6128 100644 --- a/test/OrleansTestKit.Tests/Tests/PersistentStreamWithinGrainStateTests.cs +++ b/test/OrleansTestKit.Tests/Tests/PersistentStreamWithinGrainStateTests.cs @@ -62,8 +62,8 @@ public async Task WhenActivated_StoreStreamHandlerInState() //Assert Assert.Equal(1, _stream.Subscribed); Assert.NotNull(_stateWithHandle.ChatMessageStreamSubscriptionHandle); - + var stats = Silo.StorageManager.GetStorageStats("listenerStateWithHandler"); Assert.Equal(1, stats.Writes); } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit.Tests/Tests/TimerTests.cs b/test/OrleansTestKit.Tests/Tests/TimerTests.cs index db450ac38..b5d091fdc 100644 --- a/test/OrleansTestKit.Tests/Tests/TimerTests.cs +++ b/test/OrleansTestKit.Tests/Tests/TimerTests.cs @@ -1,6 +1,4 @@ -using FluentAssertions; -using Orleans.TestKit.Timers; -using TestGrains; +using TestGrains; using Xunit; namespace Orleans.TestKit.Tests; @@ -23,7 +21,7 @@ public async Task ShouldFirstGrainTimerAsync() } [Fact] - public async Task ShouldCancelFirstGrainTimerAsync() + public async Task ShouldCancelFirstGrainTimerAsync() { // Arrange var grain = await Silo.CreateGrainAsync(0); @@ -113,7 +111,8 @@ public async Task ShouldNotCountDisposedTimersAsActive() var grain = (Grain)await Silo.CreateGrainAsync(0); var initialActiveTimers = Silo.TimerRegistry.NumberOfActiveTimers; - var newTimer = Silo.TimerRegistry.RegisterTimer(((IGrainBase)grain).GrainContext, _ => Task.CompletedTask, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + var newTimer = Silo.TimerRegistry.RegisterTimer(((IGrainBase)grain).GrainContext, _ => Task.CompletedTask, null, + TimeSpan.Zero, TimeSpan.FromSeconds(1)); Assert.Equal(initialActiveTimers + 1, Silo.TimerRegistry.NumberOfActiveTimers); @@ -138,4 +137,4 @@ public async Task ShouldRegisterSecretTimerAsync() //Assert Assert.Equal(initialActiveTimers + 1, Silo.TimerRegistry.NumberOfActiveTimers); } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit/EventSourcing/TestLogViewAdaptor.cs b/test/OrleansTestKit/EventSourcing/TestLogViewAdaptor.cs index 4753408c9..60c002716 100644 --- a/test/OrleansTestKit/EventSourcing/TestLogViewAdaptor.cs +++ b/test/OrleansTestKit/EventSourcing/TestLogViewAdaptor.cs @@ -1,11 +1,10 @@ -using Aevatar.Agents; using JetBrains.Annotations; using Orleans; using Orleans.EventSourcing; using Orleans.EventSourcing.Common; using Orleans.Storage; -public class TestLogViewAdaptor : +public class TestLogViewAdaptor : PrimaryBasedLogViewAdaptor> where TLogView : class, new() where TLogEntry : class @@ -17,6 +16,7 @@ public class TestLogViewAdaptor : public static readonly ICollection> SnapshotCollection = new List>(); + public static readonly ICollection> EventLogCollection = new List>(); @@ -61,6 +61,7 @@ protected override async Task ReadAsync() _confirmedVersion = snapshot.Version; _confirmedView = snapshot.State; } + var eventLogs = await GetAllEventsAsync(); if (!eventLogs.Any()) { @@ -82,9 +83,9 @@ protected override async Task ReadAsync() _confirmedView = snapshot.State; break; } - + // TODO: Can only retrieve log segment from _confirmedVersion to _globalVersion - + foreach (var eventLog in eventLogs) { _host.UpdateView(_confirmedView, eventLog.Event); @@ -103,9 +104,10 @@ protected override async Task ReadAsync() { e = ((ProtocolTransportException)e).InnerException!; } + LastPrimaryIssue.Record(new ReadFromPrimaryFailed { Exception = e }, Host, Services); } - + await LastPrimaryIssue.DelayBeforeRetry(); } } @@ -174,7 +176,7 @@ private Task SaveEventsAsync(IEnumerable> e return Task.FromResult(timestamp); } - + [ItemCanBeNull] private Task> GetSnapshotAsync() { diff --git a/test/OrleansTestKit/GrainProbeExtensions.cs b/test/OrleansTestKit/GrainProbeExtensions.cs index 4ad151e7e..356a6c675 100644 --- a/test/OrleansTestKit/GrainProbeExtensions.cs +++ b/test/OrleansTestKit/GrainProbeExtensions.cs @@ -66,10 +66,10 @@ public static void AddProbe(this TestKitSilo silo, Func factory) silo.GrainFactory.AddProbe(factory); } - + public static void AddProbe(this TestKitSilo silo, GrainId grainId, T grain) where T : class, IGrain { silo.GrainFactory.AddProbe(grainId, grain); } -} +} \ No newline at end of file diff --git a/test/OrleansTestKit/TestKitSilo.cs b/test/OrleansTestKit/TestKitSilo.cs index 8bcd470ea..d6bfea266 100644 --- a/test/OrleansTestKit/TestKitSilo.cs +++ b/test/OrleansTestKit/TestKitSilo.cs @@ -211,7 +211,8 @@ public IGrainContext GetOrAddGrainContext(IdSpan identity) var grainType = _grainTypeResolver.GetGrainType(typeof(T)); var grainId = GrainId.Create(grainType, identity); - if (ServiceProvider.GetService() is not TestGrainActivationContext context || context.GrainId != grainId || context.GrainType != typeof(T)) + if (ServiceProvider.GetService() is not TestGrainActivationContext context || + context.GrainId != grainId || context.GrainType != typeof(T)) { // we have not registered a context yet OR we have registered a context but it is for a different grain and we need to re-create context = new TestGrainActivationContext @@ -307,14 +308,14 @@ public void Dispose() disposable.Dispose(); } } - + // 清空创建的Grain列表 _activatedGrains.Clear(); _createdGrains.Clear(); - + // 注意:这些管理器没有实现IDisposable接口,所以我们不需要尝试释放它们 // 如果将来它们实现了IDisposable,可以在这里添加相应的代码 - + GC.SuppressFinalize(this); } -} +} \ No newline at end of file