Activities of "alexander.nikonov"

Here's what I've got after modifications in a test solution:

  1. when I added authorization attribute and removed audit-disabling attribute - the time did not change;
  2. when I added ABP appservice - the picture looks like this:

        [RemoteService]
        [Authorize]
        public class TestController : AbpController
        {
            private readonly IIdentityUserAppService _identityUserAppService;

            public TestController(IIdentityUserAppService identityUserAppService)
            {
                _identityUserAppService = identityUserAppService;
            }

            [HttpGet]
            public async Task<PagedResultDto<string>> GetPositionLookupAsync()
            {
                var result = await _identityUserAppService.GetListAsync(new GetIdentityUsersInput());

                return new PagedResultDto<string>
                {
                    Items = result.Items.Select(x => x.Email).ToList(),
                    TotalCount = result.Items.Count
                };
            }
        }

Does it look OK? Even if so - it's a test solution which uses MS SQL Server DB. Our solution uses Oracle and has a lot different functionality on top of standard test solution. Also, replacing MS SQL Server with Oracle in a test solution would take too much effort.

So I suggest to focus on analysis of our problematic solution based on my input in the previous post: 4 sec is an approx response time with no authorization and disabled auditing (almost the same as initially reported time) and 300+ ms is response time with no appservice used. Please suggest what drill-down should I make - like posting some of our AbpModule code etc.

@albert since I will be out for 2 weeks, I've decided to try some experiments right away. Is it essential to create a new controller? If I got you right regarding disabling auditing and authorization, I had to put the following attributes on my controller and appservice:

[AllowAnonymous]
[DisableAuditing]

So after doing this I run existing lookup method from POSTMAN. Result is approximately the same as from Angular app before (response time varies between 4 and 16 seconds depending on how many times I run the same details page):

Researching further... So now I have to try a new controller or new Net Core project... It will take more time.

Here's new controller with a very simple output, no appservice used:

  [RemoteService]
    [Area("app")]
    [ControllerName("Test")]
    [Route("api/ct/central-tool/tests")]
    [AllowAnonymous]
    [DisableAuditing]
    public class TestController : AbpController
    {
        public TestController()
        {
        }

        [HttpGet]
        public List<int> GetPositionLookupAsync()
        {
            return new List<int>
            {
                0, 1, 2, 3, 4, 5, 6, 7, 999, 10000 
            };
        }
    }

Is this time still NOT OK? I mean it is noticeably less than previous, but this code does not use DI (getting appservice instance), does not access DB... And it is still 300+ ms... Should I proceed with a new project or should I proceed with investigating appservice code somehow?

UPDATE: in fact I have had test solution based on ABP Framework 4.3.0. I used the same test method as above and here is the timing from Swagger (I did not manage to run it from Postman, getting some weird Invalid character in header content ["Host"] error, even though there was nothing wrong with the URL):

Looking forward for your recommendation as to my next actions.

@albert Redis is already disabled

@maliming Here are logs from both HttpApi hosts. Level was set to 'Debug': .MinimumLevel.Override("Microsoft", LogEventLevel.Debug)

Please be aware, that this time response times are less - though, they are still too big:

https://1drv.ms/u/s!AhWdpZddvifTtw10XrTEduNTBt8-?e=RKpfLs https://1drv.ms/u/s!AhWdpZddvifTtwzipyhO1VtNwgbF?e=3oxwaQ

P.S. Could you please add possibility to attach log files to a message, not only images?

  • ABP Framework version: v4.3.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

We make calls from Angular app to several HTTP hosts which reside:

  1. in production - on the same domain (different web apps) - XXX.cloudapp.azure.com/host1, XXX.cloudapp.azure.com/host2, etc.
  2. locally - on different ports: XXX.localhost:44328, XXX.localhost:44338, etc.

Gathering data from all the hosts is too slow, please have a look:

Log file analysis shows that is it not a problem of DB query which takes usually several dozens of ms, it is a server response creation itself, so looks like using alternative server cache (e.g. Redis) would not help (meanwhile we use default ABP caching):

[14:46:50 INF] Executed action method AbxEps.CentralTools.Controllers.FreeCodeValues.FreeCodeValueController.GetCumulationTypesAsync (AbxEps.CentralTools.HttpApi), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 2167.4438ms.

[14:46:51 INF] Executed endpoint 'AbxEps.CentralTools.Controllers.FreeCodeValues.FreeCodeValueController.GetCumulationsAsync (AbxEps.CentralTools.HttpApi)' info: Microsoft.EntityFrameworkCore.Infrastructure[10403] Entity Framework Core 5.0.5 initialized 'CoreDbContext' using provider 'Oracle.EntityFrameworkCore' with options: SensitiveDataLoggingEnabled QuerySplittingBehavior=SplitQuery info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (43ms) [Parameters=[:filter_AbxTenantId_0='17' (Nullable = true), :filter_DomainId_1='MD' (Size = 4), :filter_CodeName_2='C_FND_CUM_TYP' (Size = 50), :filter_LanguageCode_3='E' (Size = 4), :defaultLanguageCode_4='E' (Size = 4)], CommandType='Text', CommandTimeout='0'] SELECT c.C_TENANT, c.C_DOMAIN, c.C_FLD, c.C_LANGUAGE, c.C_STR, c.S_COMMENT, c.D_INS, c.C_USR_INS, c.S_TXT, c.U_CA_IMAGE, c.D_UPD, c.C_USR_UPD, c.C_NEOSKEY, c.C_NUM, c.S_TXT_INT FROM CT_CA_CD_POS c WHERE ((((((c.C_TENANT = :filter_AbxTenantId_0) AND (c.C_DOMAIN = :filter_DomainId_1))) AND (c.C_FLD = :filter_CodeName_2))) AND (((c.C_LANGUAGE = :filter_LanguageCode_3) OR (c.C_LANGUAGE = :defaultLanguageCode_4))))

I also see some gaps between numbers which form total response time above and can't figure out what those ~15 seconds are spent for:

[14:46:54 INF] Request finished HTTP/2 GET https://localhost:44328/api/ct/central-tool/free-codes/values/cumulations/en - - - 200 302 application/json;+charset=utf-8 17065.3807ms

Used Oracle DB resides on Azure cloud, but it may not contribute much to the total time either.

How to overcome this issue with TTFB? We use standard ABP layered architecture, nothing fancy.

  • ABP Framework version: v4.3.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): Identity Server Separated
> [15:44:46 ERR] ---------- RemoteServiceErrorInfo ----------
> {
>   "code": null,
>   "message": "An internal error occurred during your request!",
>   "details": null,
>   "data": {
>     "ActivatorChain": "AbxEps.CentralTools.Controllers.AbxUserProfile.AbxUserProfileController"
>   },
>   "validationErrors": null
> }
> [15:44:46 ERR] An exception was thrown while activating AbxEps.CentralTools.Controllers.AbxUserProfile.AbxUserProfileController.
> Autofac.Core.DependencyResolutionException: An exception was thrown while activating AbxEps.CentralTools.Controllers.AbxUserProfile.AbxUserProfileController.
>  ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Volo.Abp.Autofac.AbpAutofacConstructorFinder' on type 'AbxEps.CentralTools.Controllers.AbxUserProfile.AbxUserProfileController' can be invoked with the available services and parameters:
> Cannot resolve parameter 'AbxEps.CentralTools.AbxUserProfile.IAbxUserProfileService abxUserProfileService' of constructor 'Void .ctor(AbxEps.CentralTools.AbxUserProfile.IAbxUserProfileService)'.
>    at Autofac.Core.Activators.Reflection.ReflectionActivator.GetAllBindings(ConstructorBinder[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)
>    at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
>    at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
>    at Autofac.Builder.RegistrationBuilder`3.&lt;&gt;c__DisplayClass41_0.&lt;PropertiesAutowired&gt;b__0(ResolveRequestContext ctxt, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
>    --- End of inner exception stack trace ---
>    at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
>    at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
>    at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
>    at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
>    at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
>    at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
>    at Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator.Create(ControllerContext actionContext)
>    at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
>    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
>    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
> --- End of stack trace from previous location ---
>    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

This happens in a very common situation - we have another controllers which work fine. And this one seems to look the same, but for some reason it causes the given exception:

Answer

Let's say I have a lot of localizations and edit something at page 6 (UserName):

After editing is done, the grid is reloading to page 1, which is not very user-friendly: I'd prefer to stay at the same page and see the record I've just edited. Or sort the records by modification date in descending order - this way my record will be at the top of the grid and I won't need to look for it.

Answer

@maliming

Actually i've managed to achieve this, but using slighly different approach: i've overriden a couple of classes, where filtered existing permissions, but using licence rules:

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IPermissionAppService))]
    [Authorize]
    public class CentralToolsPermissionAppService : PermissionAppService
    
    public class CentralToolsRolePermissionValueProvider : RolePermissionValueProvider
    

This way I get the filtered roles in the menu and in the Role Permission management. I am not sure we would use Client Permission Management for clients, but then probably I would need to override that provider too.

Possibly I am missing something??

Another approach - to use client-side changes: to override RoutesService and PermissionGuard in Angular app - so they would react on licence rules: so menu items will be filtered out and service access will be restricted based on these rules...

Are existing permissions are cached somehow by ABP? BTW, we do not use Redis so far and still not planning too... So if it's about caching - we will use something simple built-in...

Answer

You can create some permissions

We have a list of module IDs (each module can be considered as a separate page in navigation menu) and we would prefer not to mix that with "permissions", since it's another conception. And we would like to use it in parallel with requiredPolicy as shown in screenshot:

ModuleId needs to be checked in Licence Provider and decide whether the given user has access to the given module ID (page): if not - the page is not displayed in the navigation menu neither user can access data for it.

Answer

Can you try the latest? 4.3.2

I've tried 4.3.2 and now Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context) is not triggered at all for a logged user: is it correct behavior? When it needs to be triggered??

The angular permission check happens locally, the server will check all the permissions of the current user or user's role etc and return to angular. The menu just checks whether the permission is granted

Yes, I understand - but how to extend "permissions" functionality and use some custom things like our moduleId in our licence provider?

Showing 41 to 50 of 141 entries
Made with ❤️ on ABP v9.1.0-rc.1. Updated on January 17, 2025, 14:13