abpframework / eShopOnAbp

Reference microservice solution built with the ABP Framework and .NET, runs on Kubernetes with Helm configuration, includes API Gateways, Angular and ASP.NET Core MVC applications, PostgreSQL and MongoDB databases
https://www.eShopOnAbp.com/
MIT License
664 stars 259 forks source link

Admin app localization problem #235

Closed gterdem closed 4 months ago

gterdem commented 4 months ago

Fixes https://github.com/abpframework/eShopOnAbp/issues/231

Also sample for Gateway Aggregation Pattern. YARP is not a gateway but just a reverse proxy hence it is not supported out of the box like Ocelot. This is a sample for how to implement this pattern while using YARP as a gateway.

The default usage is the angular (back-office) application's request to get the localizations and the application configurations.

Introduces aggregations for

How does it work for Localization

The Localization LocalizationRouteName (in the yarp.json file) and the LocalizationEndpoint (called by the back-office app) are defined in the LocalizationAggregation service.

Based on the localization endpoint, the reverse proxy localization routing is intercepted.

A LocalizationRequest input that contains EndPoints dictionary is being created based on YARP clusters. The keys for the dictionary is combined from the ClusterName and the CultureName (ex "Administration_en").

The prepared dictionary is used to GetLocalizations.

First, it checks the LocalizationCachedService that uses IMemoryCache which keeps the ApplicationLocalizationDto data with the same LocalizationRequest endpoint dictionary key (ex "Administration_en").

If the data is not cached, the RemoteService request is done to the multiple LocalizationRequest endpoints. This is a parallel task that returns the completed request results and logs the failures (such as not running microservice). Based on the result, localization cache is being updated and only the non-existing localizations getting tried when requested again.

At the end, all the localizations are merged and a single ApplicationLocalizationDto is returned.

How does it work for ApplicationConfiguration

Since most of the repeating logic is abstracted, the main differences are:

gterdem commented 4 months ago

If the AdministrationService is not available, any first available microservice data is used.

Caching this data is not a correct way. The back-office application authentication information is based on the application configuration Auth/CurrentUser information. When it is cached, there is no practical way to invalidate it for the authentication process.

Consider caching Setting only or remove AppConfigurationAggregation all together since the other microservices do not contain their own settings.

gterdem commented 4 months ago

There are more problems with the AppConfigurationAggregation.

When the back-office application runs, the first request is done to the /application-configuration endpoint. The next request is done to the /application-localization endpoint.

When trying to change the language (ex from en to tr), the localization request is:

GET https://localhost:44372/api/abp/application-localization?cultureName=tr&onlyDynamics=false HTTP/2

However, when the AppConfigurationAggregation is active in the ReverseProxy and try to change the language (ex from en to tr) the localization request is:

GET https://localhost:44372/api/abp/application-localization?cultureName=en&onlyDynamics=false HTTP/2

So the angular back-office application language change parameter is lost and falls back to default en. Probably because the CurrentCulture can not be set: https://github.com/abpframework/abp/blob/e57159f1b96a4937d75793874f9ed89d1c2131c4/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs#L244

gterdem commented 4 months ago

Okay I've found the problem with the help of @ahmetfarukulu

Turns out I forgot to add the incoming default headers to the http requests :)