Open Closed

using MongoDB in microservice-service inside microservice solution which uses efcore #1269


0
Neozzz created

We created a microservice solution using the following command: abp new ZW -t microservice-pro -u angular

Then we added a microservice-service to the solution using: abp new CompanyService -t microservice-service-pro

Now I want to use MongoDB on the newly added ┬Áservice-service and keep using the ef core for the main solution for identity and other related features.

I've already tried to add mongodb into CompanyService ┬Áservice-service. I am getting issues with

Please let me know if this is possible, and if so is there any best practice?

Thank you

  • ABP Framework version: v4.3
  • UI type: Angular
  • DB provider: EF Core & MongoDB

39 Answer(s)
  • 0
    gterdem created
    Support Team

    Hello,

    You need to replace .EntityFrameworkCore project with .MongoDB project and update the related dependencies.

    To use auto-migration, update connection string located in your microservice host.api appsettings.json. Check Database Migrations docs to understand which connection strings are used for.

  • 0
    Neozzz created

    Hi I added the MongoDB project and removed the EntityFameworkCore project. I am still facing the same problem. It looks like when I add mongo reference its trying to use everything associated with the project like saas and admin to work with mongo. I only want to use mongo for CRUD purposes of an entity.

    Please help Tx.

  • 0
    liangshiwei created
    Support Team

    Hi,

    Update connection string to mongodb://localhost:27017/ZW_Administration

  • 0
    Neozzz created

    I dont want to use admin and saas in mongo. I want to use it as sql as they're part of the main microservice sln called 'ZW' which uses efcore. My microservice "CompanyService" service should use mongo only for crud on the entities in that.

    As explained in the first post:

    ZW - name of main microservice solution uses angular and efcore ZW.CompanyService - name of the microservice service project which uses angular and mongo.

  • 0
    gterdem created
    Support Team

    As far as I understand, you have some misconfiguration for microservices:

    Infrastructural Microservices:

    AdministrationService: If you want to have Sql-Server db, must have AdministrationService.EntityFrameworkCore project with a sql-server connection string which is default when you download template. IdentityService: If you want to have Sql-Server db, must have IdentityService.EntityFrameworkCore project with a sql-server connection string which is default when you download template. SaasService: If you want to have Sql-Server db, must have SaasService.EntityFrameworkCore project with a sql-server connection string which is default when you download template.

    If you want to change infrastructural microservice databases, you need to create a new .MongoDB project and replace it with .EntityFrameworkCore project with required module mongodb references.

    New Microservice:

    CompanyService : If you want to use MongoDB, must have CompanyService.MongoDB project with a mongodb connection string like mongodb://localhost:27017/ZW_CompanyService.

    Same as here, create a new CompanyService.MongoDB (or whatever you want to name it) and update connection strings. Check database-migrations docs for more information.

  • 0
    ServiceBot created
    Support Team

    This question has been automatically marked as stale because it has not had recent activity.

  • 0
    Neozzz created

    Hi,

    the microservice template has gotten better by leaps and bounds since the last time I raised this issue. Now we can add a service to a microservice solution by using:

    abp new OrderService -t microservice-service-pro
    

    This creates a solution with efcore.

    Do we have a similar command, say:

    abp new ProductService -t microservice-service-pro -d mongodb
    

    That allows us to add a service that uses mongodb for storing its domain entities? This service will be using the efcore backing given by the microservice for identity, admin, saas etc.

    The above command is only for reference, it doesn't generate a project with mongodb.

    Now to the question.

    Is there a command to straight away generate a microservice service that uses mongodb? If not, is there any references that we can check to see how to implement one? Could you please let us know how to achieve this?

    Thank you :)

  • 0
    Neozzz created

    Hi, any updates please.

  • 0
    Neozzz created

    helooo anybody there?

  • 0
    liangshiwei created
    Support Team

    Hi,

    Is there a command to straight away generate a microservice service that uses mongodb?

    CLI does not support -d arg for microservice template, but I think this is a useful feature, we will consider support it.

    If not, is there any references that we can check to see how to implement one? Could you please let us know how to achieve this?

    No document yet, you can create an app template with ef core and other template with mongod to compare.

  • 0
    Neozzz created

    Hi Liang,

    I am already doing it, I'll keep the thread active with errors that I'll run into on the way ;) Btw it'd be good to have something to look into while we do this. May I suggest you that from your next iteration of microservice template, you could include a microservice service that uses mongo as well? Right now we have product-service that uses ef core, why not have one more service that uses mongo. This would be highly helpful.

  • 0
    vincent.goh created

    Hi Neozzz,

    I'm trying to achieve the same thing as you but I'm still trying to figure things out. It will be great if you could share how you change the new microservice to use MongoDB while the other microservices are still using EF Core.

    Thanks!

  • 0
    Neozzz created

    Hi Vincent,

    we as users of the platform wouldn't know 100% how the platform works and hence it's really difficult for us to do this task, I figure. However I was trying it out, but let's hope with the help of the abp support team we can find some solution. If we manage to do that, I'll put it in abp community and share it :)

  • 0
    Neozzz created

    Hi Liang,

    I have updated the project with mongodb. i havent integrated it with the main microservice solution. Could you please take a look at the mongodb integration? Meanwhile, could you please check error with gateway that i mentioned in ticket #2065? Both are in the same repo.

    Looking forward to your reply :)

  • 0
    liangshiwei created
    Support Team

    Hi,

    We have no plan support MongoDB for microservice template yet. but I will give you some suggestions to switch to MongoDB.

  • 0
    Neozzz created

    Hi Liang,

    thank you. awaiting your reply.

    have you checked #2065?

    thank you

  • 0
    liangshiwei created
    Support Team

    Hi,

    There are many steps to change to mongodb. so I made an example, will send to your email, you can check it.

  • 0
    Neozzz created

    Thanks a lot Liang.

    Waiting for your mail :)

  • 0
    vincent.goh created

    Hi Liang, if you don't mind, could you email me the changes needed for mongodb as well?

    Thanks!

  • 0
    liangshiwei created
    Support Team

    Okay, please email me [email protected]

    Also, We will write a guide to help switch to MongoDB, I will reply when the guide is complete.

  • 0
    Neozzz created

    Hi liang,

    Been a while :) While running your project I got the following error:

    Please advise.

    Thank you :)

  • 0
    liangshiwei created
    Support Team

    Hi,

    Make sure your MongoDB supports transcation.

    Or disable transactions:

    Configure<AbpUnitOfWorkDefaultOptions>(options =>
    {
        options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
    });
    
  • 0
    Neozzz created

    Thanks Liang!

    Thank you for the solution, which uses mongo for all the db requirements. I tried to put a mongo project into the main microservice solution that uses efcore for the admin, saas and other common operations. I am getting some errors from the database migration event handler. Could you please guide me on how to resolve this?

    I'll share the repo access with you, or if you'd like to take a look at this remotely, please let me know.

    Thanks for the help :)

  • 0
    Neozzz created

    hi liang, kind reminder.

  • 0
    Neozzz created

    hi,

    please update.

  • 0
    maliming created
    Support Team

    hi Neozzz

    You can completely disable transactions if your database doesn't support it.

    https://support.abp.io/QA/Questions/2176#answer-a0b36b39-5bdd-3259-a49e-3a005ca3118c

    https://github.com/abpframework/abp/pull/10658

  • 0
    Neozzz created

    hi maliming,

    this was my question: https://support.abp.io/QA/Questions/1269/using-MongoDB-in-microservice-service-inside-microservice-solution-which-uses-efcore#answer-3c384c74-c57f-d8c8-f71a-3a005a05e232

  • 0
    Neozzz created

    we have a microservice-pro solution that uses efcore. i need to add a microservice service inside this solution. but this has to use mongo for storing its entities but at the same time has to make use of the efcore for saas, admin etc.

    i have tried something, but while migrating we've to divide the concerns to both mongo and efcore. guess this is where am having the issue.

    please lemme know how to proceed.

  • 0
    maliming created
    Support Team

    hi

    Can you try to apply the changes of this PR to your mongodb?

    https://github.com/abpframework/abp/pull/10658/files

  • 0
    Neozzz created
    [DependsOn(
            typeof(PJNameSharedHostingMicroservicesModule),
            typeof(MySvcApplicationModule),
            typeof(MySvcHttpApiModule),
            typeof(MySvcMongoDbModule)
            )]
        public class MySvcHttpApiHostModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {           
                context.Services.AddSingleton(typeof(UnitOfWorkManager));
                Configure<AbpUnitOfWorkDefaultOptions>(options =>
                {
                    options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
                });
                JwtBearerConfigurationHelper.Configure(context, "MySvc");
                SwaggerConfigurationHelper.Configure(context, "MySvc API");
            }
    
            public override void OnApplicationInitialization(ApplicationInitializationContext context)
            {
                var app = context.GetApplicationBuilder();
                var env = context.GetEnvironment();
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseCorrelationId();
                app.UseAbpRequestLocalization();
                app.UseStaticFiles();
                app.UseRouting();
                app.UseAuthentication();
                app.UseAbpClaimsMap();
                app.UseMultiTenancy();
                app.UseAuthorization();
                app.UseSwagger();
                app.UseSwaggerUI(options =>
                {
                    options.SwaggerEndpoint("/swagger/v1/swagger.json", "MySvc API");
                });
                app.UseAbpSerilogEnrichers();
                app.UseAuditing();
                app.UseUnitOfWork();
                app.UseConfiguredEndpoints();
            }
    
            public override void OnPostApplicationInitialization(ApplicationInitializationContext context)
            {
                using (var scope = context.ServiceProvider.CreateScope())
                {
                    AsyncHelper.RunSync(
                        () => scope.ServiceProvider
                            .GetRequiredService<MySvcDatabaseMigrationChecker>()
                            .CheckAsync()
                    );
                }
            }
        }
    
        [Dependency(ReplaceServices = true)]
        public class MyUnitOfWorkManager : IUnitOfWorkManager, ISingletonDependency
        {
            private readonly UnitOfWorkManager _innerUnitOfWorkManager;
    
            public MyUnitOfWorkManager(UnitOfWorkManager innerUnitOfWorkManager)
            {
                _innerUnitOfWorkManager = innerUnitOfWorkManager;
            }
    
            public IUnitOfWork Begin(AbpUnitOfWorkOptions options, bool requiresNew = false)
            {
                options.IsTransactional = false;
                return _innerUnitOfWorkManager.Begin(options, requiresNew);
            }
    
            public IUnitOfWork Reserve(string reservationName, bool requiresNew = false)
            {
                return _innerUnitOfWorkManager.Reserve(reservationName, requiresNew);
            }
    
            public void BeginReserved(string reservationName, AbpUnitOfWorkOptions options)
            {
                options.IsTransactional = false;
                _innerUnitOfWorkManager.BeginReserved(reservationName, options);
            }
    
            public bool TryBeginReserved(string reservationName, AbpUnitOfWorkOptions options)
            {
                options.IsTransactional = false;
                return _innerUnitOfWorkManager.TryBeginReserved(reservationName, options);
            }
    
            public IUnitOfWork Current => _innerUnitOfWorkManager.Current;
        }
    }
    
  • 0
    Neozzz created

    I have done the above changes as you suggested. But I am getting the following error. I'd request you to take a look at the code.

    2021-11-24 22:37:37.642 +04:00 [ERR] An exception was thrown while activating ZW.mySvc.DbMigrations.mySvcDatabaseMigrationEventHandler.
    Autofac.Core.DependencyResolutionException: An exception was thrown while activating ZW.mySvc.DbMigrations.mySvcDatabaseMigrationEventHandler.
     ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Volo.Abp.Autofac.AbpAutofacConstructorFinder' on type 'ZW.mySvc.DbMigrations.mySvcDatabaseMigrationEventHandler' can be invoked with the available services and parameters:
    Cannot resolve parameter 'System.String databaseName' of constructor 'Void .ctor(Volo.Abp.MultiTenancy.ICurrentTenant, Volo.Abp.Uow.IUnitOfWorkManager, Volo.Abp.MultiTenancy.ITenantStore, Volo.Saas.Tenants.ITenantRepository, Volo.Abp.EventBus.Distributed.IDistributedEventBus, System.String, System.IServiceProvider)'.
       at Autofac.Core.Activators.Reflection.ReflectionActivator.GetAllBindings(ConstructorBinder[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)
       at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
       at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
       at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       --- End of inner exception stack trace ---
    

    Please let me know how to proceed.

  • 0
    maliming created
    Support Team

    Can you try this

    https://support.abp.io/QA/Questions/1269#answer-39041f27-8e29-5711-781e-3a0061b46232

  • 0
    Neozzz created

    I added the following:

    context.Services.AddSingleton(typeof(UnitOfWorkManager));
                context.Services.AddSingleton(typeof(UnitOfWorkMongoDbContextProvider<>));
                context.Services.AddSingleton(typeof(AbpMongoDbContextOptions));
    

    The error:

     [ERR] An exception was thrown while activating ZW.MySvc.DbMigrations.MySvcDatabaseMigrationEventHandler.
    Autofac.Core.DependencyResolutionException: An exception was thrown while activating ZW.MySvc.DbMigrations.MySvcDatabaseMigrationEventHandler.
     ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Volo.Abp.Autofac.AbpAutofacConstructorFinder' on type 'ZW.MySvc.DbMigrations.MySvcDatabaseMigrationEventHandler' can be invoked with the available services and parameters:
    Cannot resolve parameter 'System.String databaseName' of constructor 'Void .ctor(Volo.Abp.MultiTenancy.ICurrentTenant, Volo.Abp.Uow.IUnitOfWorkManager, Volo.Abp.MultiTenancy.ITenantStore, Volo.Saas.Tenants.ITenantRepository, Volo.Abp.EventBus.Distributed.IDistributedEventBus, System.String, System.IServiceProvider)'.
       at Autofac.Core.Activators.Reflection.ReflectionActivator.GetAllBindings(ConstructorBinder[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)
       at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
       at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext ctxt)
       at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext ctxt, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
       at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
    
  • 0
    maliming created
    Support Team

    https://github.com/abpframework/abp/pull/10658/files

  • 0
    Neozzz created

    after adding that only i added the DI code.

  • 0
    Neozzz created

    I had created a new class DatabaseMigrationEventHandlerBaseMongo for handling mongo db instead of DatabaseMigrationEventHandlerBase which uses ef core. It inherits from AbpMongoDbContext instead of AbpDbContext.

    I think this is causing the issue.

  • 0
    Neozzz created

    If you could check the code that'd be great. Taking remote would be easier for you as the infra is running and debugging may be easier. Let me know.

  • 0
    liangshiwei created
    Support Team

    Hi,

    I don't know about your project details, can you create a new project to reproduce the problem and share to me? [email protected] thanks.

  • 0
    liangshiwei created
    Support Team

    The guide: https://github.com/abpio/abp-commercial-docs/pull/146