【问题标题】:Spring data mongoDB lazy configuration of database connectionSpring data mongoDB 数据库连接的懒配置
【发布时间】:2018-10-27 18:45:15
【问题描述】:

我有一个多租户 mongoDB 应用程序,我们假设 从 HTTP 请求标头中的租户名称中选择与正确数据库的正确连接(我使用先前准备的带有租户名称的属性文件)。 当应用程序启动时,mongoDB 正在配置并且我没有关于租户的信息,因为没有发送到应用程序的请求,所以我不知道我应该连接到哪个数据库。当我尝试从 mongo 存储库获取一些数据时(然后我从 HTTP 请求中获得租户名称),是否有可能动态配置 mongoDB 与数据库的连接?

MongoDb 配置:

@Configuration
public class MongoDbConfiguration {

    private final MongoConnector mongoConnector;

    @Autowired
    public MongoDbConfiguration(MongoConnector mongoConnector) {
        this.mongoConnector = mongoConnector;
    }

    @Bean
    public MongoDbFactory mongoDbFactory() {
        return new MultiTenantSingleMongoDbFactory(mongoConnector, new MongoExceptionTranslator());
    }

    @Bean
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoDbFactory());
    }
}

【问题讨论】:

    标签: java spring mongodb multi-tenant spring-data-mongodb


    【解决方案1】:
    @Component
    @Slf4j
    public class MultiTenantMongoDbFactory extends SimpleMongoDbFactory {
    
      private static final Logger logger = LoggerFactory.getLogger(MultiTenantMongoDbFactory.class);
    
      private Map<String, DbConfig> tenantToDbConfig;
    
      private Map<String, MongoDatabase> tenantToMongoDatabase;
    
      @Autowired
      public MultiTenantMongoDbFactory(
          final @Qualifier("sibTenantContexts") Map<String, DbConfig> dbConfigs,
          final SibEnvironment env) {
    
        super(new MongoClientURI(env.getDefaultDatabase()));
        this.tenantToDbConfig = dbConfigs;
        // Initialize tenantToMongoDatabase map.
        buildTenantDbs();
      }
    
      @Override
      public MongoDatabase getDb() {
    
        String tenantId = (!StringUtils.isEmpty(TenantContext.getId()) ? TenantContext.getId()
            : SibConstant.DEFAULT_TENANT);
        return this.tenantToMongoDatabase.get(tenantId);
      }
    
      /**
       * Create tenantToMongoDatabase map.
       */
      @SuppressWarnings("resource")
      private void buildTenantDbs() {
    
        log.debug("Building tenantDB configuration.");
        this.tenantToMongoDatabase = new HashMap<>();
        /*
         * for each tenant fetch dbConfig and intitialize MongoClient and set it to
         * tenantToMongoDatabase
         */
        for (Entry<String, DbConfig> idToDbconfig : this.tenantToDbConfig.entrySet()) {
          try {
            this.tenantToMongoDatabase.put(idToDbconfig.getKey(),
                new MongoClient(new MongoClientURI(idToDbconfig.getValue()
                    .getUri())).getDatabase(idToDbconfig.getValue()
                        .getDatabase()));
          } catch (MongoException e) {
            log.error(e.getMessage(), e.getCause());
          }
        }
      }
    }
    

    在此,tenantToDbConfig 是我在应用程序启动时创建的一个 bean,我在其中针对每个租户存储 DBConfiguration(如(Url/数据库名称))。启动时需要一个默认数据库,并且对于每个请求,我都希望在请求标头中使用tenantId。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      相关资源
      最近更新 更多