VOMongoRepository fails to connect to MongoDB replicaset with user credentials (Pharo/Voyage) - mongodb

I am trying to save a root Object (MyDocument) into a mongoDB with authentication enabled and a ReplicaSet consisting of 3 Nodes (as inserted into mongoUrls)
With this call:
(VOMongoRepository
mongoUrls: {'127.0.0.1:27017' . '127.0.0.1:27018' . '127.0.0.1:27019'}
database: 'myDB'
username: 'myUser'
password: 'myPass') enableReplication
I receive a VOMongoConnectionError without any deeper information.
Trying the same with this:
VOMongoRepository
mongoUrls: {'myUser:myPass#127.0.0.1:27017/?replicaSet=myRepl' }
database: 'myDB'
I then receive a VOMongoError "not authorized for Query on myDB.MyDocument"
The credentials are double checked with mongo client and Compass, also the read/write permissions (actually the role is dbOwner).
Interestingly my testDocumentLifeCycle is able to create the object and to send a message to save, that returns without signaling an error, although it does not create the document in MongoDB. But the selectOne: is then returning the VOMongoError:
| doc |
MyDocument new
identity: 'me#there.com';
save.
user := MyDocument selectOne: [ :each | each identity = 'me#there.com'].
Just to mention: the above test for MyDocument class did work with a standalone mongod without authentication enabled. The only thing changed is the repository.
So what am I doing wrong?

Actually there is a bug in the replicaSet part of VoyageMongo. It is not using the credentials provided. It has been posted at https://github.com/pharo-nosql/voyage/issues/104

Related

Error in connection to mongodb atlas from siddhi

I am new to Siddhi, and I am trying to connect to MongoDB Atlas to make an insertion to the database of a collection, but when I configure the parameters and run the code in siddhi editor, it seems that there is no error in the console but it does not add the record to MongoDB.
Here is the code:
#App:name("ConectionMongoDBAtlas")
#App:description("Description of conection to MongoDB Atlas")
#sink(type='mongodb',
-- mongodb.uri='mongodb://username:password#ac-qe2xpea-shard-00-00.cs3wyqb.mongodb.net:27017,ac-qe2xpea-shard-00-01.cs3wyqb.mongodb.net:27017,ac-qe2xpea-shard-00-02.cs3wyqb.mongodb.net:27017/siddhi?ssl=true&replicaSet=atlas-4drk5v-shard-0&authSource=admin&retryWrites=true&w=majority',
uri='mongodb+srv://username:password#cluster0.cs3wyqb.mongodb.net/siddhi?retryWrites=true&w=majority',
collection.name = 'siddhiCollection',
database.name = 'siddhi'
-- secure.connection = 'true',
-- trust.store = 'C:/Users/luis.ortega/Downloads/siddhi-tooling-5.1.0/resources/security/client-truststore.jks',
-- key.store.password = 'mongodb',
-- sslEnabled = 'true',
-- trustStore = 'C:/Users/luis.ortega/Downloads/siddhi-tooling-5.1.0/resources/security/cloud.mongodb2',
-- keyStorePassword = 'mongodb',
-- #map(type='json')
-- #payload('{"name":"{{name}}", "age":{{age}}}')
)
#primaryKey("name")
#index('age')
define table siddhiCollection(name string, age int);
#sink(type = 'log')
define stream BarStream(message string);
#info(name= 'query1')
define stream InsertStream (name string, age int);
from InsertStream
insert into MongoCollection;
I tried to configure mongodb with the store annotation as it is in the documentation and also with the sink annotation.
We don't know if the database SSL certificate issue is a problem, I even added the certificate to the client-trutstore.jks.
I have tried the connection to the MongoDB (but not for the Atlas) with the following steps and it was successful.
Copy the mongo driver[1] to the /lib directory.
Create a database as 'test' and add the user admin to the database.
db.createUser({user: "admin", pwd: "admin", roles : [{role: "readWrite", db: "test"}]});
Then simulate the siddhi application using tooling UI after deploying the siddhi application[2].
[1] https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver/3.4.2
[2]
#App:name("store-mongodb")
#Store(type="mongodb",mongodb.uri='mongodb://admin:admin#localhost:27017/test') #PrimaryKey("name") #Index("amount:1", "{background:true}") define table SweetProductionTable (name string, amount double);
/* Inserting event into the mongo store */ #info(name='query1') from insertSweetProductionStream insert into SweetProductionTable;
If there are connection issues to the database, there should be error logs in the carbon log file of the tooling. You can check the log file, 'carbon.log' from the location /wso2/server/logs. This is needed to be checked only if you have observed the logs in the console of the browser.

Mongoose keeps trying to authenticate with wrong admin db even though it is specified

The initial connection to the database seems to authenticate fine with this:
mongoose.connect('mongodb://user:pass#localhost/traderdb/?authSource=admin', {
auth: {
authdb: "admin"
}
}, function(e) {
//other things
});
After that however, when I try to create a new session and authenticate the user everything crashes and in the mongo logs I can see that the application tried to authenticate with mongodb using the traderdb database and not the admin database, even though I have authSource set correctly and it connects fine the first time with the same URI.
This is where I initialize the session store. This is placed inside the callback of the mongoose.connect call.
app.use(session({
secret: 'secrettexthere',
saveUninitialized: true,
resave: true,
store: new MongoStore({
url: 'mongodb://user:pass#localhost/traderdb/?authSource=admin',
db: 'traderdb',
collection: 'sessions',
auto_reconnect: true
})
}));
Nothing fails on application startup, and the mongo logs confirm that a connection was successfully made and authenticated with the admin database. After that however, when I try to actually use the session store the application crashes with the error Error: Error setting TTL index on collection : sessions. And in the mongo server logs I can see that my application tried connecting and authenticating with traderdb instead of admin as the authentication source.

How can I write a query to connect mongodb?

I have installed mongodb in different server. I have modified my old code
db: 'mongodb://localhost/dev',
to new code
my username : proUseAdd
password : mongodb#23
ip : 169.213.64.127
I modified like this
db: 'mongodb://proUseAdd:mongodb#23#169.213.64.127:27017/dav',
I am getting this error
Could not connect to MongoDB!
Error: failed to connect to
[23#169.213.64.127:27017]
UPDATE
i have tried changed my password:mongodb23
query strin:
db: 'mongodb://proUseAdd:mongodb23#169.213.64.127:27017/dav',
still i'm getting error
Could not connect to MongoDB!
Error: failed to connect to
[169.213.64.127:27017]
Change your password to something which doesn't contain #.
While parsing your connection string, MongoDB driver looks for the # character to separate your credentials and the host name. Since your password has an # in it, it recognizes your credentials as proUseAdd:mongodb and your host name as 23#169.213.64.127:27017.

Can't authenticate with mongoenine to mongodb replicas

1) Before even setting replica sets in mongo i created admin user, with "readWriteAnyDatabase", "userAdminAnyDatabase", "dbAdminAnyDatabase", "clusterAdmin" roles.
2) Then i set my /etc/mongodb.conf configurations on all 3 servers.
dbpath=/var/lib/mongodb
logpath=/var/log/mongodb/mongodb.log
logappend=true
port = 27017
auth = true
replSet = test4
3) Initiated replicas, but got error
(Do not remember exactly what the error was, but something related to that one of the server was not up. So i figured that it just can't authenticate)
config = {"_id" : "test4", "version" : 1, "members" : [{"_id" : 0,"host" : "xxx.xxx.xxx.xxx:27017"}, {"_id" : 1,"host" : "xxx.xxx.xxx.xxx:27017"}, {"_id":2,"host" : "xxx.xxx.xxx.xxx:27017"}]}
rs.initiate(config)
4) To solve the error, i generated keyFile and added keyFile authentication to my mongodb.conf file.
dbpath=/var/lib/mongodb
keyFile = /etc/keyFile
logpath=/var/log/mongodb/mongodb.log
logappend=true
port = 27017
auth = true
replSet = test4
And everything worked like a charm. Database copied itself over replicas. Admin user worked as expected too.
5) Then i created user with all needed permissions for other database i have, lets call it 'testdb' and user: notadmin, pass: notadmin.
But there is one strange thing i noticed. When i enter mongo in console i do not see replicas, until i log in admin database as an admin like this:
use admin
db.auth('admin', 'admin')
Then my console changes to test4:PRIMARY> or test4:SECONDARY> and i can perform actions with replicas. Guess it should be like this.
And everything works fine, if i insert data through pymongo library. Permissions work, admin user can insert into any database, given permissions, and notadmin user can insert into testdb.
But if i try to make the same thing with mongoengine models,
mongodsn = 'mongodb://notadmin:notadmin#xxx.xxx.xxx.xxx:27017,xx.x.xx.xxx:27017,xxx.xxx.xxx.xx:27017/'
db_instance = mongoengine.connect('testdb', host=mongodsn, replicaSet='test4', readPreference='secondaryPreferred')
rt = ReconnectTest()
rt.content = 'item#{0:d}'.format(x)
rt.save()
i get authentication error:
mongoengine.errors.OperationError: Could not save document (command
SON([('authenticate', 1), ('user', u'notadmin'), ('nonce',
u'9ae2f85cd41f6c74'), ('key', u'8f814aa2434s4t2e0ff9bae03762e')])
failed: auth fails)
The only thing it permits me is from admin user to write to admin database. So something like this works:
mongodsn = 'mongodb://admin:admin#xxx.xxx.xxx.xxx:27017,xx.x.xx.xxx:27017,xxx.xxx.xxx.xx:27017/'
db_instance = mongoengine.connect('admin', host=mongodsn, replicaSet='test4', readPreference='secondaryPreferred')
rt = ReconnectTest()
rt.content = 'item#{0:d}'.format(x)
rt.save()
I am so confused, because mongoengine is just wrapper around pymongo. So how come i can do actions with pymongo, and can't do the same with mongoenige. How do i authenticate with mongoengine to testdb ?
You need to create a user under the "testdb" database, as follows:
$ mongo admin -u <username> -p <password>
> use testdb
> db.addUser({user: <username>, pwd: <password>, roles: [<permissions>]})
Then trying to connect through mongoengine using the newly created user.
Also, add the database in the connection string, as such:
'mongodb://notadmin:notadmin#xxx.xxx.xxx.xxx:27017/testdb'

Grails+Mongodb = do not persist object. Why?

I have first expirence in grails+mongodb. And I have a problem on saving object. First I connected local mongo db in such way to grails:
grails {
mongo {
host = "localhost"
//port = 27107
//username = "login"
//password="pwd"
databaseName = "db"
}
}
I don't know why, but if I specify port and login+password (I create such user with such password), grails give me an error, that cann't connect to mongodb. This is a log of mongodb on daemon start:
22:47:04 [initandlisten] MongoDB starting : pid=918 port=27017 dbpath=/var/lib/mongodb 64-bit host=ubnt-VirtualBox
Ok, with out port and login+pass it works. Next I create domain:
class Cover {
String name
String url
static constraints = {
name(blank: false)
url(blank: false)
}
static mapping = {
collection "cover"
database "covers"
}
}
I try to save it:
Cover cover = new Cover()
cover.name = title.text()
cover.url = url
println("Try to save object: ${cover.toString()}")
cover.save()
println("After save object: ${cover.toString()}")
What I have in output:
Try to save object: com.mydomain.Cover : (unsaved)
After save object: com.mydomain.Cover : 23
When I run shell with command 'mongo', then try to:
>use covers
>db.cover.find()
I see that there is nothing in collection. But when I look at db.cover.next_id.find() I see 23. So it seems like id increments. I can't figure out why object didn't save to mongodb. Why? Before I try to connect to mongodb and save via java driver and saving works (so mongodb seems to install correctly).
Also when I run shell I see such info >connecting to: test what means test? Where I could configure it before? May be shell connects to one db and grails to another?
For me it seems it's saving without problems unless you've some constraint errors...
Have you tried to print the errors after saving/validating?
println cover.errors
Also you could try to recover all the instances from the application without looking in mongo with
println Cover.list()
If with this last line you can see your saved instances, maybe grails is mixing the databases as you have in databaseName=db and you later say that Cover should be saved to covers database
I have found an error, it discovers for me that source in src/groovy have to access to grails sources in specific way, so to save cover I need to create service in grails, where I cna implemet save method, and they in place where I want to call save I should get service in such way
def ctx = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
CoverService coverService = ctx.coverService
And now it works.