Open Closed

A sample project to change the template services(saas, identity, administration) db provider to MongoDB in a Microservice Project #3258


User avatar
0
jeffbuot created

Hello, can anyone provide a sample project of changing or using a MongoDB provider for a microservice solution? ABP Suite only offers creating it with an EFCore SqlServer db provider. I understand that there is a documentation guide(https://docs.abp.io/en/commercial/latest/guides/microservice-mongodb) for changing the default into mongo db but it only shows changing the product service. I just want to know how to change also the administration, identity, saas services since its dbcontexts depends on many other module's db context. I'm afraid I might miss something or might not do it on a right way if I do it myself.

Cheers, Jeff

  • ABP Framework version: v5.3.0
  • UI type: Blazor

9 Answer(s)
  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    Actually, It is pretty much the same.

    Follow the guide and replace the EntityFramework layer with MongoDB in AdministrationService. At the end, AdministrationServiceDbContext must be implementing IAbpMongoDbContext.

    For DbMigrations, navigate to MyCompanyName.Shared.Hosting.Microservices project references and uncomment the Volo.Abp.MongoDB reference:

    <!--        Un-comment if you are using mongodb in any microservice -->
    <!--        <ProjectReference Include="..\..\..\..\..\..\abp\framework\src\Volo.Abp.MongoDB\Volo.Abp.MongoDB.csproj" />-->
    

    Navigate to MongoDB folder and to PendingMongoDbMigrationsChecker.cs file and uncomment the public abstract class PendingMongoDbMigrationsChecker<TDbContext> class.

    Navigate to AdministrationServiceDatabaseMigrationChecker and update it to extend PendingMongoDbMigrationsChecker instead of PendingEfCoreMigrationsChecker.

    The same goes for all the microservices.

  • User Avatar
    0
    jeffbuot created

    Hi, gterdem thanks for the response. How about this one, I see IPermissionManagementDbContext inherits IEfCoreDbContext and also the others. Q1: What are the existing interface for MongoDB that is equivalent to IPermissionManagementDbContext, ISettingManagementDbContext, etc.. that inherits IAbpMongoDbContext? Q2: The model builder configuration here are from Volo.Abp.*.EntityFrameworkCore namespace, are there also ones equivalent for MongoDB?

    using Microsoft.EntityFrameworkCore;
    using Volo.Abp.AuditLogging;
    using Volo.Abp.AuditLogging.EntityFrameworkCore;
    using Volo.Abp.BlobStoring.Database;
    using Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
    using Volo.Abp.Data;
    using Volo.Abp.EntityFrameworkCore;
    using Volo.Abp.FeatureManagement;
    using Volo.Abp.FeatureManagement.EntityFrameworkCore;
    using Volo.Abp.LanguageManagement;
    using Volo.Abp.LanguageManagement.EntityFrameworkCore;
    using Volo.Abp.PermissionManagement;
    using Volo.Abp.PermissionManagement.EntityFrameworkCore;
    using Volo.Abp.SettingManagement;
    using Volo.Abp.SettingManagement.EntityFrameworkCore;
    using Volo.Abp.TextTemplateManagement.EntityFrameworkCore;
    using Volo.Abp.TextTemplateManagement.TextTemplates;
    
    namespace ProjectName.AdministrationService.EntityFrameworkCore;
    
    [ConnectionStringName(AdministrationServiceDbProperties.ConnectionStringName)]
    public class AdministrationServiceDbContext : AbpDbContext<AdministrationServiceDbContext>,
        IPermissionManagementDbContext,
        ISettingManagementDbContext,
        IFeatureManagementDbContext,
        IAuditLoggingDbContext,
        ILanguageManagementDbContext,
        ITextTemplateManagementDbContext,
        IBlobStoringDbContext
    {
        public DbSet<PermissionGrant> PermissionGrants { get; set; }
        public DbSet<Setting> Settings { get; set; }
        public DbSet<FeatureValue> FeatureValues { get; set; }
        public DbSet<AuditLog> AuditLogs { get; set; }
        public DbSet<Language> Languages { get; set; }
        public DbSet<LanguageText> LanguageTexts { get; set; }
        public DbSet<TextTemplateContent> TextTemplateContents { get; set; }
        public DbSet<DatabaseBlobContainer> BlobContainers { get; set; }
        public DbSet<DatabaseBlob> Blobs { get; set; }
    
        public AdministrationServiceDbContext(DbContextOptions<AdministrationServiceDbContext> options)
            : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.ConfigurePermissionManagement();
            modelBuilder.ConfigureSettingManagement();
            modelBuilder.ConfigureFeatureManagement();
            modelBuilder.ConfigureAuditLogging();
            modelBuilder.ConfigureLanguageManagement();
            modelBuilder.ConfigureTextTemplateManagement();
            modelBuilder.ConfigureBlobStoring();
        }
    }
    
    

    Cheers, Jeff B

  • User Avatar
    1
    gterdem created
    Senior .NET Developer

    Q1: What are the existing interface for MongoDB that is equivalent to IPermissionManagementDbContext, ISettingManagementDbContext, etc.. that inherits IAbpMongoDbContext?

    You need to use the relevant nuget package. For permission management It is Volo.Abp.PermissionManagement.MongoDB instead of Volo.Abp.PermissionManagement.EntityFrameworkCore. Same goes for all the modules.

    Q2: The model builder configuration here are from Volo.Abp.*.EntityFrameworkCore namespace, are there also ones equivalent for MongoDB?

    Yes, there are. You need to use the correct NuGet package as I have mentioned above.

    IdentityService.MongoDB.csproj should contain packages as below:

    <ItemGroup>
            <PackageReference Include="Volo.Abp.MongoDB" Version="5.3.0" />
            <PackageReference Include="Volo.Abp.Identity.Pro.MongoDB" Version="5.3.0" />
            <PackageReference Include="Volo.Abp.IdentityServer.MongoDB" Version="5.3.0" />
        </ItemGroup>
    
        <ItemGroup>
            <ProjectReference Include="..\MyFoodStore.IdentityService.Domain\MyFoodStore.IdentityService.Domain.csproj" />
        </ItemGroup>
    

    IdentityServiceDbContext should look like:

    [ConnectionStringName(IdentityServiceDbProperties.ConnectionStringName)]
    public class IdentityServiceDbContext: AbpMongoDbContext, IIdentityProMongoDbContext, IAbpIdentityServerMongoDbContext
    {
        public IMongoCollection<IdentityUser> Users { get; set; }
        public IMongoCollection<IdentityRole> Roles { get; set; }
        public IMongoCollection<IdentityClaimType> ClaimTypes { get; set; }
        public IMongoCollection<OrganizationUnit> OrganizationUnits { get; set; }
        public IMongoCollection<IdentitySecurityLog> SecurityLogs { get; set; }
        public IMongoCollection<IdentityLinkUser> LinkUsers { get; set; }
        public IMongoCollection<ApiResource> ApiResources { get; set; }
        public IMongoCollection<ApiScope> ApiScopes { get; set; }
        public IMongoCollection<Client> Clients { get; set; }
        public IMongoCollection<IdentityResource> IdentityResources { get; set; }
        public IMongoCollection<PersistedGrant> PersistedGrants { get; set; }
        public IMongoCollection<DeviceFlowCodes> DeviceFlowCodes { get; set; }
        
        protected override void CreateModel(IMongoModelBuilder modelBuilder)
        {
            base.CreateModel(modelBuilder);
    
            modelBuilder.ConfigureIdentityPro();
            modelBuilder.ConfigureIdentityServer();
        }
    }
    

    You need to use the correct packages.

  • User Avatar
    0
    jeffbuot created

    Oh I see, that helps. Thanks a lot!

  • User Avatar
    0
    jeffbuot created

    One more related question, why do there are some collections missing on mongodb interface over efcore? e.g. IPaymentDbContext has DbSet<GatewayPlan> GatewayPlans { get; } but GatewayPlans mongo collection is not present on IPaymentMongoDbContext? Same with some interface collections on IdentityServiceDbContext over IdentityServiceDbContext.

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    They shouldn't be missing, we add MongoDB for all modules.

    You can check Commercial NuGet packages at https://abp.io/Packages. They are not listed at https://www.nuget.org.

    Some of the commercial modules are using the open-source MongoDB layer while some of them can use the commercial layer.

  • User Avatar
    0
    jeffbuot created

    For example the IdentityService: *.MongoDb based from your example:

    //using ...
    
    namespace ProjectName.IdentityService.MongoDb;
    
    [ConnectionStringName(IdentityServiceDbProperties.ConnectionStringName)]
    public class IdentityServiceDbContext : AbpMongoDbContext,
        IIdentityServiceDbContext,
        IIdentityProMongoDbContext, 
        IAbpIdentityServerMongoDbContext
    {
        public IMongoCollection<IdentityUser> Users { get; }
        public IMongoCollection<IdentityRole> Roles { get; }
        public IMongoCollection<IdentityClaimType> ClaimTypes { get; }
        public IMongoCollection<OrganizationUnit> OrganizationUnits { get; }
        public IMongoCollection<IdentitySecurityLog> SecurityLogs { get; }
        public IMongoCollection<IdentityLinkUser> LinkUsers { get; }
        public IMongoCollection<ApiResource> ApiResources { get; }
        public IMongoCollection<ApiScope> ApiScopes { get; }
        public IMongoCollection<Client> Clients { get; }
        public IMongoCollection<IdentityResource> IdentityResources { get; }
        public IMongoCollection<PersistedGrant> PersistedGrants { get; }
        public IMongoCollection<DeviceFlowCodes> DeviceFlowCodes { get; }
        
       //Create Model
    }
    

    On EFCore:

    //using ...
    
    namespace ProjectName.IdentityService.EntityFramework;
    
    [ConnectionStringName(IdentityServiceDbProperties.ConnectionStringName)]
    public class IdentityServiceDbContext : AbpDbContext<IdentityServiceDbContext>, IIdentityDbContext, IIdentityServerDbContext
    {
        public DbSet<IdentityUser> Users { get; set; }
        public DbSet<IdentityRole> Roles { get; set; }
        public DbSet<IdentityClaimType> ClaimTypes { get; set; }
        public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
        public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
        public DbSet<IdentityLinkUser> LinkUsers { get; set; }
        public DbSet<ApiResource> ApiResources { get; set; }
        public DbSet<ApiResourceSecret> ApiResourceSecrets { get; set; }
        public DbSet<ApiResourceClaim> ApiResourceClaims { get; set; }
        public DbSet<ApiResourceScope> ApiResourceScopes { get; set; }
        public DbSet<ApiResourceProperty> ApiResourceProperties { get; set; }
        public DbSet<ApiScope> ApiScopes { get; set; }
        public DbSet<ApiScopeClaim> ApiScopeClaims { get; set; }
        public DbSet<ApiScopeProperty> ApiScopeProperties { get; set; }
        public DbSet<IdentityResource> IdentityResources { get; set; }
        public DbSet<IdentityResourceClaim> IdentityClaims { get; set; }
        public DbSet<IdentityResourceProperty> IdentityResourceProperties { get; set; }
        public DbSet<Client> Clients { get; set; }
        public DbSet<ClientGrantType> ClientGrantTypes { get; set; }
        public DbSet<ClientRedirectUri> ClientRedirectUris { get; set; }
        public DbSet<ClientPostLogoutRedirectUri> ClientPostLogoutRedirectUris { get; set; }
        public DbSet<ClientScope> ClientScopes { get; set; }
        public DbSet<ClientSecret> ClientSecrets { get; set; }
        public DbSet<ClientClaim> ClientClaims { get; set; }
        public DbSet<ClientIdPRestriction> ClientIdPRestrictions { get; set; }
        public DbSet<ClientCorsOrigin> ClientCorsOrigins { get; set; }
        public DbSet<ClientProperty> ClientProperties { get; set; }
        public DbSet<PersistedGrant> PersistedGrants { get; set; }
        public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
    
        // Constructor
        // OnModelCreating
    }
    

    You can see there are collections that are not on the mongodbcontext. I can't seem to find interface for mongo that has the same required collections from Volo.Abp.IdentityServer.EntityFrameworkCore.IIdentityServerDbContext

  • User Avatar
    0
    jeffbuot created

    On Identity Mongo interface:

    public interface IIdentityProMongoDbContext : IAbpIdentityMongoDbContext, IAbpMongoDbContext
    {
    }
    public interface IAbpIdentityMongoDbContext : IAbpMongoDbContext
    {
        IMongoCollection<IdentityUser> Users { get; }
    
        IMongoCollection<IdentityRole> Roles { get; }
    
        IMongoCollection<IdentityClaimType> ClaimTypes { get; }
    
        IMongoCollection<OrganizationUnit> OrganizationUnits { get; }
    
        IMongoCollection<IdentitySecurityLog> SecurityLogs { get; }
    
        IMongoCollection<IdentityLinkUser> LinkUsers { get; }
    }
    

    Identity Efcore Interface

    public interface IIdentityServerDbContext : IEfCoreDbContext
    {
        #region ApiResource
    
        DbSet<ApiResource> ApiResources { get; }
    
        DbSet<ApiResourceSecret> ApiResourceSecrets { get; }
    
        DbSet<ApiResourceClaim> ApiResourceClaims { get; }
    
        DbSet<ApiResourceScope> ApiResourceScopes { get; }
    
        DbSet<ApiResourceProperty> ApiResourceProperties { get; }
    
        #endregion
    
        #region ApiScope
    
        DbSet<ApiScope> ApiScopes { get; }
    
        DbSet<ApiScopeClaim> ApiScopeClaims { get; }
    
        DbSet<ApiScopeProperty> ApiScopeProperties { get; }
    
        #endregion
    
        #region IdentityResource
    
        DbSet<IdentityResource> IdentityResources { get; }
    
        DbSet<IdentityResourceClaim> IdentityClaims { get; }
    
        DbSet<IdentityResourceProperty> IdentityResourceProperties { get; }
    
        #endregion
    
        #region Client
    
        DbSet<Client> Clients { get; }
    
        DbSet<ClientGrantType> ClientGrantTypes { get; }
    
        DbSet<ClientRedirectUri> ClientRedirectUris { get; }
    
        DbSet<ClientPostLogoutRedirectUri> ClientPostLogoutRedirectUris { get; }
    
        DbSet<ClientScope> ClientScopes { get; }
    
        DbSet<ClientSecret> ClientSecrets { get; }
    
        DbSet<ClientClaim> ClientClaims { get; }
    
        DbSet<ClientIdPRestriction> ClientIdPRestrictions { get; }
    
        DbSet<ClientCorsOrigin> ClientCorsOrigins { get; }
    
        DbSet<ClientProperty> ClientProperties { get; }
    
        #endregion
    
        DbSet<PersistedGrant> PersistedGrants { get; }
    
        DbSet<DeviceFlowCodes> DeviceFlowCodes { get; }
    }
    

    Why are some of those collections missing on the mongo interface?

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    The different tables are many-to-many tables. They are represented as different tables in EfCore while in MongoDB it is in the related aggregate root.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19