Grails - Heroku not using the database defined in DataSource.groovy - postgresql

I have just deployed my Grails app on to Heroku by following docs.. https://devcenter.heroku.com/articles/getting-started-with-grails#prerequisites
Before deploying I created a Dev Database and inserted the URL details into the production section of DataSource.groovy
production {
dataSource {
dbCreate = "update"
//url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
//url = "jdbc:postgresql://localhost:5432/myapp"
uri = new URI(System.env.DATABASE_URL?:"postgres://myuser:mypassword#someAWSmachine:5432/myapp")
url = "jdbc:postgresql://" + uri.host + ":" + uri.port + uri.path
username = uri.userInfo.split(":")[0]
password = uri.userInfo.split(":")[1]
however when I deloy out my application, it created another dev database and set this URL information of this new database into the settings under
Settings -> Config Variables -> DATABASE_URL
somehow my app runs and is using this newly created database and it's settings, my question is HOW? Why would my app not be failing to run, that fact I have a different database URL configured in my DataSource.groovy?

Woops... I didn't quite digest this line the first time I read it
uri = new URI(System.env.DATABASE_URL?:"postgres://myuser:mypassword#someAWSmachine:5432/myapp")
Note the System.env.DATABASE_URL? ternary operator.
I'll leave this question here for others

Related

Terraform issue in deleting server parameter Postgresql flexi server

Getting error:waiting for deletion of Flexible Server Configuration (pgbouncer.enabled)
Once I change the configuration from portal the script works.
azurerm_postgresql_flexible_server_configuration" "pgbouncer"
{ name = "pgbouncer.enabled"
value = var.pgbouncer
server_id = azurerm_postgresql_flexible_server.pgsql.id
}

Connect to MongoDB atlas cluster with flask-mongoengine

I am trying to connect with mongodb atlas from my flask app using flask-mongoengine.
DB_URI = "mongodb+srv://flask_app_user:flask_app_user#cluster0.6jwadcx5g.mongodb.net/flask_app?retryWrites=true&w=majority"
def create_app():
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', 'replace_me_32437264278642')
app.config['MONGODB_SETTINGS'] = {
'host': os.environ.get('MONGODB_URI', DB_URI)
}
MongoEngine(app)
socketio.init_app(app)
SSLify(app)
return app
But I am getting an error,
pymongo.errors.InvalidURI: Invalid URI scheme: URI must begin with 'mongodb://'
How can I use mongo atlas with flask_mongoengine?
I don't want to stick with flask_mongoengine. I don't want to change that.
It worked correctly for me with the latest version flask_mongoengine-1.0.0 and pymongo-3.11.2
It seems you're using the host from MONGODB_URI env var...
What do you have in MONGODB_URI??
Could you share also which version are you using?

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

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

Correct mongo database is not picked up from the connection parameter, instead have to map it manually

I am having an issue where I need to manually map the correct database to the domain instead of it being picked up from the connection argument.
I am using grails 3.2.8, plugin "org.grails.plugins:mongodb:6.1.0". I have both hibernate and mongodb plugin enabled.
I have define my connection URL as
//application.yml
mongodb:
url: 'mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}#${MONGODB_REPLICA_SET}/${MONGODB_DATABASE}?${MONGODB_CONNECTION_OPTIONS}'
My domain object is defined as :
class ReportData {
String id
Long someField
static mapWith = "mongo"
static mapping = {
//database "db-name" DOESN'T WORK WHEN COMMENTING OUT THIS LINE
}
}
Shouldn't the database(system property MONGODB_DATABASE) be picked up auto-magically from the connection url? I am not sure if this is a bug or I am missing some configuration aspect.
I realized that I had not added following in my build.gradle file:
bootRun {
systemProperties = System.properties
}
so my application environment settings were not even getting applied correctly and hence my connection url was invalid.
I found that detail here: http://docs.grails.org/latest/guide/conf.html

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.