Skip to content

Commit

Permalink
EUREKA-65: add script to migrate data from mod-consortia (#77)
Browse files Browse the repository at this point in the history
Co-authored-by: Yaroslav_Kiriak <[email protected]>
  • Loading branch information
yaroslav-kiriak and yaroslav-epam authored Aug 15, 2024
1 parent 055dec3 commit 6381cb8
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 6 deletions.
40 changes: 36 additions & 4 deletions src/main/java/org/folio/consortia/service/FolioTenantService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.folio.consortia.service;

import java.sql.ResultSet;
import java.util.Map;
import liquibase.exception.LiquibaseException;
import liquibase.exception.UnexpectedLiquibaseException;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
Expand All @@ -9,6 +12,7 @@
import org.folio.consortia.domain.dto.CustomField;
import org.folio.consortia.domain.dto.CustomFieldType;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.exception.TenantUpgradeException;
import org.folio.spring.liquibase.FolioSpringLiquibase;
import org.folio.spring.service.PrepareSystemUserService;
import org.folio.spring.service.SystemUserScopedExecutionService;
Expand All @@ -26,7 +30,8 @@
@Primary
public class FolioTenantService extends TenantService {

private static final String EXIST_SQL = "SELECT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?)";
private static final String EXIST_SQL =
"SELECT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?)";

private final KafkaService kafkaService;
private final CustomFieldService customFieldService;
Expand All @@ -36,6 +41,7 @@ public class FolioTenantService extends TenantService {
private final CustomFieldsRetryProperties customFieldsRetryProperties;

private static final String ORIGINAL_TENANT_ID_NAME = "originalTenantId";
private static final String TENANT_NAME_PARAMETER = "tenantname";
private static final CustomField ORIGINAL_TENANT_ID_CUSTOM_FIELD = CustomField.builder()
.name(ORIGINAL_TENANT_ID_NAME)
.entityType("user")
Expand All @@ -62,6 +68,31 @@ public FolioTenantService(JdbcTemplate jdbcTemplate,
this.customFieldsRetryProperties = customFieldsRetryProperties;
}

/*
* Because of the liquibase.Scope implementation for the SpringLiquibase it is not possible to run several
* SpringLiquibase executions simultaneously. That is why this method must be synchronized.
*/
@Override
public synchronized void createOrUpdateTenant(TenantAttributes tenantAttributes) {
if (folioSpringLiquibase != null) {
var params = Map.of(TENANT_NAME_PARAMETER, folioExecutionContext.getTenantId());
folioSpringLiquibase.setChangeLogParameters(params);
log.info("Set ChangeLog parameters: {}", params);

folioSpringLiquibase.setDefaultSchema(getSchemaName());
log.info("About to start liquibase update for tenant [{}]", context.getTenantId());

try {
folioSpringLiquibase.performLiquibaseUpdate();
} catch (LiquibaseException | UnexpectedLiquibaseException e) {
throw new TenantUpgradeException(e);
}
log.info("Liquibase update for tenant [{}] executed successfully", context.getTenantId());
}

afterTenantUpdate(tenantAttributes);
}

@Override
protected void afterTenantUpdate(TenantAttributes tenantAttributes) {
try {
Expand All @@ -75,8 +106,8 @@ protected void afterTenantUpdate(TenantAttributes tenantAttributes) {
}

/**
* Implemented by HSQLDB way
* Check if the tenant exists (by way of its database schema)
* Implemented by HSQLDB way. Check if the tenant exists (by way of its database schema)
*
* @return if the tenant's database schema exists
*/
@Override
Expand All @@ -92,7 +123,8 @@ protected boolean tenantExists() {
private void createOriginalTenantIdCustomField() {
systemUserScopedExecutionService.executeAsyncSystemUserScoped(folioExecutionContext.getTenantId(), () -> {
if (ObjectUtils.isNotEmpty(customFieldService.getCustomFieldByName(ORIGINAL_TENANT_ID_NAME))) {
log.info("createOriginalTenantIdCustomField:: custom-field already available in tenant {} with name {}", folioExecutionContext.getTenantId(), ORIGINAL_TENANT_ID_NAME);
log.info("createOriginalTenantIdCustomField:: custom-field already available in tenant {} with name {}",
folioExecutionContext.getTenantId(), ORIGINAL_TENANT_ID_NAME);
} else {
createCustomFieldsWithRetry();
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/db/changelog/changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
<include file="changes/create-sharing-instance-action-table.xml" relativeToChangelogFile="true"/>
<include file="changes/create-sharing-setting-table.xml" relativeToChangelogFile="true"/>
<include file="changes/adjust-update-fields-of-auditable-info.xml" relativeToChangelogFile="true"/>
<include file="changes/migrate-data-from-mod-consortia.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.consortia_configuration" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''consortia_configuration''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.consortia_configuration (
id, central_tenant_id, created_by, created_date, updated_by, updated_date
) SELECT
id, central_tenant_id, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.consortia_configuration;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.consortium" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''consortium''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.consortium (
id, name, created_by, created_date, updated_by, updated_date
) SELECT
id, name, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.consortium;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.pc_state" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''pc_state''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.pc_state (
id, status, total_records, created_by, created_date, updated_by, updated_date
) SELECT
id, status, total_records, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.pc_state;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.pc_tenant_request" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''pc_tenant_request''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.pc_tenant_request (
id, pc_id, tenant_id, status, request_url, request_payload, response, response_status_code,
completed_date, created_by, created_date, updated_by, updated_date
) SELECT
id, pc_id, tenant_id, status, request_url, request_payload, response, response_status_code,
completed_date, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.pc_tenant_request;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.sharing_instance" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''sharing_instance''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.sharing_instance (
id, instance_id, source_tenant_id, target_tenant_id, status, error, created_by, created_date, updated_by, updated_date
) SELECT
id, instance_id, source_tenant_id, target_tenant_id, status, error, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.sharing_instance;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.sharing_setting" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''sharing_setting''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.sharing_setting (
id, setting_id, tenant_id, created_by, created_date, updated_by, updated_date
) SELECT
id, setting_id, tenant_id, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.sharing_setting;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.tenant" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''tenant''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.tenant (
id, name, consortium_id, code, is_central, created_by, created_date, updated_by, updated_date, setup_status, is_deleted
) SELECT
id, name, consortium_id, code, is_central, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date, setup_status, is_deleted
FROM ${tenantname}_mod_consortia.tenant;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

<changeSet id="EUREKA-65@@migrate-data-from-mod_consortia.user_tenant" author="yaroslavkiriak">
<sql>
DO
'
DECLARE
BEGIN
IF (EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = ''${tenantname}_mod_consortia'' AND table_name = ''user_tenant''))
THEN
INSERT INTO ${tenantname}_mod_consortia_keycloak.user_tenant (
id, user_id, username, tenant_id, is_primary, created_by, created_date, updated_by, updated_date
) SELECT
id, user_id, username, tenant_id, is_primary, created_by, created_date, updated_by,
(CASE WHEN updated_date IS NULL THEN created_date ELSE updated_date END) as updated_date
FROM ${tenantname}_mod_consortia.user_tenant;
END IF;
END;
' LANGUAGE plpgsql;
</sql>
</changeSet>

</databaseChangeLog>
2 changes: 1 addition & 1 deletion src/test/java/org/folio/consortia/base/BaseIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public abstract class BaseIT {
protected MockMvc mockMvc;

protected static final int WIRE_MOCK_PORT = TestSocketUtils.findAvailableTcpPort();
protected static final String TOKEN = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWt1X2FkbWluIiwidXNlcl9pZCI6IjFkM2I1OGNiLTA3YjUtNWZjZC04YTJhLTNjZTA2YTBlYjkwZiIsImlhdCI6MTYxNjQyMDM5MywidGVuYW50IjoiZGlrdSJ9.2nvEYQBbJP1PewEgxixBWLHSX_eELiBEBpjufWiJZRs";
public static final String TOKEN = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWt1X2FkbWluIiwidXNlcl9pZCI6IjFkM2I1OGNiLTA3YjUtNWZjZC04YTJhLTNjZTA2YTBlYjkwZiIsImlhdCI6MTYxNjQyMDM5MywidGVuYW50IjoiZGlrdSJ9.2nvEYQBbJP1PewEgxixBWLHSX_eELiBEBpjufWiJZRs";
public static final String TENANT = "consortium";
protected static WireMockServer wireMockServer;
protected static PostgreSQLContainer<?> postgreDBContainer = new PostgreSQLContainer<>("postgres:12-alpine");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import org.springframework.test.annotation.DirtiesContext;

@Log4j2
@DataJpaTest
@DataJpaTest(properties = "spring.liquibase.parameters.tenantname=consortium")
@EnablePostgresExtension
@DirtiesContext(classMode = AFTER_CLASS)
@Import({FolioAuditorAware.class})
Expand Down
Loading

0 comments on commit 6381cb8

Please sign in to comment.