diff --git a/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6300-hs-booking-item.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6300-hs-booking-item.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6306-hs-booking-item-migration.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6306-hs-booking-item-migration.sql new file mode 100644 index 00000000..83870841 --- /dev/null +++ b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6306-hs-booking-item-migration.sql @@ -0,0 +1,96 @@ +--liquibase formatted sql + +-- TODO: These changesets are just for the external remote views to simulate the legacy tables. +-- Once we don't need the external remote views anymore, create revert changesets. + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-mapping:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CREATE TABLE hs_booking_item_legacy_id +( + uuid uuid NOT NULL REFERENCES hs_booking_item(uuid), + legacy_id integer NOT NULL +); +--// + + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-sequence:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CREATE SEQUENCE IF NOT EXISTS hs_booking_item_legacy_id_seq + AS integer + START 1000000000 + OWNED BY hs_booking_item_legacy_id.legacy_id; +--// + + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-default:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +ALTER TABLE hs_booking_item_legacy_id + ALTER COLUMN legacy_id + SET DEFAULT nextVal('hs_booking_item_legacy_id_seq'); +--/ + + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-insert:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CALL defineContext('schema-migration'); +INSERT INTO hs_booking_item_legacy_id(uuid, legacy_id) + SELECT uuid, nextVal('hs_booking_item_legacy_id_seq') FROM hs_booking_item; +--/ + + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-insert-trigger:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- +create or replace function insertBookingItemLegacyIdMapping() + returns trigger + language plpgsql + strict as $$ +begin + if TG_OP <> 'INSERT' then + raise exception 'invalid usage of trigger'; + end if; + + INSERT INTO hs_booking_item_legacy_id VALUES + (NEW.uuid, nextVal('hs_booking_item_legacy_id_seq')); + + return NEW; +end; $$; + +create trigger createBookingItemLegacyIdMapping + after insert on hs_booking_item + for each row + execute procedure insertBookingItemLegacyIdMapping(); +--/ + + +-- ============================================================================ +--changeset hs-booking-item-MIGRATION-delete-trigger:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- +create or replace function deleteBookingItemLegacyIdMapping_tf() + returns trigger + language plpgsql + strict as $$ +begin + if TG_OP <> 'DELETE' then + raise exception 'invalid usage of trigger'; + end if; + + DELETE FROM hs_booking_item_legacy_id + WHERE uuid = OLD.uuid; + + return OLD; +end; $$; + +create trigger deleteBookingItemLegacyIdMapping_tg + before delete on hs_booking_item + for each row + execute procedure deleteBookingItemLegacyIdMapping_tf(); +--/ diff --git a/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6308-hs-booking-item-test-data.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6308-hs-booking-item-test-data.sql diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql new file mode 100644 index 00000000..0cff5fbe --- /dev/null +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql @@ -0,0 +1,96 @@ +--liquibase formatted sql + +-- TODO: These changesets are just for the external remote views to simulate the legacy tables. +-- Once we don't need the external remote views anymore, create revert changesets. + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-mapping:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CREATE TABLE hs_hosting_asset_legacy_id +( + uuid uuid NOT NULL REFERENCES hs_hosting_asset(uuid), + legacy_id integer NOT NULL +); +--// + + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-sequence:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CREATE SEQUENCE IF NOT EXISTS hs_hosting_asset_legacy_id_seq + AS integer + START 1000000000 + OWNED BY hs_hosting_asset_legacy_id.legacy_id; +--// + + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-default:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +ALTER TABLE hs_hosting_asset_legacy_id + ALTER COLUMN legacy_id + SET DEFAULT nextVal('hs_hosting_asset_legacy_id_seq'); +--/ + + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-insert:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +CALL defineContext('schema-migration'); +INSERT INTO hs_hosting_asset_legacy_id(uuid, legacy_id) + SELECT uuid, nextVal('hs_hosting_asset_legacy_id_seq') FROM hs_hosting_asset; +--/ + + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-insert-trigger:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- +create or replace function insertassetLegacyIdMapping() + returns trigger + language plpgsql + strict as $$ +begin + if TG_OP <> 'INSERT' then + raise exception 'invalid usage of trigger'; + end if; + + INSERT INTO hs_hosting_asset_legacy_id VALUES + (NEW.uuid, nextVal('hs_hosting_asset_legacy_id_seq')); + + return NEW; +end; $$; + +create trigger createassetLegacyIdMapping + after insert on hs_hosting_asset + for each row + execute procedure insertassetLegacyIdMapping(); +--/ + + +-- ============================================================================ +--changeset hs-hosting-asset-MIGRATION-delete-trigger:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- +create or replace function deleteassetLegacyIdMapping_tf() + returns trigger + language plpgsql + strict as $$ +begin + if TG_OP <> 'DELETE' then + raise exception 'invalid usage of trigger'; + end if; + + DELETE FROM hs_hosting_asset_legacy_id + WHERE uuid = OLD.uuid; + + return OLD; +end; $$; + +create trigger deleteassetLegacyIdMapping_tg + before delete on hs_hosting_asset + for each row + execute procedure deleteassetLegacyIdMapping_tf(); +--/ diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 17d4d40a..26bd20b8 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -142,15 +142,19 @@ databaseChangeLog: - include: file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql - include: - file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql + file: db/changelog/6-hs-booking/630-booking-item/6300-hs-booking-item.sql - include: file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql - include: - file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql + file: db/changelog/6-hs-booking/630-booking-item/6306-hs-booking-item-migration.sql + - include: + file: db/changelog/6-hs-booking/630-booking-item/6308-hs-booking-item-test-data.sql - include: file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql - include: file: db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql + - include: + file: db/changelog/7-hs-hosting/701-hosting-asset/7016-hs-hosting-asset-migration.sql - include: file: db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql - include: diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java index f00d57dd..c8f107f1 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/BaseOfficeDataImport.java @@ -17,7 +17,6 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity; -import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeAll; @@ -615,7 +614,7 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { jpaAttempt.transacted(() -> { context(rbacSuperuser); contacts.forEach(this::persist); - updateLegacyIds(contacts, "hs_office_contact_legacy_id", "contact_id"); + updateLegacyIds(contacts, "hs_office_contact_legacy_id", "contact_id"); }).assertSuccessful(); jpaAttempt.transacted(() -> { @@ -699,24 +698,6 @@ public abstract class BaseOfficeDataImport extends CsvDataImport { assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS); } - private void updateLegacyIds( - Map entities, - final String legacyIdTable, - final String legacyIdColumn) { - em.flush(); - entities.forEach((id, entity) -> em.createNativeQuery(""" - UPDATE ${legacyIdTable} - SET ${legacyIdColumn} = :legacyId - WHERE uuid = :uuid - """ - .replace("${legacyIdTable}", legacyIdTable) - .replace("${legacyIdColumn}", legacyIdColumn)) - .setParameter("legacyId", id) - .setParameter("uuid", entity.getUuid()) - .executeUpdate() - ); - } - @Test @Order(9999) @ContinueOnFailure diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java index d10f3577..e9b61603 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java @@ -45,6 +45,7 @@ import static java.lang.Boolean.parseBoolean; import static java.util.Arrays.stream; import static java.util.Objects.requireNonNull; import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; import static net.hostsharing.hsadminng.mapper.Array.emptyArray; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.assertj.core.api.Assertions.assertThat; @@ -334,6 +335,30 @@ public class CsvDataImport extends ContextBasedTest { errors.clear(); assertThat(errorsToLog).isEmpty(); } + + protected void updateLegacyIds( + Map entities, + final String legacyIdTable, + final String legacyIdColumn) { + em.flush(); + entities.forEach((id, entity) -> em.createNativeQuery(""" + UPDATE ${legacyIdTable} + SET ${legacyIdColumn} = :legacyId + WHERE uuid = :uuid + """ + .replace("${legacyIdTable}", legacyIdTable) + .replace("${legacyIdColumn}", legacyIdColumn)) + .setParameter("legacyId", id) + .setParameter("uuid", entity.getUuid()) + .executeUpdate() + ); + } + + String fetchFirstLegacyIds(final String table) { + return ((List>) em.createNativeQuery( + "SELECT * FROM " + table + "_legacy_id WHERE legacy_id is not null ORDER BY legacy_id LIMIT 10", + List.class).getResultList()).stream().map(row -> row.get(1).toString()).collect(joining("\n")); + } } class Columns { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java index d3ed3407..876dd36c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java @@ -47,12 +47,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.regex.Pattern; -import java.util.stream.Collectors; import static java.util.Arrays.stream; import static java.util.Map.entry; import static java.util.Map.ofEntries; import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER; @@ -758,9 +758,28 @@ public class ImportHostingAssets extends BaseOfficeDataImport { jpaAttempt.transacted(() -> { context(rbacSuperuser); bookingItems.forEach(this::persistRecursively); + updateLegacyIds(contacts, "hs_booking_item_legacy_id", "legacy_id"); }).assertSuccessful(); } + @Test + @Order(19019) + void verifyBookingItemLegacyIds() { + assumeThatWeAreImportingControlledTestData(); + assertThat(fetchFirstLegacyIds("hs_booking_item")).isEqualTo(""" + 1000000021 + 1000000022 + 1000000023 + 1000000024 + 1000000025 + 1000000026 + 1000000027 + 1000000028 + 1000000029 + 1000000030 + """.trim()); + } + @Test @Order(19120) @Commit @@ -949,8 +968,27 @@ public class ImportHostingAssets extends BaseOfficeDataImport { assertThat(haCount).isEqualTo(68); } + // ============================================================================================ + @Test + @Order(19998) + void verifyHostingAssetLegacyIds() { + assumeThatWeAreImportingControlledTestData(); + assertThat(fetchFirstLegacyIds("hs_hosting_asset")).isEqualTo(""" + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 363 + 381 + """.trim()); + } + @Test @Order(19999) void logErrorsAfterPersistingHostingAssets() { @@ -1006,6 +1044,11 @@ public class ImportHostingAssets extends BaseOfficeDataImport { } ).assertSuccessful() ); + + jpaAttempt.transacted(() -> { + context(rbacSuperuser); + updateLegacyIds(assets, "hs_hosting_asset_legacy_id", "legacy_id"); + }).assertSuccessful(); } private void verifyActuallyPersistedHostingAssetCount( @@ -1610,7 +1653,7 @@ public class ImportHostingAssets extends BaseOfficeDataImport { //noinspection unchecked zoneData.put("user-RR", ((ArrayList>) zoneData.get("user-RR")).stream() - .map(userRR -> userRR.stream().map(Object::toString).collect(Collectors.joining(" "))) + .map(userRR -> userRR.stream().map(Object::toString).collect(joining(" "))) .toArray(String[]::new) ); domainDnsSetupAsset.getConfig().putAll(zoneData);