We have an XData/Webcore application that takes care of it's own logins at present. At present we have a server per client (there's only 2 at the moment), but want to convert it to a Multi-Tenant server with each tenant having their own database.
I want to use Sphinx to manage the logins and trying to think of the best way to do this:
A separate Sphinx server: This has advantages that if anyone has access to more than one system, they can select which one
This is key information. If this is something you consider implementing in future, then it completely discards option 2 and a multi-tenant Sphinx server.
But if the clients will be completely separated, meaning a user "a" will access "client1", and if there exists a "client2" you will want that "a' makes a new registration, use a different password, etc, to access "client2", then the setup is different.
There is no right answer and no best scenario, you really have to decide if your setup should have different users for different clients, or if the users will be shared.
Once this is decided, then we can proceed to suggest some implementations, and indeed a few options can be provided for each scenario.
Thinking it through I don't think that anyone will need access to more than one system. The only occasion would be for support, but a different login for each system isn't a bad idea even then. So that would keep clients completely separated.
In this case you have both options: a completely separate Sphinx server for each of your clients, or a single Sphinx multi-tenant server that authenticates users from each client, but still having the users separated.
Unfortunately there is no current demo, but use is relatively simple: instead of using a TXDataConnectionPool component, you will use a TXDataMultiDBConnectionPool. Then you create a handler for the event OnCreateDatabasePoolEvent:
TCreateDatabasePoolEvent = procedure(Sender: TObject; const DatabaseId: string;
var Pool: IDBConnectionPool) of object;
Such event will pass the DatabaseId (just another name for the tenant id).
With the tenant id provided, you should set the Pool variable with the respective connection pool for that tenant.
Thus, if tenant is "A", create and return a IDBConnectionPool that connects to the database "A" and do the same for B, C, etc..
The tenant id is automatically set by the tenant middleware, so that part is transparent.
On the second point. I am using a TXDataMultiDBConnectionPool which doesn't have the GetPool Method as it doesn't implement ITenantDBPoolProvider interface either itself or it's ancestors. So I'm wondering if
Result := (MultiDBConnectionPool.GetPoolInterface as ITenantDBPoolProvider).GetPool(TenantId).GetConnection;