mongodbdockerdocker-composedockerfiledocker-network

Spring not able to connect to MongoDB on docker


I have created two docker compose file, one for DBs:

# docker compose -f ./_DockerEndpoints.yaml -p storage up -d
version: '3.8'

services:
  my-postgresql-db:
    image: postgres:latest
    container_name: postgresql-db
    ports:
      - "5432:5432"
    volumes:
      - /Users/Develop/Personal/projects/tools/data/PostgreSQL:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: paulmarcelinbejan
      POSTGRES_PASSWORD: PaulMarcelinBejanPassword
      POSTGRES_DB: MyDB
    networks:
      - storage-network
    healthcheck:
      test: ["CMD", "pg_isready", "-q", "-d", "MyDB", "-U", "paulmarcelinbejan"]
      interval: 10s
      timeout: 5s
      retries: 4
  my-mongo-db:
    image: mongo:latest
    container_name: mongo-db
    ports:
      - "27017:27017"
    volumes:
      - /Users/Develop/Personal/projects/tools/data/MongoDB:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: paulmarcelinbejan
      MONGO_INITDB_ROOT_PASSWORD: PaulMarcelinBejanPassword
    command: --auth
    networks:
      - storage-network
    healthcheck:
      test: ["CMD", "mongo", "--eval", "db.getCollectionNames()"]
      interval: 10s
      timeout: 5s
      retries: 4

networks:
  storage-network:
    driver: bridge

one for web application

# docker compose -f ./HyperBank_APIs.yaml -p hyperbank up -d
version: '3.8'

services:
  hyperbank-config-provider:
    image: hyperbank-config-provider:latest
    container_name: config-provider
    ports:
      - "8888:8888"
    networks:
      - hyperbank-network
      - storage_storage-network
    healthcheck:
      test: "curl --fail --silent http://config-provider:8888/actuator/health | grep UP || exit 1"
      start_period: 20s
      interval: 5s
      timeout: 10s
      retries: 3

  hyperbank-types:
    image: hyperbank-types:latest
    container_name: types
    ports:
      - "9008:9008"
    environment:
      CONFIG_PROVIDER_HOST: config-provider
    networks:
      - hyperbank-network
      - storage_storage-network
    depends_on:
      hyperbank-config-provider:
        condition: service_healthy

networks:
  hyperbank-network:
    driver: bridge
  storage_storage-network:
    external: true

I'm connected with DBeaver to PostreSQL using localhost:5432 and with Studio3T to MongoDB using localhost:27017

while inside spring-boot I'm using the name of containers as host: my-postgresql-db and my-mongo-db

during startup of hyperbank-types, there are no issue of connectivity on both DBs

those are the logs for MongoDB:

2024-04-01 18:41:03 {"timeMillis":1711989663655,"thread":"main","level":"INFO","loggerName":"org.mongodb.driver.client","message":"MongoClient with metadata {\"driver\": {\"name\": \"mongo-java-driver|sync|spring-boot\", \"version\": \"4.9.1\"}, \"os\": {\"type\": \"Linux\", \"name\": \"Linux\", \"architecture\": \"aarch64\", \"version\": \"6.3.13-linuxkit\"}, \"platform\": \"Java/Eclipse Adoptium/21.0.2+13-LTS\"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=MongoCredential{mechanism=null, userName='paulmarcelinbejan', source='HyperBankMongoDB', password=<hidden>, mechanismProperties=<hidden>}, streamFactoryFactory=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@da4cf09, com.mongodb.Jep395RecordCodecProvider@1980a3f]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[my-mongo-db:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='30000 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, sendBufferSize=0}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, sendBufferSize=0}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, contextProvider=null}","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","contextMap":{},"threadId":1,"threadPriority":5,"appName":"spring.application.name","version":"spring.application.version"}
2024-04-01 18:41:03 {"timeMillis":1711989663667,"thread":"cluster-ClusterId{value='660ae39ffcaa200ce45daab3', description='null'}-my-mongo-db:27017","level":"INFO","loggerName":"org.mongodb.driver.cluster","message":"Monitor thread successfully connected to server with description ServerDescription{address=my-mongo-db:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=21, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=20379000}","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","contextMap":{},"threadId":37,"threadPriority":5,"appName":"spring.application.name","version":"spring.application.version"}

When I execute an api on hyperbank-types, it correctyle execute a query on PostgreSQL:

2024-04-01 18:47:24 Hibernate: 
2024-04-01 18:47:24     select
2024-04-01 18:47:24         s1_0.id_account_type,
2024-04-01 18:47:24         s1_0.code,
2024-04-01 18:47:24         s1_0.description 
2024-04-01 18:47:24     from
2024-04-01 18:47:24         account_type s1_0 
2024-04-01 18:47:24     where
2024-04-01 18:47:24         s1_0.id_account_type=?

but when is trying to insert a document on MongoDB is going in error:

2024-04-01 18:47:24 {"timeMillis":1711990044245,"thread":"http-nio-9008-exec-1","level":"WARN","loggerName":"org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver","message":"Failure in @ExceptionHandler com.hyperbank.architecture.web.controller.HyperBankExceptionRestController#handleFunctionalException(FunctionalException)","thrown":{"commonElementCount":0,"localizedMessage":"Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='paulmarcelinbejan', source='HyperBankMongoDB', password=<hidden>, mechanismProperties=<hidden>}","message":"Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='paulmarcelinbejan', source='HyperBankMongoDB', password=<hidden>, mechanismProperties=<hidden>}","name":"org.springframework.data.mongodb.UncategorizedMongoDbException","cause":{"commonElementCount":84,"localizedMessage":"Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='paulmarcelinbejan', source='HyperBankMongoDB', password=<hidden>, mechanismProperties=<hidden>}","message":"Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='paulmarcelinbejan', source='HyperBankMongoDB', password=<hidden>, mechanismProperties=<hidden>}","name":"com.mongodb.MongoSecurityException","cause":{"commonElementCount":84,"localizedMessage":"Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server my-mongo-db:27017. The full response is {\"ok\": 0.0, \"errmsg\": \"Authentication failed.\", \"code\": 18, \"codeName\": \"AuthenticationFailed\"}","message":"Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server my-mongo-db:27017. The full response is {\"ok\": 0.0, \"errmsg\": \"Authentication failed.\", \"code\": 18, \"codeName\": \"AuthenticationFailed\"}","name":"com.mongodb.MongoCommandException","extendedStackTrace":"com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server my-mongo-db:27017. The full response is {\"ok\": 0.0, \"errmsg\": \"Authentication failed.\", \"code\": 18, \"codeName\": \"AuthenticationFailed\"}\n\tat com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:205) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:443) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:365) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:102) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:49) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:224) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.SaslAuthenticator.getNextSaslResponse(SaslAuthenticator.java:131) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.SaslAuthenticator.lambda$authenticate$0(SaslAuthenticator.java:63) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:277) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:59) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:57) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.InternalStreamConnectionInitializer.authenticate(InternalStreamConnectionInitializer.java:205) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.InternalStreamConnectionInitializer.finishHandshake(InternalStreamConnectionInitializer.java:85) ~[mongodb-driver-core-4.9.1.jar!/:?]\n\tat com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:209) ~[mongodb-driver-core-4.9.1.jar!/:?]"},"endOfBatch":false,"loggerFqcn":"org.apache.commons.logging.LogAdapter$Log4jLog","contextMap":{},"threadId":41,"threadPriority":5,"appName":"spring.application.name","version":"spring.application.version"}}}

Solution

  • the issue was related to authentication-mechanism, was using SCRAM-SHA-1, so I have replaced:

    spring:  
       data:
          mongodb:
             host: ${endpoints.nosql.HyperBankMongoDB.host}
             port: ${endpoints.nosql.HyperBankMongoDB.port}
             database: ${endpoints.nosql.HyperBankMongoDB.name}
             username: ${endpoints.nosql.HyperBankMongoDB.username}
             password: ${endpoints.nosql.HyperBankMongoDB.password}
             authentication-database: ${endpoints.nosql.HyperBankMongoDB.authentication-database}
    

    with:

    spring:
       data:
          mongodb:
             uri: mongodb://${endpoints.nosql.HyperBankMongoDB.username}:${endpoints.nosql.HyperBankMongoDB.password}@${endpoints.nosql.HyperBankMongoDB.host}:${endpoints.nosql.HyperBankMongoDB.port}/${endpoints.nosql.HyperBankMongoDB.name}?authSource=${endpoints.nosql.HyperBankMongoDB.authentication-database}&authMechanism=${endpoints.nosql.HyperBankMongoDB.authentication-mechanism}
    

    in order to add authMechanism SCRAM-SHA-256