EzyMongo: Connect Multi Databases

Nowaday, we usually work with microservice system, so, we will have a requirement to fetch data from many databases. With EzyMongo this task is so simple.

1. Configuration

Let's say we need connect to 2 datasource named author and book for book management system. For first step, we need add to the configuration file like this:
# for application.yaml
author:
  database:
    mongo:
      uri: mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/author
      database: author
      collection:
        naming:
          case: UNDERSCORE
          ignored_suffix: Entity
book:
  database:
    mongo:
      uri: mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/book
      database: book
      collection:
        naming:
          case: UNDERSCORE
          ignored_suffix: Entity
# for application.properties
author.database.mongo.uri=mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/author
author.database.mongo.database=author
author.database.mongo.collection.naming.case=UNDERSCORE
author.database.mongo.collection.naming.ignored_suffix=Entity

book.database.mongo.uri=mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/book
book.database.mongo.database=book
book.database.mongo.collection.naming.case=UNDERSCORE
book.database.mongo.collection.naming.ignored_suffix=Entity
Next step, if you're using in your project's dependencies, you can exclude EzyMongoConfiguration from bean management like this:
import com.tvd12.ezyfox.bean.annotation.EzyExclusiveClassesConfiguration;
import com.tvd12.ezyfox.boot.mongodb.EzyMongoConfiguration;

@EzyExclusiveClassesConfiguration(
    EzyMongoConfiguration.class
)
public class ExampleMongoMultiDatabasesApplication {

    public static void main(String[] args) throws Exception {
        EzyHttpApplicationBootstrap.start(ExampleMongoMultiDatabasesApplication.class);
    }
}
Now, you can create 2 configration classes like this:
import static com.tvd12.properties.file.util.PropertiesUtil.getPropertiesByPrefix;
import static java.util.Collections.singleton;

import java.util.Properties;
import java.util.Set;

import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.boot.mongodb.EzyMongoConfiguration;

@EzyConfigurationBefore
public class AuthorMongoConfiguration extends EzyMongoConfiguration {

    @Override
    public void setPackagesToScan(Set<String> packagesToScan) {
        super.setPackagesToScan(
            singleton("com.tvd12.ezydata.example.mongo.author")
        );
    }

    @Override
    public void setProperties(Properties properties) {
        final Properties clone = new Properties(properties);
        clone.putAll(getPropertiesByPrefix(properties, "author"));
        super.setProperties(clone);
    }
}
package com.tvd12.ezydata.example.mongo.config;

import static com.tvd12.properties.file.util.PropertiesUtil.getPropertiesByPrefix;
import static java.util.Collections.singleton;

import java.util.Properties;
import java.util.Set;

import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.boot.mongodb.EzyMongoConfiguration;

@EzyConfigurationBefore
public class BookMongoConfiguration extends EzyMongoConfiguration {

    @Override
    public void setPackagesToScan(Set<String> packagesToScan) {
        super.setPackagesToScan(
            singleton("com.tvd12.ezydata.example.mongo.book")
        );
    }

    @Override
    public void setProperties(Properties properties) {
        final Properties clone = new Properties(properties);
        clone.putAll(getPropertiesByPrefix(properties, "book"));
        super.setProperties(clone);
    }
}
For entity classes and repository interfaces, you will need to organize them into the respective packages like this:
root-package/

  +--config/
  |  +--AuthorMongoConfiguration.java
  |  +--BookMongoConfiguration.java
  +--author/
  |  +--repository/
  |  |  +--AuthorRepository.java
  |  +--entity/
  |    +--Author.java
  +--book/
  |  +--repository/
  |  |  +--BookRepository.java
  |  |  +--CategoryRepository.java
  |  +--entity/
  |    +--Category.java
  |    +--Book.java

2. Usage

After the configuration, you can use the repositories normally like single data source like this:
@EzySingleton
@AllArgsConstructor
public class BookService {
    private final AuthorRepository authorRepository;
    private final BookRepository bookRepository;

    public BookData addBook(AddBookData data) {
        Book existedBook = bookRepository.findByNameAndAuthorId(
            data.getBookName(),
            data.getAuthorId()
        );
        if (existedBook != null) {
            throw new DuplicatedBookException(
                "author: " + data.getAuthorId() +
                    " has already registered book: " + data.getBookName()
            );
        }
        final Author author = authorRepository.findById(data.getAuthorId());
        if (author == null) {
            throw new InvalidAuthorIdException(
                "author: " + data.getAuthorId() + " not found"
            );
        }
        // other codes
    }
}