Skip to content

OBPIH-6740 Move liquibase migrations to a single entrypoint changelog#4860

Merged
ewaterman merged 7 commits intodevelopfrom
maintenance/OBPIH-6740-unify-liquibase-changelog
Jan 15, 2025
Merged

OBPIH-6740 Move liquibase migrations to a single entrypoint changelog#4860
ewaterman merged 7 commits intodevelopfrom
maintenance/OBPIH-6740-unify-liquibase-changelog

Conversation

@ewaterman
Copy link
Member

@ewaterman ewaterman commented Sep 24, 2024

✨ Description of Change

A concise summary of what is being changed. Please provide enough context for reviewers to be able to understand the change and why it is necessary. If the issue/ticket already provides enough information, you can put "See ticket" as the description.

Link to GitHub issue or Jira ticket: https://pihemr.atlassian.net/browse/OBPIH-6740

Description: There are more details in the ticket, but essentially this change moves the migration logic that we had in Bootstrap into the entrypoint changelog. I've also taken the chance to clean up how we call our clean install migrations vs regular upgrade migrations to hopefully simplify the process somewhat. This approach lets us take advantage of the migration plugin's properties (which will be convenient for tests to be able to override the changelog, providing its own that will insert test data). For example:

grails:
    plugin:
      databasemigration:
          changelogFileName: changelog.groovy


environments:
  test:
      plugin:
          databasemigration:
              changelogFileName: changelog-test.groovy

You'll also notice that I added a 'final' tagged changeset to each release folder. We don't strictly need to use tags for this change to work, but it is a more proper solution in my opinion. It's easy enough to revert though if we choose not to use them.

@ewaterman ewaterman added the warn: do not merge Marks a pull request that is not yet ready to be merged label Sep 24, 2024
@ewaterman ewaterman requested a review from jmiranda September 24, 2024 21:18
@ewaterman ewaterman self-assigned this Sep 24, 2024
@github-actions github-actions bot added type: maintenance Code improvements, optimizations and refactors, dependency upgrades... domain: backend Changes or discussions relating to the backend server flag: schema change Hilights a pull request that contains a change to the database schema flag: config change Hilights a pull request that contains a change to the app config labels Sep 24, 2024
@ewaterman
Copy link
Member Author

@jmiranda take a look at this when you get a chance. I've only tested the happy path on my local so it's not ready to merge yet but I wanted to get something into review so that we could talk about it. If we like it, and want to move forward with a change like this, we can open it up to the rest of the team and start testing it more properly.

* Represents an app version from the perspective of a tagged liquibase changeSet.
* By convention these should map to directories under the grails-app/migrations folder (Ex: '0.9.x').
*/
class TaggedMigrationVersion implements Comparable<TaggedMigrationVersion> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a convenience class to make comparing versions easier

@ewaterman
Copy link
Member Author

ewaterman commented Sep 24, 2024

okay, I see that this is failing for integration tests with:

WARN  groovy.sql.Sql - Failed to execute: SELECT EXISTS (SELECT 1 FROM DATABASECHANGELOG) because: Table 'test.DATABASECHANGELOG' doesn't exist
    2024-09-24 21:26:36,369 [Test worker] ERROR o.s.boot.SpringApplication - Application startup failed
    liquibase.exception.ChangeLogParseException: java.sql.SQLSyntaxErrorException: Table 'test.DATABASECHANGELOG' doesn't exist

I'll try to figure out why migrations aren't running properly for test containers but we can still review this change as normal for now.

Maybe it just needs the following config:

grails.plugin.databasemigration.autoMigrateScripts = ['RunApp','TestApp']
grails.plugin.databasemigration.forceAutoMigrate = true

* List all of our tagged migration versions. Any new tagged versions should be added to this list.
* By convention, these should map to the migrations directories.
*/
final List<TaggedMigrationVersion> ALL_VERSIONS = [
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about having it read all the folder names in the /migrations folder to extract these versions so that we wouldn't need to update this list with every release but that felt pretty hacky so I left it like this. We're already expecting that specific folder structure though so maybe it's fine to do.

@jmiranda jmiranda changed the title OBPIH-6740: move liquibase migrations to a single entrypoint changelog OBPIH-6740 Move liquibase migrations to a single entrypoint changelog Sep 27, 2024
@ewaterman ewaterman removed the warn: do not merge Marks a pull request that is not yet ready to be merged label Oct 3, 2024
@ewaterman
Copy link
Member Author

I've tested this change on my local 0.9.x setup and on clean installs via integration tests. It could be useful to further test this for 0.8.x installs just to be extra safe though

@jmiranda
Copy link
Member

I promise I'll get back to reviewing this one soon.

@codecov
Copy link

codecov bot commented Jan 2, 2025

Codecov Report

Attention: Patch coverage is 55.40541% with 33 lines in your changes missing coverage. Please review.

Project coverage is 7.73%. Comparing base (08b3608) to head (b6f1ac2).
Report is 191 commits behind head on develop.

Files with missing lines Patch % Lines
src/main/groovy/util/LiquibaseUtil.groovy 54.54% 13 Missing and 7 partials ⚠️
src/main/groovy/util/TaggedMigrationVersion.groovy 53.57% 6 Missing and 7 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             develop   #4860      +/-   ##
============================================
+ Coverage       7.67%   7.73%   +0.05%     
- Complexity       834     854      +20     
============================================
  Files            605     610       +5     
  Lines          42451   42581     +130     
  Branches       10308   10343      +35     
============================================
+ Hits            3260    3292      +32     
- Misses         38711   38802      +91     
- Partials         480     487       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jmiranda
Copy link
Member

I encountered a weird issue when running this against a 0.8.x database.

2025-01-13 15:12:59,467 ERROR [main] liquibase.changelog.ChangeSet: Change Set 0.8.x/changelog-2018-05-30-2300-create-dimensional-model.xml::1546354459620-35::jmiranda (generated) failed.  Error: Table 'openboxes_demo2.transaction_type_dimension' doesn't exist [Failed SQL: (1146) ALTER TABLE openboxes_demo2.transaction_type_dimension ADD CONSTRAINT FK7FA87A22B3FB7111 FOREIGN KEY (transaction_type_id) REFERENCES openboxes_demo2.transaction_type (id)]

Upon further investigation, it turns out the database was not getting restored completely as the mysql import was stopping around the shipment tables.

I hadn't noticed it the first time around, but upon re-running the restore process off the demo database dump I saw the following error.

[jmiranda@ThinkPad-P17 ~]$ mysql openboxes_demo < openboxes_demo.sql 
ERROR 1273 (HY000) at line 5071: Unknown collation: 'utf8mb4_0900_ai_ci'

For context, I'm running the mysqldump on MySQL 8 and the MySQL import on MariaDB, so there's something wonky between the two. However, the weird thing is that none of our tables should be using utf8mb4 since we always default to utf8 which is a pointer to utf8mb3.

Long story short, I need a bit more time to debug this.

At the very least the changelog seems to be executing the expected versions, so I think once I think we'll be good once I get passed this.

2025-01-13 15:12:55,768 INFO  [main] org.pih.warehouse.BootStrap: Executing migrations ...
Executing migrations for release version: 0.8.x
Executing migrations for release version: 0.9.x

One caveat is that I was hoping to see the same logging from before (in particular, the lines that output executeChangelogVersions and upgradeChangelogVersions). Is it possible to restore those? It's just helpful for debugging in case we encounter issues in the future. You can make them DEBUG if necessary.

2025-01-13 16:07:03,366 INFO  [main] org.pih.warehouse.BootStrap: executedChangelogVersions: [[version:install], [version:0.8.x], [version:0.9.x], [version:0.5.x], [version:0.6.x], [version:0.7.x], [version:views]]
2025-01-13 16:07:03,366 INFO  [main] org.pih.warehouse.BootStrap: Dropping all views (will rebuild after migrations complete)...
2025-01-13 16:07:04,218 INFO  [main] l.c.StandardChangeLogHistoryService: Reading from openboxes.DATABASECHANGELOG
2025-01-13 16:07:04,627 INFO  [main] liquibase.changelog.ChangeSet: Custom SQL executed
2025-01-13 16:07:04,627 INFO  [main] liquibase.changelog.ChangeSet: ChangeSet views/drop-all-views.xml::1633402273161-1::jmiranda ran successfully in 371ms
2025-01-13 16:07:06,870 INFO  [main] org.pih.warehouse.BootStrap: upgradeChangeLogVersions: [0.5.x, 0.6.x, 0.7.x, 0.8.x]
2025-01-13 16:07:06,873 INFO  [main] org.pih.warehouse.BootStrap: Running upgrade changelog ...
2025-01-13 16:07:08,229 INFO  [main] l.c.StandardChangeLogHistoryService: Reading from openboxes.DATABASECHANGELOG
2025-01-13 16:07:08,780 INFO  [main] org.pih.warehouse.BootStrap: Running latest updates
2025-01-13 16:07:09,419 INFO  [main] l.c.StandardChangeLogHistoryService: Reading from openboxes.DATABASECHANGELOG

@ewaterman
Copy link
Member Author

ewaterman commented Jan 14, 2025

@jmiranda first off, thanks for testing these thoroughly.

Some of the log statements are necessarily gone because I moved the logic from BootStrap.groovy to inside the root changelog.groovy itself, which I don't think I can log from (I'm actually not certain about that). I can definitely log before and after the migrations run, so I'll try to add some more helpful log statements there at least. They shouldn't be too bloated so I don't mind them staying as INFO.

EDIT: okay it does seem like I can at least print to the console while inside the changelog so there are options. Obviously not ideal (a proper log would be better) but it works

@ewaterman
Copy link
Member Author

@jmiranda I updated the logs to the following. Turns out the changelog can in fact log properly:

2025-01-14 08:39:29,874 INFO  [main] org.pih.warehouse.BootStrap: Executing migrations ...
2025-01-14 08:39:30,401 INFO  [main] changelog: Dropping all views. They will be rebuilt after migrations complete...
2025-01-14 08:39:30,447 INFO  [main] changelog: Current migration version is 0.9.x. Skipping older migrations. They've already ran.
2025-01-14 08:39:30,451 INFO  [main] changelog: Executing migrations for release version: 0.9.x
2025-01-14 08:39:31,774 INFO  [main] l.c.StandardChangeLogHistoryService: Reading from openboxes.DATABASECHANGELOG
2025-01-14 08:39:31,972 INFO  [main] liquibase.changelog.ChangeSet: Custom SQL executed
2025-01-14 08:39:31,972 INFO  [main] liquibase.changelog.ChangeSet: ChangeSet views/drop-all-views.xml::1633402273161-1::jmiranda ran successfully in 144ms
2025-01-14 08:39:31,992 INFO  [main] liquibase.changelog.ChangeSet: SQL in file views/product-demand-view.sql executed
2025-01-14 08:39:31,992 INFO  [main] liquibase.changelog.ChangeSet: ChangeSet views/changelog.xml::1580848680306-1::jmiranda ran successfully in 12ms
...all other changesets...

Copy link
Member

@jmiranda jmiranda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally tested the three cases I wanted to cover

  • empty database
  • existing 0.8.x database
  • existing 0.9.x database

... and everything worked as expected.

@jmiranda
Copy link
Member

With respect to the issue I encountered with the 0.8.x database, it looks like MySQL 8 set the character set to utf8mb4 for one table on the demo server. I'm not sure how that happens, but will check to see if obdev1 and/or any of the other 0.8.x databases to see if they have any tables with the wrong character set.

mysql> SELECT table_name, CCSA.character_set_name FROM information_schema.`TABLES` T,        information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA WHERE CCSA.collation_name = T.table_collation   AND T.table_schema = "openboxes_demo" and character_set_name != 'utf8mb3' \G
*************************** 1. row ***************************
        TABLE_NAME: stockout_fact
CHARACTER_SET_NAME: utf8mb4
1 row in set (0.00 sec)

@ewaterman ewaterman merged commit 6afc7f7 into develop Jan 15, 2025
8 checks passed
@ewaterman ewaterman deleted the maintenance/OBPIH-6740-unify-liquibase-changelog branch January 15, 2025 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: backend Changes or discussions relating to the backend server flag: config change Hilights a pull request that contains a change to the app config flag: schema change Hilights a pull request that contains a change to the database schema type: maintenance Code improvements, optimizations and refactors, dependency upgrades...

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants