Skip to content

Add support for named clients in mongo collection#187

Merged
Gérald Barré (geraldbarre-workleap) merged 6 commits into
mainfrom
feature/EP-5071_Support-Client-CollectionAttribute
Mar 4, 2026
Merged

Add support for named clients in mongo collection#187
Gérald Barré (geraldbarre-workleap) merged 6 commits into
mainfrom
feature/EP-5071_Support-Client-CollectionAttribute

Conversation

@Yalpe

@Yalpe Carl Tremblay (Yalpe) commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Jira issue link: EP-5071

Description of changes

Officevibe has multiple clusters (Candor, Prod and Prod2). Services outside of the monolith consumes at least two of those (Prod and Prod2) as we are slowly strangling the monolith. Most services are using the old Officevibe libs for mongo, but I recently made a push to use the WL lib for feedback. One problem it solves is that we can use named clients and index both clusters (not possible with the old libs). The WL lib also offers more static analyzer support. However, the lib currently assumes that we want to use the default client when using assembly scanning for indexing or collection injection (DI). My proposal is to add support for the ClientName to the attribute/configuration and to take that into account in both cases.

[MongoCollection("people", ClientName = "anotherCluster", DatabaseName = "foo")]
public class PersonDocument : IMongoDocument
{
    // [...]
}

That way, we can still use assembly scanning to update our indexes. For a more concrete example, here is what our code looks like without this support:

            app.ApplicationServices
                .GetRequiredService<IMongoIndexer>()
                .UpdateIndexesAsync([
                    typeof(FeedbackLabelDocument),
                    typeof(FeedbackTopicDocument),
                    typeof(MemberDigestScheduleDocument),
                    typeof(ParticipationReportDocument),
                    typeof(ParticipationReportHistoryDocument)])
                .GetAwaiter()
                .GetResult();

            // Monolith indexes
            app.ApplicationServices
                .GetRequiredService<IMongoIndexer>()
                .UpdateIndexesAsync([
                    typeof(SurveyMetricConversationDocument)], clientName: "monolith")
                .GetAwaiter()
                .GetResult();

Injecting an IMongoCollection into a class would also use the proper client and remove the need for this boilerplate:

private readonly IMongoCollection<MyDocument> _collection;

public MyClass(IMongoClientProvider clientProvider)
{
    this._collection = clientProvider.GetClient("monolith").GetDatabase("my-database").GetCollection<MyDocument>();
}

Breaking changes

No breaking changes. The code will still default to the default client as the client name is optional.

  • Updated the documentation of the project to reflect the changes
  • Added new tests that cover the code changes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class support for routing Mongo collection resolution and index creation to a named Mongo client (cluster) via a new ClientName value on the collection attribute/configuration, enabling multi-cluster scenarios without manual per-client indexing/injection boilerplate.

Changes:

  • Adds ClientName to [MongoCollection] and to IMongoCollectionBuilder/configuration metadata, and propagates it through MongoCollectionInformationCache.
  • Updates IMongoCollection<TDocument> DI resolution (MongoCollectionProxy) to select the correct named client + named options based on the document’s declared ClientName.
  • Updates MongoIndexer.UpdateIndexesAsync to route each document type to its declared client when no explicit clientName override is provided; adds tests + README docs.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
wl-extensions-mongo.sln Adds a repo-level Visual Studio solution including all projects.
src/Workleap.Extensions.Mongo/MongoServiceCollectionExtensions.cs Persists ClientName from configuration-based registrations into the cache.
src/Workleap.Extensions.Mongo/MongoCollectionProxy.cs Resolves collections using the document’s declared ClientName (named client + named options).
src/Workleap.Extensions.Mongo/MongoCollectionMetadata.cs Adds ClientName to internal collection metadata.
src/Workleap.Extensions.Mongo/MongoCollectionBuilder.cs Adds builder support for setting ClientName.
src/Workleap.Extensions.Mongo/Indexing/MongoIndexer.cs Routes index updates by (effective) client and database.
src/Workleap.Extensions.Mongo.Tests/MultipleMongoClientTests.cs Adds tests for named-client collection resolution and per-type indexing routing.
src/Workleap.Extensions.Mongo.Tests/MongoCollectionBuilderTests.cs Adds tests for builder ClientName behavior.
src/Workleap.Extensions.Mongo.Tests/MongoCollectionAttributeTests.cs Adds tests for attribute ClientName behavior.
src/Workleap.Extensions.Mongo.Abstractions/MongoCollectionInformationCache.cs Stores/returns ClientName in cached collection info.
src/Workleap.Extensions.Mongo.Abstractions/MongoCollectionAttribute.cs Adds ClientName property to the public attribute API.
src/Workleap.Extensions.Mongo.Abstractions/IMongoCollectionBuilder.cs Adds ClientName(...) to the public builder interface.
README.md Documents how to use ClientName for multi-cluster setups.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Workleap.Extensions.Mongo/Indexing/MongoIndexer.cs Outdated
@PrincessMadMath

Copy link
Copy Markdown
Contributor

Copilot can you fix the error from the CI: https://github.com/workleap/wl-extensions-mongo/actions/runs/22632832147/job/65587481571?pr=187 since there is missing declared interface

Copilot AI commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Mathieu Gamache (@PrincessMadMath) I've opened a new pull request, #188, to work on those changes. Once the pull request is ready, I'll request review from you.

Comment thread wl-extensions-mongo.sln Outdated
Comment thread src/Workleap.Extensions.Mongo/Indexing/MongoIndexer.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Yalpe

Copy link
Copy Markdown
Contributor Author

Gérald Barré (@geraldbarre-workleap) I implemented the suggestions. There was a bug with the multi client test that I fixed using Claude. Here is the summary:

The test had two bugs:

Bug 1 — Invalid index field: NamedClientIndexDocumentIndexes tried to create an index on "_id", but MongoDB forbids creating a second index on _id with a different name (the id index is always there). Fixed by adding a real Tag property to NamedClientIndexDocument and indexing that instead.

Bug 2 — Wrong assertion: Assert.Contains("namedclientidx", fooIndexNames) checked for an exact name match, but IndexCreator always stores indexes as {user-prefix}_{sha256-hash} (e.g. namedclientidx_b0da3210...). Fixed by using the predicate overload: Assert.Contains(fooIndexNames, name => name.StartsWith("namedclientidx")).

@geraldbarre-workleap Gérald Barré (geraldbarre-workleap) merged commit c1929ec into main Mar 4, 2026
9 checks passed
@geraldbarre-workleap Gérald Barré (geraldbarre-workleap) deleted the feature/EP-5071_Support-Client-CollectionAttribute branch March 4, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants