Hi Enisn, Thanks for the feedback on this. I will try this, but I thought it was bad practice to spool up new httpclients everytime it was needed and instead we should use httpclientfactory? Can I share what I have done so far for this point and get your feedback?
P.S before opening the question I tried for some hours and couldnt get any service back in configure service, always receive the exception
System.ArgumentNullException: 'Value cannot be null. (Parameter 'provider')'
I'm storing tenant level configuration using the SettingsManager on each tenant. I'd like to register an httpclient in configureservices for each tenant using this configuration data for each tenant.
Whats the correct way to do this? I would need to
Could you provide an example or documentation of how to consume these services (settingmanager?, tenantmanager?) in configure service method of the application module?
I can then use the correct httpclient when a call is needed to the external remote service of that tenant.
What happens when the tenant updates their configuration, I'd need to deregister and register a new httpclient for them?
Thanks Albert,
But the question remains the same, could I get a response on it? Or could you clarify whats not clear from what I'm asking?
yikes, dont answer my question and close my ticket.
Hi Hikalkan,
I explained exactly how they are authenticated, my scenario, and that i would use setting on the tenant to store connection info and asked for recommendation on a specific point, how best to make calls to remote systems. Is it possible to have a zoom with your team to explain scenario? Paid if necessary.
If not please let me know as well. this 15 question limit discourages reaching out for your assistance so I've been holding on to them for this kind of scenario.
Albert,
My original question was around the part regarding sending requests to remote systems that require require login sessions, these systems would all be on separate servers that I would not control. It was regarding the best way to do this, pulling the connection information from configuration on the tenant. Could you please reread the thread with the original question and my clarifications after initial response?
Hi Albert, Yes actually I was clarifying the remote call issue and would like some feedback on this point of my original quest, please?
When new data comes in ( new orders for example ) the module will kick off a distributed event (these will be local initially but the code should work for when we move to microservice, per the docs). The main application then subscribes to these events and should record the transaction locally on abp database, and then schedule and process a background job (using the hangfire implementation) that posts the transactions into the appropriate remote backend.
Okay, thinking that you have a microservice application now since you want to manage transactions with database and background jobs. There is also a pattern for microservice transactions, which is called inbox-outbox pattern. And it happens to be that ABP will be implementing this pattern in v5. Check the annoucements about it.
Thanks, I did see the announcement earlier and am looking forward to it, but don't want to wait 2 months to start working on this, I can refactor later. Right now my app will not be a ms, but a mono with modules.
Does this make sense to do? Also since the background jobs seems to be picked up from the queue sequentially and there could be many jobs and tenants, would we run into a problem where there could be a ton of transactions queued and they'd only be processed sequentially so a particular tenant could see huge delays getting their transactions in?
I suggest checking transactional outbox pattern which we already implement. I don't think there will be a delay problem for tenants.
Okay, I'll search the forums and docs, if you have a direct link great.
A bigger concern is the fact that creating a bunch of httpclients to make the outgoing requests to the remote backends could cause resource exhaustion. In the past I've used an httpclient in DI to make the requests, however there's a problem here, and that is that each tenant will configure via settings management their remote backend url, these are different servers (but all the same software so contracts are the same).
I fail to understand the usage of http requests in here. Since you are in distributed system, why not using message broker (rabbitmq, kafka etc) async communication instead of http requests? Simply adapt for async communication over synced communication to prevent it from the begining.
I'm not currently on microservices but regardless, I'm sending requests to an external, remote, non-managed backend. For more clarity, we implement backend ERP systems, these have web api. These systems are administered by our clients. We will send data from our abp app to these remote systems, it must be through http :).
When the transaction is processed and send to the remote backend, the url will be different because they are different servers.
There are service locators (envoy, consul etc) for that. It's only job is to find the related service.
Each tenant will have different url to their remote backend server that we don't manage. We simply send the appropriate transactions via api. This abpp app will mostly be a multitenant integration platform.
To complicate matters most, the remote backend requires Login -> Receive SesssionID -> Then send this in the header of every subsequent request. In non multi-tenant implementations where its only one backend the application is sending these requests to, i simply use an interceptor to modify the header on the outgoing request.
No no no. You don't send any session id or something over the network for internal communication. If you want to use synched communication over http, it will be using Client Credential Flow grant type of OAuth2.0 without user credentials. Don't try to re-invent bicycle if it is about security and if your job is not creating bicycles for security.
Right, its not internal communication, and the remote systems only have one authentication mechanism, which is to send user and pass, receive a 30 min session id, and send this with subsequent requests.
In multi-tenant I assume the best thing to do would be to login -> send to redis cache for the tenant, and check this each time in the future when a request needs to go out and its for a particular tenant ID.
Multitenancy in ABP framework is very nicely abstracted and you can use with resolvers or a midware. You can check the source code.
I'm looking for any suggestion on how to accomplish this reliably without collapsing the application, keeping in mind that thousands of transactions can be posted in to the abp app, from different web carts, from different tenants.
The use of redis I mentioned here was intended to store the 30 min session id, and picking it up for requests that should go to the appropriate backend remote system, when it expires or is removed from cache (same right?) I'd have to login again to get a new session id and continue.
I would suggest leaning towards async messaging (eventbus over message broker) over synced messaging (http requests). Aso watching Mastering Chaos - A Netflix Guide to Microservices can give you ideas about how they solve millions of requests.
I know this is a loaded question. Just looking for direction to make the most of this framework using best practices.
You can also follow eShopOnAbp repository where we are building eShop application using Abp.
Thanks for the suggestions, I'll look up the netflix document. I started watching the eshoponabp repo since it was announced. I see a lot of action on it this last week.
Hi all, Thanks for the responses! Im subscribed to the thread but did not receive update over email so I missed your responses until now. I will clarify some parts here i noticed were not clear.
Hi!
I have some general architecture questions. I'm starting a new project on 4.4.3. The idea is that this will be a multitenant sas app. I will create several modules under the main application, each module will be for a specific webcart software, for example magento, shopify, etc. The implementation of the endpoints that remote carts will call and domain data for each of these is contained inside the module. When new data comes in ( new orders for example ) the module will kick off a distributed event (these will be local initially but the code should work for when we move to microservice, per the docs). The main application then subscribes to these events and should record the transaction locally on abp database, and then schedule and process a background job (using the hangfire implementation) that posts the transactions into the appropriate remote backend.
Does this make sense to do? Also since the background jobs seems to be picked up from the queue sequentially and there could be many jobs and tenants, would we run into a problem where there could be a ton of transactions queued and they'd only be processed sequentially so a particular tenant could see huge delays getting their transactions in?
A bigger concern is the fact that creating a bunch of httpclients to make the outgoing requests to the remote backends could cause resource exhaustion. In the past I've used an httpclient in DI to make the requests, however there's a problem here, and that is that each tenant will configure via settings management their remote backend url, these are different servers (but all the same software so contracts are the same). When the transaction is processed and send to the remote backend, the url will be different because they are different servers. To complicate matters most, the remote backend requires Login -> Receive SesssionID -> Then send this in the header of every subsequent request. In non multi-tenant implementations where its only one backend the application is sending these requests to, i simply use an interceptor to modify the header on the outgoing request.In multi-tenant I assume the best thing to do would be to login -> send to redis cache for the tenant, and check this each time in the future when a request needs to go out and its for a particular tenant ID.
I'm looking for any suggestion on how to accomplish this reliably without collapsing the application, keeping in mind that thousands of transactions can be posted in to the abp app, from different web carts, from different tenants.
I know this is a loaded question. Just looking for direction to make the most of this framework using best practices.