From d7045a5e5cfa8b923de59adaa792a897baa018ea Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 27 Nov 2025 15:12:08 +0100 Subject: [PATCH] Update documentdb compatibility. --- .../Contents/Text/DocumentDbTextIndex.cs | 23 ++++++------- .../Squidex.Data.MongoDb/ServiceExtensions.cs | 32 +++++++++++++------ .../Squidex.Data.MongoDb.csproj | 2 +- backend/src/Squidex/appsettings.json | 9 ++++++ .../MongoDb/TestHelpers/DocumentDbFixture.cs | 5 +-- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/DocumentDbTextIndex.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/DocumentDbTextIndex.cs index ecc96f476..03ac5f9ce 100644 --- a/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/DocumentDbTextIndex.cs +++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Text/DocumentDbTextIndex.cs @@ -10,7 +10,6 @@ using MongoDB.Driver.GeoJsonObjectModel; using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure; using Squidex.Infrastructure.ObjectPool; -using Squidex.Infrastructure.Translations; namespace Squidex.Domain.Apps.Entities.Contents.Text; @@ -38,21 +37,19 @@ public sealed class DocumentDbTextIndex(IMongoDatabase database, string shardKey Index.Text(x => x.Texts)), cancellationToken: ct); - await collection.Indexes.CreateManyAsync( [ new CreateIndexModel>( - Index - .Ascending(x => x.AppId) - .Ascending(x => x.ContentId)), - - new CreateIndexModel>( - Index - .Ascending(x => x.AppId) - .Ascending(x => x.SchemaId) - .Ascending(x => x.GeoField) - .Geo2DSphere(x => x.GeoObject)), - ], ct); + Index + .Ascending(x => x.AppId) + .Ascending(x => x.ContentId)), + new CreateIndexModel>( + Index + .Ascending(x => x.AppId) + .Ascending(x => x.SchemaId) + .Ascending(x => x.GeoField) + .Geo2DSphere(x => x.GeoObject)), + ], ct); } public override async Task?> SearchAsync(App app, GeoQuery query, SearchScope scope, diff --git a/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs b/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs index 1e07fff3e..f24e74b45 100644 --- a/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs +++ b/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Net; +using System.Security.Cryptography.X509Certificates; using System.Text.Json; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Caching.Distributed; @@ -63,14 +64,13 @@ public static class ServiceExtensions { public static void AddSquidexMongoEventStore(this IServiceCollection services, IConfiguration config) { - var mongoConfiguration = config.GetRequiredValue("eventStore:mongoDb:configuration"); var mongoDatabaseName = config.GetRequiredValue("eventStore:mongoDb:database"); services.AddMongoEventStore(config); services.AddSingletonAs(c => { var options = c.GetRequiredService>(); - var mongoClient = GetMongoClient(mongoConfiguration); + var mongoClient = GetMongoClient(config, "eventStore:mongoDb"); var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName); return new MongoEventStore(mongoDatabase, options); @@ -80,13 +80,12 @@ public static class ServiceExtensions public static void AddSquidexMongoAssetStore(this IServiceCollection services, IConfiguration config) { - var mongoConfiguration = config.GetRequiredValue("assetStore:mongoDb:configuration"); var mongoDatabaseName = config.GetRequiredValue("assetStore:mongoDb:database"); var mongoGridFsBucketName = config.GetRequiredValue("assetStore:mongoDb:bucket"); services.AddMongoAssetStore(c => { - var mongoClient = GetMongoClient(mongoConfiguration); + var mongoClient = GetMongoClient(config, "assetStore:mongoDb"); var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName); return new GridFSBucket(mongoDatabase, new GridFSBucketOptions @@ -98,7 +97,6 @@ public static class ServiceExtensions public static void AddSquidexMongoStore(this IServiceCollection services, IConfiguration config) { - var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration")!; var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database")!; var mongoContentDatabaseName = config.GetOptionalValue("store:mongoDb:contentDatabase", mongoDatabaseName)!; @@ -107,7 +105,7 @@ public static class ServiceExtensions return GetDatabase(c, mongoDatabaseName); }); - services.AddSingletonAs(c => GetMongoClient(mongoConfiguration)) + services.AddSingletonAs(c => GetMongoClient(config, "store:mongoDb")) .As(); services.AddSingletonAs(c => GetDatabase(c, mongoDatabaseName)) @@ -289,12 +287,28 @@ public static class ServiceExtensions .As(); } - private static IMongoClient GetMongoClient(string configuration) + private static IMongoClient GetMongoClient(IConfiguration config, string prefix) { - return Singletons.GetOrAdd(configuration, connectionString => + var mongoConfiguration = config.GetRequiredValue($"{prefix}:configuration")!; + var mongoCertificate = config.GetValue($"{prefix}:certificate"); + var cacheKey = $"{mongoConfiguration}_{mongoCertificate}"; + + return Singletons.GetOrAdd(cacheKey, _ => { - return MongoClientFactory.Create(connectionString, settings => + return MongoClientFactory.Create(mongoConfiguration, settings => { + if (!string.IsNullOrWhiteSpace(mongoCertificate)) + { + var certFile = new X509Certificate2(mongoCertificate); + + settings.SslSettings = new SslSettings + { + ClientCertificates = [certFile], + CheckCertificateRevocation = false, + ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true, + }; + } + settings.ClusterConfigurator = builder => { builder.Subscribe(new DiagnosticsActivityEventSubscriber()); diff --git a/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj b/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj index ecc802549..2fea86f27 100644 --- a/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj +++ b/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj @@ -31,7 +31,7 @@ - + diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index ba8150c63..71219e386 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -538,6 +538,9 @@ // Read More: https://docs.mongodb.com/manual/reference/connection-string/ "configuration": "mongodb://localhost", + // The path to the certificate. + "certificate": "", + // The name of the event store database. "database": "SquidexAssets", @@ -582,6 +585,9 @@ // Read More: https://docs.mongodb.com/manual/reference/connection-string/ "configuration": "mongodb://localhost", + // The path to the certificate. + "certificate": "", + // The name of the event store database. "database": "Squidex" }, @@ -627,6 +633,9 @@ // Read More: https://docs.mongodb.com/manual/reference/connection-string/ "configuration": "mongodb://localhost", + // The path to the certificate. + "certificate": "", + // The database for all your content collections (one collection per app). "contentDatabase": "SquidexContent", diff --git a/backend/tests/Squidex.Data.Tests/MongoDb/TestHelpers/DocumentDbFixture.cs b/backend/tests/Squidex.Data.Tests/MongoDb/TestHelpers/DocumentDbFixture.cs index f82b69e5d..f30afbbcf 100644 --- a/backend/tests/Squidex.Data.Tests/MongoDb/TestHelpers/DocumentDbFixture.cs +++ b/backend/tests/Squidex.Data.Tests/MongoDb/TestHelpers/DocumentDbFixture.cs @@ -34,13 +34,14 @@ public class DocumentDbFixture TestConfig.Configuration.GetValue("documentDb:configuration") ); - var cert = new X509Certificate2(TestConfig.Configuration.GetValue("documentDb:keyFile")!); + var certPath = TestConfig.Configuration.GetValue("documentDb:keyFile")!; + var certFile = new X509Certificate2(certPath); settings.RetryWrites = false; settings.RetryReads = false; settings.SslSettings = new SslSettings { - ClientCertificates = [cert], + ClientCertificates = [certFile], CheckCertificateRevocation = false, ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true, };