Open DerVerruckteFuchs opened 7 years ago
Have you tried changing dataSource
here https://github.com/dularion/streama/blob/master/grails-app/conf/application.yml#L15
I did, and I even made sure to install libpostgresql-jdbc-java
on Debian to make sure the library was available. I kept getting errors that basically amounted to org.postgresql.Driver not found/available.
In my /data/streama/application.yml I had this:
environments:
production:
dataSource:
driverClassName: 'org.postgresql.Driver'
url: jdbc:postgresql://localhost:5432/streama_db
username: streama
password: <streama postgres db user password>
Some errors I'm getting:
ERROR org.apache.tomcat.jdbc.pool.ConnectionPool - Unable to create initial connections of pool.
java.sql.SQLException: Unable to load class: org.postgresql.Driver from ClassLoader:org.springframework.boot.loader.LaunchedURLClassLoader@681a9515;ClassLoader:org.springframework.boot.loader.LaunchedURLClassLoader@681a9515
Caused by: java.lang.ClassNotFoundException: Unable to load class: org.postgresql.Driver from ClassLoader:org.springframework.boot.loader.LaunchedURLClassLoader@681a9515;ClassLoader:org.springframework.boot.loader.LaunchedURLClassLoader@681a9515
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver
@DerVerruckteFuchs
in build.gradle add:
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.1'
next application.yml
dbCreate: update url: jdbc:postgresql://$POSTGRES_HOST:$POSTGRESS_PORT/$DATABASE_NAME pooled: true jmxExport: true driverClassName: org.postgresql.Driver dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect username: sa password:
I'm getting an Unable to resolve name [net.kaleidos.hibernate.PostgresqlExtensionsDialect] as strategy [org.hibernate.dialect.Dialect]
error now. I think a dependency might be missing.
@DerVerruckteFuchs
aaaaa sory:
compile group: 'org.postgresql', name: 'postgresql', version: '42.1.1' compile 'org.grails.plugins:postgresql-extensions:5.0.0'
I'm now getting a java.lang.NoClassDefFoundError: org/hibernate/dialect/PostgreSQL94Dialect
error.
So I tried using dialect: org.hibernate.dialect.PostgreSQLDialect
in my application.yml
, and it seems to work. However, I'm getting ERROR org.hibernate.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: create table user
, which seems to be caused by the fact user
is a reserved word for postgresql:
https://stackoverflow.com/questions/22256124/cannot-create-a-database-table-named-user-in-postgresql
According to the link, changing all references to the user
table to "user"
will work, but it's bad practice. Perhaps something like username
could be used instead.
Maybe this is what you are looking for. You need to change User class, add mapping properties and then compile the code. I don't know if it's possible to define mapping from application.yml
Turns out there was an unaccepted pull request that does what I need it to:
https://github.com/dularion/streama/pull/368
It's a breaking change, so it makes sense it hasn't been accepted yet. There will need to be a migration script that checks for a user
table and runs mysql -u steama -p pass -e "RENAME TABLE 'user' TO 'users'"
or similar. There would need to be something similar for the Java H2 database. I suppose a pull request with migration scripts could get merged with #368 getting merged after.
I've manually added what was in #368 to what I've git cloned and my steama-1.1.war
runs just fine with the postgres database I made earlier.
great!
I think it's a good idea to implement this. But I want to discuss how the migration should work.
Do we think its enough to put in the release notes of the update this is in that you need to migrate any databases before startup?
Is there a way we can auto migrate both h2 and mysql on application startup?
Since interacting with h2 seems to require Java anyway, a database check and migration could be included in the startup of streama. I feel like that it might be a bit "bloated" to keep one time use code around, so keeping it around for a few versions then removing it could be a way to go. If anyone stays too long on an old pre-migration version, then they can use one of the versions that still have the migration code before upgrading to the latest version. I think Java can be used to interact with mysql/mariadb, so we could use either the bash script I wrote, or do the same thing in Java. I think using Java may be more suitable cross platform, since the bash script should only be suitable for Linux and I think MacOS and BSD.
We could just stick with the script method and write a batch script for Windows too. During the version check, it can check for which database is being used and either download the script for the OS in use, or run the h2 migration java code. I'm thinking it's probably possible to make the h2 migration stuff a separate java file, but I'd need to look into that a bit further on how that works.
I like the idea of keeping the migration stuff separate from the main streama.war file as much as possible, and possibly download a script or a java file. We'd still need to include a means of checking the database on startup though if we want it to be more automatic. After the migration we could delete any leftover migration files since they aren't needed anymore.
I agree. Keeping the migration stuff separate from the main application is a good way to go. Maybe a separate jar distributed with the release when a migration needs to happen. In the main app we just need to check if migration has been completed before we start any database related stuff.
In another application I am working on we are soon rolling out a migration system where upcoming migrations are added to a database table, and they are run through with a CRON job if they dont have to block startup, or at startup if they need to block. Then, when finished, they are marked as completed and never run again. That way, we dont bloat startup too much but still dont need to tell each user what migrations to run & when. What do you think?
That sounds good to me. I was toying with the idea of using systemd timers with that idea since some distros might not have a cron daemon installed by default, but have systemd. I think that would be a bit more tedious since creating the systemd timer and enabling it would require sudo, and as long as the streama user and permissions are set up correctly I don't think sudo would be necessary with a CRON job. We'll probably need to note somewhere in the streama setup guides and changelog that a cron daemon is a dependency if/when such a migration system is implemented.
I've learned a bit more about systemd services, and you can configure them to be run by specific users and groups. So a streama
user and/or a streaming
group could run the service for the migration. This would be nice so streama database migrations are only run by a streama
user and/or streaming
group. This would be good since anything that happens can be isolated to what streama
and/or streaming
has permissions to access. We only want to handle streama related stuff, and containing everything permissions wise would be good in the event of something going wrong. I think it would be good security wise. Also having log output centralized and visible with dmesg
or journalctl
could be nice.
Since each migration is a one time thing, making things a bit more generic with systemd might be necessary. So having a streama-migration.service
and streama-migration-at-startup.service
for either migration case. The migration files could be put in /opt/
, just to pick an arbitrary directory. Then the services could just be written to run their respective, generically named, migration files. The PathExists=
option can be used to monitor where the migration script should show up, and automatically starts when it does show up. Signing the migration files with gpg and only running when they are signed correctly would be a good idea here.
I think a set of options regarding how migrations are handled would probably be a good thing to consider.
Option 6: Don't notify user of needed migration and just run at a scheduled time* (automatic scheduled mode)
*Time could be set in configuration. If not set in config, time can be asked for and either be used one time or set in config. Boot time could be an option.
Also notifying the user of the result could be good too.
Backups and rolling back in the event of failure would be nice, but that could be a separate feature/issue.
We can still have CRON jobs as an option, we'll just need a crontab for a streama
user. Also a set of log files like /var/log/streama/error.log
and /var/log/streama/streama.log
, for example, would be nice if output is not going to be visible with dmesg
and/or journalctl
. Being able to choose between systemd or CRON in the streama settings page could be nice. Alternatively, it could be set in application.yml
.
I think I could handle the systemd service bit myself. I'd imagine just fetching the migration filename/URL from the migration table, and downloading it from the streama repo could work nicely. That's assuming the migrations are added to the database table that way. I'd need to look at how it's being done with CRON, and go from there.
As far as getting the list of migrations, I guess there could be a migrations.latest
file that could be merged with a users database, then checked if any migrations are needed. A periodic CRON job or systemd timer could check if migrations.latest
has any differences from the users migrations table and merge them. Having streama automatically check for migrations.latetest
on startup could be a good idea, or default behavior even.
After all is said and done, the migration files can be rm
ed after a successful migration. I think /tmp/
could be used, then we could avoid messing with deleting files manually. However, the migration files would need to be re-downloaded in the event of a migration failure and subsequent reboot. That might not be a big deal, but we'll need to consider that depending on the behavior we want with the migration files.
It would be really nice to be able to have PostgreSQL as an option for those of us that are trying to use a single postgres database.