All Projects → silaev → mongodb-replica-set

silaev / mongodb-replica-set

Licence: other
Run MongoDB Atlas locally for testing

Programming Languages

java
68154 projects - #9 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to mongodb-replica-set

Web3 By Example
Node.js with Web3 javascript examples for getting basic information (transactions, balances, network stats, and tokens) from the Ethereum blockchain.
Stars: ✭ 156 (+271.43%)
Mutual labels:  transaction
Multisender
Token Multisender Dapp smart contract. Airdrop tokens. Batch sending ERC20, ETH, Ethereum tokens. Send thousands of transfers in a few transactions. It can help user to save more tx fee and time than sending one by one
Stars: ✭ 185 (+340.48%)
Mutual labels:  transaction
Btcpy
A Python3 SegWit-compliant library which provides tools to handle Bitcoin data structures in a simple fashion.
Stars: ✭ 225 (+435.71%)
Mutual labels:  transaction
Smart Contract Watch
A tool to monitor a number of smart contracts and transactions
Stars: ✭ 168 (+300%)
Mutual labels:  transaction
Go Saga
Implements saga-pattern in Go, another way to distribute transaction.
Stars: ✭ 183 (+335.71%)
Mutual labels:  transaction
Easytransaction
A distribute transaction solution(分布式事务) unified the usage of TCC , SAGA ,FMT (seata/fescar AutoCompensation), reliable message, compensate and so on;
Stars: ✭ 2,284 (+5338.1%)
Mutual labels:  transaction
Raincat
强一致分布式事务框架
Stars: ✭ 1,785 (+4150%)
Mutual labels:  transaction
Specification
OpenMessaging Specification
Stars: ✭ 242 (+476.19%)
Mutual labels:  transaction
Reliable
mq transaction, tcc, eventually consistency. tx life cycle: all listeners handled, if necessary, produce next message
Stars: ✭ 187 (+345.24%)
Mutual labels:  transaction
Anima
Minimal database operation library.
Stars: ✭ 210 (+400%)
Mutual labels:  transaction
Ethereum Graph Debugger
Ethereum solidity graph plain debugger. To have the whole picture when debugging.
Stars: ✭ 177 (+321.43%)
Mutual labels:  transaction
Blockvotes
An e-voting system based on blockchain using ring signature
Stars: ✭ 182 (+333.33%)
Mutual labels:  transaction
Blockchain Wallet
区块链钱包技术指南
Stars: ✭ 205 (+388.1%)
Mutual labels:  transaction
Stove
Domain Driven Design oriented application framework, meets CRUD needs
Stars: ✭ 160 (+280.95%)
Mutual labels:  transaction
Plasmaethexchange
Plasma protocol compatible ETH Exchange Platform
Stars: ✭ 235 (+459.52%)
Mutual labels:  transaction
Jstarcraft Core
目标是提供一个通用的Java核心编程框架,作为搭建其它框架或者项目的基础. 让相关领域的研发人员能够专注高层设计而不用关注底层实现. 涵盖了缓存,存储,编解码,资源,脚本,监控,通讯,事件,事务9个方面.
Stars: ✭ 150 (+257.14%)
Mutual labels:  transaction
Learning Blockchain
Tidy up Blockchain ecosystem and tutorial
Stars: ✭ 188 (+347.62%)
Mutual labels:  transaction
Typeorm Transactional Cls Hooked
A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS
Stars: ✭ 251 (+497.62%)
Mutual labels:  transaction
Sequelize Docs Zh Cn
Sequelize 文档的中文版本: v4.42.0 | v5.21.5 | v6.6.5
Stars: ✭ 2,745 (+6435.71%)
Mutual labels:  transaction
Dntframeworkcore
Lightweight and Extensible Infrastructure for Building Web Applications - Web Application Framework
Stars: ✭ 208 (+395.24%)
Mutual labels:  transaction

Run MongoDB Atlas locally for testing

build codecov

Prerequisite

  • Java 8+

  • Docker

  • Chart shows local and remote docker support for replicaSetNumber

    replicaSetNumber local docker host local docker host running tests from inside a container with mapping the Docker socket remote docker daemon availability of an arbiter node
    1 + + + -
    from 2 to 7 (including) only if adding either host.docker.internal (your Docker version should support it) or dockerhost to the OS host file. See Supported features for details + + +

Tip: A single node replica set is the fastest among others. That is the default mode for MongoDbReplicaSet. However, to use only it, consider the Testcontainers MongoDB module on GitHub

Getting it

  • Gradle:
dependencies {
    testCompile("com.github.silaev:mongodb-replica-set:${LATEST_RELEASE}")
}
  • Maven:
<dependencies>
    <dependency>
        <groupId>com.github.silaev</groupId>
        <artifactId>mongodb-replica-set</artifactId>
        <version>${LATEST_RELEASE}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Replace ${LATEST_RELEASE} with the Latest Version Number If you cannot find a release on Maven, please, use Jitpack

Run on Apple silicon

Use digests for linux/arm64/v8 and Docker Desktop for Apple silicon supporting host.docker.internal (should be in the OS host file). Examples: 1.

MongoDbReplicaSet.builder()
    .mongoDockerImageName("mongo@sha256:8a823923d80e819e21ee6c179eabf42460b6b7d8ac3dd5f35b59419ae5413640")
    .useHostDockerInternal(true)
    .build()`

2 ./gradlew clean build -DmongoReplicaSetProperties.mongoDockerImageName=mongo@sha256:8a823923d80e819e21ee6c179eabf42460b6b7d8ac3dd5f35b59419ae5413640 -DmongoReplicaSetProperties.useHostDockerInternal=true

MongoDB versions that MongoDbReplicaSet is constantly tested against

version transaction support
3.6.14 -
4.0.12 +
4.2.8 +
4.4.4 +
5.0.5 +

Examples

Click to see a single node example
class ITTest {
    @Test
    void testDefaultSingleNode() {
        try (
            //create a single node mongoDbReplicaSet and auto-close it afterwards
            final MongoDbReplicaSet mongoDbReplicaSet = MongoDbReplicaSet.builder()
                .mongoDockerImageName("mongo:4.4.4")
                .build()
        ) {
            //start it
            mongoDbReplicaSet.start();
            assertThat(
                mongoDbReplicaSet.nodeStates(mongoDbReplicaSet.getMongoRsStatus().getMembers()),
                hasItem(ReplicaSetMemberState.PRIMARY)
            );
            assertNotNull(mongoDbReplicaSet.getReplicaSetUrl());
        }
    }
}
Click to see a fault tolerance example
class ITTest {
    @Test
    void testFaultTolerance() {
        try (
            //create a PSA mongoDbReplicaSet and auto-close it afterwards
            final MongoDbReplicaSet mongoDbReplicaSet = MongoDbReplicaSet.builder()
                //with the latest mongo:4.4.4 docker image
                .mongoDockerImageName("mongo:4.4.4")
                //If true then use host.docker.internal of Docker, 
                //otherwise take dockerhost of Qoomon docker-host.
                //Make sure that your OS host file includes one of them.
                //All new Docker versions support the first variant.
                .useHostDockerInternal(true)
                //with 2 working nodes
                .replicaSetNumber(2)
                //with an arbiter node
                .addArbiter(true)
                //create a proxy for each node to simulate network partitioning
                .addToxiproxy(true)
                .build()
        ) {
            //start it
            mongoDbReplicaSet.start();
            assertNotNull(mongoDbReplicaSet.getReplicaSetUrl());

            //get a primary node
            final MongoNode masterNode = mongoDbReplicaSet.getMasterMongoNode(
                mongoDbReplicaSet.getMongoRsStatus().getMembers()
            );

            //cut off the primary node from network
            mongoDbReplicaSet.disconnectNodeFromNetwork(masterNode);
            //wait until a new primary is elected that is different from the masterNode
            mongoDbReplicaSet.waitForMasterReelection(masterNode);
            assertThat(
                mongoDbReplicaSet.nodeStates(mongoDbReplicaSet.getMongoRsStatus().getMembers()),
                hasItems(
                    ReplicaSetMemberState.PRIMARY,
                    ReplicaSetMemberState.ARBITER
                )
            );

            //bring back the disconnected masterNode
            mongoDbReplicaSet.connectNodeToNetwork(masterNode);
            //wait until all nodes are up and running
            mongoDbReplicaSet.waitForAllMongoNodesUp();
            assertThat(
                mongoDbReplicaSet.nodeStates(mongoDbReplicaSet.getMongoRsStatus().getMembers()),
                hasItems(
                    ReplicaSetMemberState.PRIMARY,
                    ReplicaSetMemberState.ARBITER,
                    ReplicaSetMemberState.SECONDARY
                )
            );
        }
    }
}

Motivation

  • Cross-platform solution that doesn't depend on fixed ports;
  • Testing MongoDB transactions to run against an environment close to a production one;
  • Testing production issues by recreating a real MongoDB replica set (currently without shards);
  • Education to newcomers to the MongoDB world (learning the behaviour of a distributed NoSQL database while dealing with network partitioning, analyze the election process and so on).

General info

Click to see how to create a 3 node replica set on fixed ports via Docker manually

MongoDB starting from version 4 supports multi-document transactions only on a replica set. For example, to initialize a 3 node replica set on fixed ports via Docker, one has to do the following:

  1. Add 127.0.0.1 mongo1 mongo2 mongo3 to the host file of an operation system;
  2. Run in terminal:
    • docker network create mongo-cluster
    • docker run --name mongo1 -d --net mongo-cluster -p 50001:50001 mongo:4.0.10 mongod --replSet docker-rs --port 50001
    • docker run --name mongo2 -d --net mongo-cluster -p 50002:50002 mongo:4.0.10 mongod --replSet docker-rs --port 50002
    • docker run --name mongo3 -d --net mongo-cluster -p 50003:50003 mongo:4.0.10 mongod --replSet docker-rs --port 50003
  3. Prepare the following unix end of lines script (optionally put it folder scripts or use rs.add on each node):
    rs.initiate({
        "_id": "docker-rs",
        "members": [
            {"_id": 0, "host": "mongo1:50001"},
            {"_id": 1, "host": "mongo2:50002"},
            {"_id": 2, "host": "mongo3:50003"}
        ]
    });
  4. Run in terminal:
    • docker cp scripts/ mongo1:/scripts/
    • docker exec -it mongo1 /bin/sh -c "mongo --port 50001 < /scripts/init.js"

As we can see, there is a lot of operations to execute and we even didn't touch a non-fixed port approach. That's where the MongoDbReplicaSet might come in handy.

Supported features

Feature Description default value how to set
replicaSetNumber The number of voting nodes in a replica set including a master one 1 MongoDbReplicaSet.builder()
awaitNodeInitAttempts The number of approximate seconds to wait for a master or an arbiter node(if addArbiter=true) 29 starting from 0 MongoDBReplicaSet.builder()
propertyFileName yml file located on the classpath none MongoDbReplicaSet.builder()
mongoDockerImageName a MongoDB docker file name mongo:4.0.10 finds first set:
1) MongoDbReplicaSet.builder()
2) the system property mongoReplicaSetProperties.mongoDockerImageName
3) propertyFile
4) default value
addArbiter whether or not to add an arbiter node to a cluster false MongoDbReplicaSet.builder()
slaveDelayTimeout whether or not to create one master and the others as delayed members false MongoDbReplicaSet.builder()
useHostDockerInternal If true then use host.docker.internal of Docker, otherwise take dockerhost of Qoomon docker-host false finds first set:
1) MongoDbReplicaSet.builder()
2) the system property mongoReplicaSetProperties.useHostDockerInternal
3) default value
addToxiproxy whether or not to create a proxy for each MongoDB node via Toxiproxy false MongoDbReplicaSet.builder()
enabled whether or not MongoReplicaSet is enabled even if instantiated in a test true finds first set:
1) the system property mongoReplicaSetProperties.enabled
2) propertyFile
3) default value
commandLineOptions command line options, example:Arrays.asList("--oplogSize", "50") emptyList MongoDbReplicaSet.builder()

a propertyFile.yml example:

mongoReplicaSetProperties:
  enabled: false
  mongoDockerImageName: mongo:4.1.13

License

Apache License, Version 2.0

Additional links

Copyright

Copyright (c) 2022 Konstantin Silaev [email protected]

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].