Spring Webflux does not respect configuration for database name MongoDB - java

I am trying to implement a reactive application with Spring Webflux and MongoDB.
I have the following configuration in application.properties file:
spring.data.mongodb.database=my-db
spring.data.mongodb.uri=mongodb://user:pass#host:port/my-db
However, when I try save some document to the MongoDB I am getting the following error:
backend_1 | Caused by: com.mongodb.MongoCommandException: Command failed with error 13 (Unauthorized): 'not authorized on test to execute command { insert: "user", ordered: true, $db: "test" }' on server database:27017. The full response is { "ok" : 0.0, "errmsg" : "not authorized on test to execute command { insert: \"user\", ordered: true, $db: \"test\" }", "code" : 13, "codeName" : "Unauthorized" }
backend_1 | at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179) ~[mongodb-driver-core-3.8.2.jar:na]
backend_1 | at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:370) ~[mongodb-driver-core-3.8.2.jar:na]
I simply can not understand why the driver does not respect the configuration for the database name and tries to insert into the database test (and thus fail).
Am I missing something?
One more thing is that I am using the Java backend and MongoDB within a separate containers with docker compose.

I have found a solution for the authentication issue.
It was the authSource that I was missing, so I added it in the database URI and it worked.
spring.data.mongodb.uri=mongodb://user:pass#host:port/my-db?authSource=admin
However I still do not understand why the documents that my Java backend creates are being inserted in test database and not the database that I configured to work with.

Put this in application.properties file:
# MongoDB
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=my-db
spring.data.mongodb.username=username
spring.data.mongodb.password=password

Related

Failed to setup gcp repository using elasticsearch operator

I'm launching 3 elastic nodes using elastic operator and i tried to set up automated snapshots for these instances.
I followed this doc
I minified the json of the service account key and created a file called gcs.client.default.credentials_file with no file extension and added this file to kubernetes secrets.
And added the secureSettings.secretName field to the spec of the elastic cluster and added the secret name to it which was gcs-credentials
But i get this error on the logs
{"#timestamp":"2022-12-26T18:45:40.037Z", "log.level":"ERROR", "message":"fatal exception while booting Elasticsearch", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.elasticsearch.bootstrap.Elasticsearch","elasticsearch.node.name":"elasticsearch-cluster-es-node-1","elasticsearch.cluster.name":"elasticsearch-cluster","error.type":"java.lang.IllegalStateException","error.message":"failed to load plugin class [org.elasticsearch.repositories.gcs.GoogleCloudStoragePlugin]","error.stack_trace":"java.lang.IllegalStateException: failed to load plugin class [org.elasticsearch.repositories.gcs.GoogleCloudStoragePlugin]\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.loadPlugin(PluginsService.java:607)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:482)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:290)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:159)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.lambda$getPluginsServiceCtor$14(PluginsService.java:634)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.node.Node.<init>(Node.java:406)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.node.Node.<init>(Node.java:316)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.bootstrap.Elasticsearch$2.<init>(Elasticsearch.java:214)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.bootstrap.Elasticsearch.initPhase3(Elasticsearch.java:214)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:67)\nCaused by: java.lang.reflect.InvocationTargetException\n\tat java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:79)\n\tat java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)\n\tat java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:484)\n\tat org.elasticsearch.server#8.5.0/org.elasticsearch.plugins.PluginsService.loadPlugin(PluginsService.java:600)\n\t... 9 more\nCaused by: java.lang.IllegalArgumentException: failed to load GCS client credentials from [gcs.client.default.credentials_file]\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.loadCredential(GoogleCloudStorageClientSettings.java:265)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.getClientSettings(GoogleCloudStorageClientSettings.java:221)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.load(GoogleCloudStorageClientSettings.java:209)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStoragePlugin.reload(GoogleCloudStoragePlugin.java:88)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStoragePlugin.<init>(GoogleCloudStoragePlugin.java:36)\n\tat java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)\n\t... 12 more\nCaused by: java.io.IOException: Invalid PKCS#8 data.\n\tat com.google.auth.oauth2.ServiceAccountCredentials.privateKeyFromPkcs8(ServiceAccountCredentials.java:496)\n\tat com.google.auth.oauth2.ServiceAccountCredentials.fromPkcs8(ServiceAccountCredentials.java:474)\n\tat com.google.auth.oauth2.ServiceAccountCredentials.fromJson(ServiceAccountCredentials.java:212)\n\tat com.google.auth.oauth2.ServiceAccountCredentials.fromStream(ServiceAccountCredentials.java:548)\n\tat com.google.auth.oauth2.ServiceAccountCredentials.fromStream(ServiceAccountCredentials.java:520)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.lambda$loadCredential$13(GoogleCloudStorageClientSettings.java:257)\n\tat java.base/java.security.AccessController.doPrivileged(AccessController.java:569)\n\tat org.elasticsearch.repositories.gcs.SocketAccess.doPrivilegedIOException(SocketAccess.java:33)\n\tat org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.loadCredential(GoogleCloudStorageClientSettings.java:256)\n\t... 17 more\n"}
ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/elasticsearch-cluster.log
Try adding the following lines to your configuration (on each Elasticsearch):
elasticsearch01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
...
ulimits:
memlock:
soft: -1
hard: -1
Also check this link on Elasticsearch for more detailed information.

Spring Boot Redisson not able to read clusterServersConfig

Here is the application.yml I am using for my Spring WebFlux project
redis:
redisson:
config: |
clusterServersConfig:
idleConnectionTimeout: 10000
connectTimeout: ${REDISSON_CONNECT_TIMEOUT:20000}
timeout: ${REDISSON_TIMEOUT:3000}
retryAttempts: ${REDISSON_RETRY_ATTEMPTS:3}
retryInterval: ${REDISSON_RETRY_INTERVAL:1500}
subscriptionConnectionPoolSize: ${REDISSON_SUBSCRIPTION_POOL_SIZE:50}
slaveConnectionMinimumIdleSize: ${REDISSON_SLAVE_MIN_IDLE_SIZE:24}
slaveConnectionPoolSize: ${REDISSON_SLAVE_POOL_SIZE:48}
masterConnectionMinimumIdleSize: ${REDISSON_MASTER_MIN_IDLE_SIZE:24}
masterConnectionPoolSize: ${REDISSON_MASTER_POOL_SIZE:48}
nodeAddresses:
- "rediss://${APPS_REDIS:-}:${APPS_REDIS_PORT:6379}"
password: ${APPS_REDIS_SECRET:-}
threads: ${REDISSON_THREADS:16}
nettyThreads: ${REDISSON_NETTY_THREADS:96}
But whenever I am starting the project in my laptop, this error comes up
Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'clusterServersConfig': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
I am not sure why it is saying clusterServersConfig is an unrecognized token. In the official doc also, it is mentioned and here is an example of this.
At first I thought it might be because I am running redis locally in my M1 Mac so redis-clusters aren't generated by default. I even tried to enable clusters in redis.conf and run a redis clusters with 3 nodes using redis-cli but still this happens. I have tried almost everything I could think of or search on the net. Any help appreciated :)

SAP CF XSUAA Service - Error Message: Invalid redirect <redirect_uri>/login/callback did not matched the registered values

Implementing SAP xsuaa service with java and deployed, accessing the application URL facing below issue.
Posting this problem solution as I faced and resolved.
Case 1: If you are using BAS (Business Application Studio) and deploying through mta file,
make sure you have added forwardAuthToken: true for xsuaa service associated application instance.
in the mta file add the below properties.
requires:
- name: my_xsuaa
- name: MY_API
group: destinations
properties:
name: MY_API
url: '~{url}'
forwardAuthToken: true
If it is not working after that then check your xs-security.json file
"oauth2-configuration": {
"token-validity": 604800,
"refresh-token-validity": 2592000,
"redirect-uris":[
"https://*.<your_uri>/login/callback"
]
}
Case 2: If deploying a java application below properties should be set in the menifest.yml file.
env:
SESSION_TIMEOUT: 30
destinations: >
[{
"name":"MY_API",
"url" :"<you_java_application_uri>",
"forwardAuthToken": true
}
]
I had the same problem while doing this sap tutorial (https://developers.sap.com/tutorials/btp-cf-buildpacks-node-create.html) and it was solved by adding the oath2-configuration to the xs-security.json:
"oauth2-configuration": {
"token-validity": 604800,
"refresh-token-validity": 2592000,
"redirect-uris": [
"https://<App-router Url>/**"
]
},

Attempt to switch database target during SASL authentication

I try to setup a Mongo DB in Spring Boot project. I've set an uri in application.yml:
spring:
data:
mongodb:
uri: mongodb://user:pass#localhost:27017/mydbname
But application fails to read data from repository with error:
Attempt to switch database target during SASL authentication.
Line where error occurs (kotlin):
val emails = emailRepository.findAllByStatus(READY_TO_SEND)
where
interface EmailRepository : MongoRepository<Email, String> {
fun findAllByStatus(status: EmailStatus) : Collection<Email>
}
and
data class Email(
#Id
#get:JsonIgnore
var id: String? = null,
#get:NotNull
val from: MailActor,
#get:NotEmpty
val to: Collection<MailActor>,
#get:NotEmpty
val subject: String,
#get:NotEmpty
val htmlText: String,
val attachments: Collection<Attachment> = listOf(),
val cc: Collection<MailActor> = listOf(),
val bcc: Collection<MailActor> = listOf(),
#get:JsonIgnore
val status: EmailStatus = EmailStatus.READY_TO_SEND,
#get:JsonIgnore
val created: LocalDateTime = LocalDateTime.now(),
#get:JsonIgnore
val lastSendAttempt: LocalDateTime? = null,
)
The same error occurs with findAll and save operations on repository (and likely others too)
Stack trace:
Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='user', source='user', password=<hidden>, mechanismProperties=<hidden>}
at com.mongodb.internal.connection.SaslAuthenticator.wrapException(SaslAuthenticator.java:235) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:80) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:241) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.authenticate(InternalStreamConnectionInitializer.java:168) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:63) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:144) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.UsageTrackingInternalConnection.open(UsageTrackingInternalConnection.java:51) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.open(DefaultConnectionPool.java:431) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:115) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:100) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:92) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:119) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.client.internal.ClientSessionBinding$SessionBindingConnectionSource.getConnection(ClientSessionBinding.java:135) ~[mongodb-driver-sync-4.1.1.jar:na]
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:653) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:650) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:582) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:650) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:78) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:178) ~[mongodb-driver-sync-4.1.1.jar:na]
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135) ~[mongodb-driver-sync-4.1.1.jar:na]
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92) ~[mongodb-driver-sync-4.1.1.jar:na]
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2790) ~[spring-data-mongodb-3.1.2.jar:3.1.2]
... 33 common frames omitted
Caused by: com.mongodb.MongoCommandException: Command failed with error 17 (ProtocolError): 'Attempt to switch database target during SASL authentication.' on server localhost:27017. The full response is {"ok": 0.0, "errmsg": "Attempt to switch database target during SASL authentication.", "code": 17, "codeName": "ProtocolError"}
at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:175) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:280) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator.sendSaslContinue(SaslAuthenticator.java:195) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator.access$200(SaslAuthenticator.java:43) ~[mongodb-driver-core-4.1.1.jar:na]
at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:69) ~[mongodb-driver-core-4.1.1.jar:na]
... 55 common frames omitted
I am able to connect to mongo via Intellij Idea client with the same credentials.
I run mongo db with docker-compose
version: '3.1'
services:
mongodb:
image: mongo
container_name: my-service-mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: user
MONGO_INITDB_ROOT_PASSWORD: pass
MONGO_INITDB_DATABASE: mydbname
ports:
- 27017:27017
volumes:
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
where mongo-init.js is
db.createUser(
{
user: "user",
pwd: "pass",
roles: [
{
role: "readWrite",
db: "mydbname"
}
]
}
);
What is going on? The only place in the internet where I found this error message is... mongo source code 8].
Any help appreciated.
spring:
data:
mongodb:
uri: mongodb://admin:admin#127.0.0.1:27017/dbname?authSource=admin
add authSource param
If you:
Have multiple similar accounts (with same credentials), one in "admin" and the other in another database.
Intend to log in with the other account not in the "admin" database.
Have SASL enabled.
Then you may be affected by JAVA-4290, which is caused by speculative authentication only supporting the "admin" database, in mongodb-driver-core versions before 4.3.2. This resulted in the client successfully authenticating with the wrong account (the one in the admin database) via speculative authentication, only for MongoDB to trap the error when the SASL Continue message is sent. It does so with a Protocol Error, as you have observed.
As of Spring Boot 2.5.4, the version of mongodb-driver-core that ships with Spring Boot is only 4.2.3.
It seems that it's a bug in mongo DB version
4.4.3-bionic
I've changed image in docker-compose to
mongo:3
and the error went away. Uh, so many hours....
Adding spring.data.mongodb.authentication-database=admin in your application.properties will set the authentication database to admin. This is equivalent to adding ?authSource=admin in your connection string.
I faced the same issue . I was using the spring-boot-starter-parent 2.4.1 and it worked fine with the latest mongodb docker instance. But I had to connect to Bitnami mongo docker container which uses lower mongo and then the same error occurred. I downgraded the version to 2.3.7.RELEASE and then the expected behavior was obtained without errors.
This reason for the error for me was compatibility issue. Refer Spring data MongoDB Compatibility Matrix for viewing different versions and compatibility.
EDIT
I faced similar error in a different application. With the help of this stackoverflow post, Mongodb could not find user "user#database", I was able to understand the issue and solve it. Basically, you need to specify the authentication database properly. If not, by default the user will be checked in the database provided and not the authentication database. In my case I specified database A and my user was in admin db. So user admin was checked in database A.
This answer may not directly related to this question, but I hope it will help others. If you use uri then #ChanningQiu answer is fine. But if you use property for each param then you can try following way-
spring:
data:
mongodb:
host: localhost
port: 27017
database: db_name
username: db_user_name
password: db_password
authentication-database: admin
So in this case you need to set authentication-database: admin value.
Along with #Lutoslaw answer above: rollback to 4.2.2 works for me too.
I'v gotten the same error - Attempt to switch database target during SASL authentication - on createIndex operation.
It seems as my first operation under ordinary user after successful creation admin one.
It would be cool to know what has been so dramatically changed in the auth mechanism between those versions.

Table doesn't exist when deployed in server hibernate

When i deploy the web app on test server (it works fine on localhost ), this BLO_BlOCKED_MOBILES table at the given line of code.
Query query = this.getSession().createSQLQuery(
strQuery.append(" INSERT INTO BLO_BlOCKED_MOBILES (BLO_CUSTOMER_ID_FK,BLO_MOBILE,BLO_NEWMOBILE,BLO_PASSPORT,BLO_STATUS,BLOCKED_BY,BLOCKED_AT ) "
+"VALUES( "+customer.getId() +", '"+ oldMobile +"','"+newMobile+"','"+customer.getPassportNo()+"','Y','user',CURRENT_TIMESTAMP)" ).toString());
mtmrsLogger.info(query.toString());
int affectedRows = query.executeUpdate();
The db is in mysql and app uses hibernate,struts 1 and spring. I created this new table ,
added this on hibernate.cfg.xml
< mapping class="com.mtmrs.model.branch.BlockedMobile"/>
and created the model file BlockedMobile.java
and when it is used, the below error comes.
WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1146, SQLState: 42S02
ERROR org.hibernate.util.JDBCExceptionReporter - Table 'merchantrade.blo_blocked_mobiles' doesn't exist
Please let me know if the information is insufficient. I don't see what's wrong.
Peraphs the two DB (on your localhost server and on test server) are different. So the test server has not got your table.
According to the error message, either the table blo_blocked_mobiles or the scheme merchantrade does not exist on the MySQL database on the test server.

Categories