From 5368b01148b43e6ea3d3deb779bfc5b64e06fcd6 Mon Sep 17 00:00:00 2001 From: Xin Li <59580070+xin-hedera@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:29:21 -0500 Subject: [PATCH] Fix v1.43.2 migration failure (#2450) - change ownership of the temp table and the function in the sql script to the importer user Signed-off-by: Xin Li --- ..._add_missing_token_account_association.sql | 30 ++++++++++++++++++- ...gTokenAccountAssociationMigrationTest.java | 22 +++++++------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.43.2__add_missing_token_account_association.sql b/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.43.2__add_missing_token_account_association.sql index 18f16a11f50..dae766b9b7e 100644 --- a/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.43.2__add_missing_token_account_association.sql +++ b/hedera-mirror-importer/src/main/resources/db/migration/v1/V1.43.2__add_missing_token_account_association.sql @@ -53,9 +53,37 @@ begin -- with cascade, also drop the trigger drop function add_missing_token_account_association() cascade; return null; -end; +end $$ language plpgsql; create trigger missing_token_account_trigger after insert on account_balance_file execute procedure add_missing_token_account_association(); + +-- change access privilege for importer db user, if different than db owner, so later the importer db user +-- can own the temp table and the trigger function +create or replace function change_access_privilege(grant_or_revoke boolean) returns void as +$$ +begin + if current_user <> '${db-user}' then + if grant_or_revoke then + grant create on schema public to ${db-user}; + execute 'grant ${db-user} to ' || current_user; + else + revoke create on schema public from ${db-user}; + execute 'revoke ${db-user} from ' || current_user; + end if; + end if; +end +$$ language plpgsql; + +select change_access_privilege(true); + +-- change owner of the temp table and the function to the importer db user so when the trigger function runs +-- by the importer db user, it can drop the temp table, the function itself, and the trigger +alter table if exists last_transaction owner to ${db-user}; +alter function add_missing_token_account_association() owner to ${db-user}; + +select change_access_privilege(false); + +drop function if exists change_access_privilege(boolean); diff --git a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/migration/AddMissingTokenAccountAssociationMigrationTest.java b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/migration/AddMissingTokenAccountAssociationMigrationTest.java index 745ede25c8b..5e5ac0fa8b9 100644 --- a/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/migration/AddMissingTokenAccountAssociationMigrationTest.java +++ b/hedera-mirror-importer/src/test/java/com/hedera/mirror/importer/migration/AddMissingTokenAccountAssociationMigrationTest.java @@ -108,8 +108,10 @@ class AddMissingTokenAccountAssociationMigrationTest extends IntegrationTest { @Resource private RecordParserProperties parserProperties; + private String migrationSql; + @Value("classpath:db/migration/v1/V1.43.2__add_missing_token_account_association.sql") - private File migrationSql; + private File migrationSqlFile; @Resource private RecordFileRepository recordFileRepository; @@ -123,14 +125,18 @@ class AddMissingTokenAccountAssociationMigrationTest extends IntegrationTest { @Value("classpath:db/scripts/undo_v1.43.2.sql") private File undoSql; + @Value("${hedera.mirror.importer.db.username}") + private String username; + @BeforeEach - void beforeEach() { + void beforeEach() throws IOException { customFeePgCopy = new PgCopy<>(CustomFee.class, meterRegistry, parserProperties); + migrationSql = FileUtils.readFileToString(migrationSqlFile, "UTF-8").replace("${db-user}", username); } @AfterEach void afterEach() throws IOException { - runScript(undoSql); + jdbcOperations.update(FileUtils.readFileToString(undoSql, "UTF-8")); } @ParameterizedTest @@ -143,7 +149,7 @@ void afterEach() throws IOException { }) void verify(Long lastTransactionConsensusTimestamp, boolean expectAdded, boolean freezeDefault, boolean freezeKey, boolean kycKey, TokenFreezeStatusEnum expectedFreezeStatus, - TokenKycStatusEnum expectedKycStatus) throws IOException { + TokenKycStatusEnum expectedKycStatus) { // given // at time of the new token creation: // collector1 is a fixed fee collector who collects fee in the new token and the existing token @@ -211,7 +217,7 @@ void verify(Long lastTransactionConsensusTimestamp, boolean expectAdded, boolean // when accountBalanceFileParser.parse(previousAccountBalanceFile); - runScript(migrationSql); + jdbcOperations.execute(migrationSql); accountBalanceFileParser.parse(latestAccountBalanceFile); // then @@ -227,10 +233,6 @@ void verify(Long lastTransactionConsensusTimestamp, boolean expectAdded, boolean assertThat(tokenAccountRepository.findAll()).containsExactlyInAnyOrderElementsOf(tokenAccountList); } - private void runScript(File file) throws IOException { - jdbcOperations.update(FileUtils.readFileToString(file, "UTF-8")); - } - private AccountBalance accountBalance(EntityId accountId, long consensusTimestamp, EntityId... tokens) { AccountBalance accountBalance = new AccountBalance(); accountBalance.setBalance(1000L); @@ -272,7 +274,7 @@ private RecordFile recordFile(Long lastTransactionConsensusTimestamp) { } private Token token(long createdTimestamp, boolean freezeDefault, boolean freezeKey, boolean kycKey, - EntityId tokenId) { + EntityId tokenId) { Token token = new Token(); token.setCreatedTimestamp(createdTimestamp); token.setDecimals(5);