Skip to content

Commit

Permalink
gh-4594 Fix migs V07_06_00_405 & V07_06_00_305
Browse files Browse the repository at this point in the history
  • Loading branch information
at055612 committed Nov 15, 2024
1 parent 61032a3 commit e0d4c27
Show file tree
Hide file tree
Showing 6 changed files with 457 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ BEGIN
IF object_count = 0 THEN
ALTER TABLE execution_schedule ADD COLUMN run_as_user_uuid varchar(255) DEFAULT NULL;

-- The now legacy doc_permission table may be removed at some later point
-- in which case we don't have to do anything
SELECT COUNT(1)
INTO object_count
FROM information_schema.tables
Expand All @@ -43,10 +45,16 @@ BEGIN

IF object_count = 1 THEN
SET @sql_str = CONCAT(
'UPDATE execution_schedule es, doc_permission dp ',
'SET es.run_as_user_uuid = dp.user_uuid ',
'WHERE es.doc_uuid = dp.doc_uuid ',
'AND dp.permission = "Owner"');
'UPDATE execution_schedule es ',
'INNER JOIN ( ',
' SELECT DISTINCT ',
' dp.doc_uuid, ',
' FIRST_VALUE(dp.user_uuid) ',
' OVER (PARTITION BY dp.doc_uuid ORDER BY dp.id DESC) latest_owner_uuid ',
' FROM doc_permission dp ',
' WHERE dp.permission = "Owner" ',
') as dpv on dpv.doc_uuid = es.doc_uuid ',
'SET es.run_as_user_uuid = dpv.latest_owner_uuid;');
PREPARE stmt FROM @sql_str;
EXECUTE stmt;
END IF;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package stroom.analytics.impl.db.migration;

import stroom.analytics.impl.AnalyticsConfig.AnalyticsDbConfig;
import stroom.analytics.impl.db.AnalyticsDbConnProvider;
import stroom.analytics.impl.db.AnalyticsDbModule;
import stroom.db.util.AbstractFlyWayDbModule;
import stroom.test.common.util.db.AbstractSingleFlywayMigrationTest;

import org.flywaydb.core.api.MigrationVersion;

import java.util.List;
import java.util.Optional;

public abstract class AbstractAnalyticsMigrationTest
extends AbstractSingleFlywayMigrationTest<AnalyticsDbConfig, AnalyticsDbConnProvider> {

@Override
protected AbstractFlyWayDbModule<AnalyticsDbConfig, AnalyticsDbConnProvider> getDatasourceModule() {

return new AnalyticsDbModule() {

@Override
protected List<String> getFlyWayLocations() {
return mergeLocations(super.getFlyWayLocations(), getTestDataMigrationLocation());
}

// Override this, so we target a specific version and don't run all migrations
@Override
protected Optional<MigrationVersion> getMigrationTarget() {
return Optional.ofNullable(getTargetVersion());
}
};
}

@Override
protected Class<AnalyticsDbConnProvider> getConnectionProviderType() {
return AnalyticsDbConnProvider.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package stroom.analytics.impl.db.migration;

import stroom.util.logging.AsciiTable;
import stroom.util.logging.LambdaLogger;
import stroom.util.logging.LambdaLoggerFactory;
import stroom.util.logging.LogUtil;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;

public class TestV07_06_00_405 extends AbstractAnalyticsMigrationTest {

private static final LambdaLogger LOGGER = LambdaLoggerFactory.getLogger(TestV07_06_00_405.class);

private static final String USER1 = "user_1_uuid";
private static final String USER2 = "user_2_uuid";
private static final String USER3 = "user_3_uuid";

private static final String DOC1 = "doc_1_uuid";
private static final String DOC2 = "doc_2_uuid";
private static final String DOC3 = "doc_3_uuid";

private static final String OWNER = "Owner";
private static final String READ = "Read";

@Override
protected String getTestDataScript() {
final StringBuilder sb = new StringBuilder("""
-- Cross module so doesn't exist in the test
CREATE TABLE doc_permission (
id bigint NOT NULL AUTO_INCREMENT,
user_uuid varchar(255) NOT NULL,
doc_uuid varchar(255) NOT NULL,
permission varchar(255) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY `doc_permission_fk_user_uuid_doc_uuid_permission_idx` (
user_uuid,`doc_uuid`,`permission`),
KEY doc_permission_fk_user_uuid (`user_uuid`),
KEY doc_permission_doc_uuid (`doc_uuid`)
) ENGINE=InnoDB DEFAULT
CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
""");

// Create the perms
appendPermissionSql(sb, USER1, DOC1, OWNER);
appendPermissionSql(sb, USER2, DOC1, OWNER);
appendPermissionSql(sb, USER3, DOC1, READ);

appendPermissionSql(sb, USER1, DOC2, OWNER);
appendPermissionSql(sb, USER3, DOC2, READ);

// Create the schedules
appendScheduleSql(sb, "doc1 schedule 1", DOC1);
appendScheduleSql(sb, "doc1 schedule 2", DOC1);

appendScheduleSql(sb, "doc2 schedule 1", DOC2);
appendScheduleSql(sb, "doc2 schedule 2", DOC2);

appendScheduleSql(sb, "doc3 schedule 1", DOC3);
appendScheduleSql(sb, "doc3 schedule 2", DOC3);

return sb.toString();
}

private void appendPermissionSql(final StringBuilder sb,
final String userUuid,
final String docUuid,
final String permission) {

sb.append(LogUtil.message("""
insert into doc_permission (
user_uuid,
doc_uuid,
permission)
values (
'{}',
'{}',
'{}');
""", userUuid, docUuid, permission));
}

private void appendScheduleSql(final StringBuilder sb,
final String name,
final String docUuid) {

sb.append(LogUtil.message("""
insert into execution_schedule (
name,
node_name,
schedule_type,
expression,
doc_type,
doc_uuid)
values (
'{}',
'node1',
'mySchType',
'myExpr',
'myDocType',
'{}');
""", name, docUuid));
}

@Test
void test() {
// By this point the database will have been migrated up to the target version
// with the test data having been applied prior to the target migration running.
// If it fails before you get here then there is an exception in the migration
// or the test data.

// If you get here then you probably want to assert something about the migrated
// state.

final List<PermRow> permRows = getRows("""
select
id,
user_uuid,
doc_uuid,
permission
from doc_permission""",
rec -> new PermRow(
rec.get("id", long.class),
rec.get("user_uuid", String.class),
rec.get("doc_uuid", String.class),
rec.get("permission", String.class)));

LOGGER.info("permRows:\n{}", AsciiTable.fromCollection(permRows));

final List<ScheduleRow> scheduleRows = getRows("""
select
name,
doc_uuid,
run_as_user_uuid
from execution_schedule
""",
rec -> new ScheduleRow(
rec.get("name", String.class),
rec.get("doc_uuid", String.class),
rec.get("run_as_user_uuid", String.class)));

LOGGER.info("scheduleRows:\n{}", AsciiTable.fromCollection(scheduleRows));

Assertions.assertThat(scheduleRows)
.containsExactlyInAnyOrder(
new ScheduleRow("doc1 schedule 1", DOC1, USER2),
new ScheduleRow("doc1 schedule 2", DOC1, USER2),

new ScheduleRow("doc2 schedule 1", DOC2, USER1),
new ScheduleRow("doc2 schedule 2", DOC2, USER1),

new ScheduleRow("doc3 schedule 1", DOC3, null),
new ScheduleRow("doc3 schedule 2", DOC3, null));
}


// --------------------------------------------------------------------------------

public record PermRow(
long id,
String docUuid,
String userUuid,
String permission) {

}


// --------------------------------------------------------------------------------


public record ScheduleRow(
String name,
String docUuid,
String runAsUserUuid) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ protected void configure() {
// Don't call super.configure() else it will try to multi-bind AppDbConnProvider as
// a Datasource which will result in a circular dependency


// * *******************************************************
// * ********************** WARNING ************************
// * *******************************************************
// *
// * This approach of having a cross-module module is problematic.
// * It gets run after all the other modules, so it has
// * no idea what state each of the other modules is in, e.g. a
// * cross-module mig written for v7.5 may get run after all the
// * other modules have been brought up to v7.10 and thus
// * look different to what this mig expects.
// *
// * Leaving it here in case it is we find a way to safely use it.
// *
// * *******************************************************
// * *******************************************************
// * *******************************************************


// Bind all the cross-module java migrations here so flyway knows what to run.
// Don't do any SQL migrations as you can't guarantee that each module is in
// the same DB/host. Java migrations must inject the dbConnProvider for each
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,16 @@ BEGIN

IF object_count = 1 THEN
SET @sql_str = CONCAT(
'UPDATE processor_filter pf, doc_permission dp ',
'SET pf.run_as_user_uuid = dp.user_uuid ',
'WHERE pf.uuid = dp.doc_uuid ',
'AND dp.permission = "Owner"');
'UPDATE processor_filter pf ',
'INNER JOIN ( ',
' SELECT DISTINCT ',
' dp.doc_uuid, ',
' FIRST_VALUE(dp.user_uuid) '
' OVER (PARTITION BY dp.doc_uuid ORDER BY dp.id DESC) latest_owner_uuid ',
' FROM doc_permission dp ',
' WHERE dp.permission = "Owner" ',
') as dpv on dpv.doc_uuid = pf.uuid ',
'SET pf.run_as_user_uuid = dpv.latest_owner_uuid; ');
PREPARE stmt FROM @sql_str;
EXECUTE stmt;
END IF;
Expand Down
Loading

0 comments on commit e0d4c27

Please sign in to comment.