diff --git a/openbis/.classpath b/openbis/.classpath index c2d0eff320aa089b73bc122ddf38adb26e27ebc7..802cf87074c82f71f6827a08bb07b46bc8406af2 100644 --- a/openbis/.classpath +++ b/openbis/.classpath @@ -19,5 +19,6 @@ <classpathentry combineaccessrules="false" kind="src" path="/lims_base"/> <classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/> <classpathentry kind="lib" path="/libraries/restrictionchecker/restrictions.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/dbmigration"/> <classpathentry kind="output" path="targets/classes"/> </classpath> diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/.gitignore b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java new file mode 100644 index 0000000000000000000000000000000000000000..6442c70625c41cab215751b37f728e2cecfea133 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java @@ -0,0 +1,65 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; + +import ch.systemsx.cisd.dbmigration.java.IMigrationStep; +import ch.systemsx.cisd.lims.base.dto.TableNames; +import ch.systemsx.cisd.openbis.generic.server.util.UuidUtil; + +/** + * Finishes migration of the database version 22 to version 23 by setting the <i>UUID</i> code of + * the database instance. + * <p> + * Note that, at that time, the <i>UUID</i> column label was <code>GLOBAL_CODE</code> and not + * <code>UUID</code>. + * </p> + * + * @author Tomasz Pylak + */ +public final class MigrationStepFrom022To023 implements IMigrationStep +{ + // + // IMigrationStep + // + + public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException + { + final String uuid = UuidUtil.generateUUID(); + final int count = + simpleJdbcTemplate.queryForInt(String.format("select count(*) from %s", + TableNames.DATABASE_INSTANCES_TABLE)); + if (count == 1) + { + simpleJdbcTemplate.update(String.format("update %s set GLOBAL_CODE = ?", + TableNames.DATABASE_INSTANCES_TABLE), uuid); + } else + { + throw new IncorrectResultSizeDataAccessException(1, count); + } + } + + public final void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException + { + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java new file mode 100644 index 0000000000000000000000000000000000000000..abe27bacfb274e1b7a008bd016211ea86b9641ab --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java @@ -0,0 +1,188 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.log4j.Logger; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle; +import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter; +import ch.systemsx.cisd.lims.base.dto.TableNames; + +/** + * A migration step from database version <code>v23</code> to version <code>v24</code>. + * <p> + * This migration step does the following: it migrate the dataset locations in the database (<code>Instance_<instance code></code> + * renamed Instance_<UUID> when <instance code> is the original source). + * </p> + * + * @author Christian Ribeaud + */ +public final class MigrationStepFrom023To024 extends MigrationStepAdapter +{ + private static final String INSTANCE_PREFIX = "Instance_"; + + private static final Logger operationLog = + LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom023To024.class); + + private final static ParameterizedRowMapper<DatabaseInstance> DATABASE_ROW_MAPPER = + new ParameterizedRowMapper<DatabaseInstance>() + { + + // + // ParameterizedRowMapper + // + + public final DatabaseInstance mapRow(final ResultSet rs, final int rowNum) + throws SQLException + { + final String code = rs.getString("code"); + final String uuid = rs.getString("uuid"); + return new DatabaseInstance(code, uuid); + } + }; + + private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER = + new ParameterizedRowMapper<ExternalData>() + { + // + // ParameterizedRowMapper + // + public final ExternalData mapRow(final ResultSet rs, final int rowNum) + throws SQLException + { + final long id = rs.getLong("data_id"); + final String location = rs.getString("location"); + return new ExternalData(id, location); + } + }; + + private final static DatabaseInstance getDatabaseInstance( + final SimpleJdbcTemplate simpleJdbcTemplate) + { + final DatabaseInstance databaseInstance = + simpleJdbcTemplate.queryForObject(String.format( + "select uuid, code from %s where is_original_source = ?", + TableNames.DATABASE_INSTANCES_TABLE), DATABASE_ROW_MAPPER, true); + return databaseInstance; + } + + final static String getNewLocation(final ExternalData externalData, + final DatabaseInstance databaseInstance) + { + final String location = externalData.location; + final int index = location.indexOf('/'); + if (index < 0) + { + throw new DataIntegrityViolationException(String.format( + "No '/' found in location of externa data '%s'.", externalData)); + } + final String afterInstance = location.substring(index); + return INSTANCE_PREFIX + databaseInstance.uuid + afterInstance; + } + + // + // MigrationStepAdapter + // + + @Override + public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException + { + final DatabaseInstance databaseInstance = getDatabaseInstance(simpleJdbcTemplate); + final List<ExternalData> externalDatas = + simpleJdbcTemplate.query(String.format( + "select data_id, location from %s where location like 'Instance_%s%%'", + TableNames.EXTERNAL_DATA_TABLE, databaseInstance.code), + EXTERNAL_DATA_ROW_MAPPER); + if (externalDatas.size() == 0) + { + operationLog.info("No data set location has been migrated."); + } else + { + for (final ExternalData externalData : externalDatas) + { + final int updated = + simpleJdbcTemplate.update(String.format( + "update %s set location = ? where data_id = ?", + TableNames.EXTERNAL_DATA_TABLE), getNewLocation(externalData, + databaseInstance), externalData.id); + if (updated != 1) + { + throw new IncorrectResultSizeDataAccessException(1, updated); + } + } + operationLog.info(String.format( + "Following data set locations '%s' have been migrated.", CollectionUtils + .abbreviate(externalDatas, 10))); + } + } + + // + // Helper classes + // + + final static class DatabaseInstance + { + + final String code; + + final String uuid; + + DatabaseInstance(final String code, final String uuid) + { + this.code = code; + this.uuid = uuid; + } + } + + final static class ExternalData + { + final long id; + + final String location; + + ExternalData(final long id, final String location) + { + this.id = id; + this.location = location; + } + + // + // ExternalData + // + + @Override + public final String toString() + { + return ToStringBuilder.reflectionToString(this, + ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE); + } + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java new file mode 100644 index 0000000000000000000000000000000000000000..b78f9305cd7d4d1b08c8b92fc505c36683c769f1 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java @@ -0,0 +1,147 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.log4j.Logger; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle; +import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter; +import ch.systemsx.cisd.lims.base.dto.TableNames; + +/** + * A migration step from database version <code>v25</code> to version <code>v26</code>. + * <p> + * Adapts the data set locations in database after OBSERVABLE_TYPE has been renamed to + * DATA_SET_TYPE. + * </p> + * + * @author Izabela Adamczyk + */ +public final class MigrationStepFrom025To026 extends MigrationStepAdapter +{ + + private static final String OBSERVABLE_TYPE_PREFIX = "/ObservableType_"; + + private static final String DATA_SET_TYPE_PREFIX = "/DataSetType_"; + + private static final Logger operationLog = + LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom025To026.class); + + private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER = + new ParameterizedRowMapper<ExternalData>() + { + public final ExternalData mapRow(final ResultSet rs, final int rowNum) + throws SQLException + { + final long id = rs.getLong("data_id"); + final String location = rs.getString("location"); + return new ExternalData(id, location); + } + }; + + public final static String getNewLocation(final String oldLocation) + { + final int index = oldLocation.indexOf(OBSERVABLE_TYPE_PREFIX); + if (index < 0) + { + StringBuilder builder = new StringBuilder(); + builder.append("WARNING: "); + builder.append("No "); + builder.append(OBSERVABLE_TYPE_PREFIX); + builder.append(" found in external data location '"); + builder.append(oldLocation); + builder.append("'."); + operationLog.warn(builder.toString()); + return oldLocation; + } + return oldLocation.replaceFirst(OBSERVABLE_TYPE_PREFIX, DATA_SET_TYPE_PREFIX); + } + + // + // MigrationStepAdapter + // + + @Override + public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException + { + + final List<ExternalData> externalDatas = + simpleJdbcTemplate.query(String.format("select data_id, location from %s", + TableNames.EXTERNAL_DATA_TABLE), EXTERNAL_DATA_ROW_MAPPER); + if (externalDatas.size() == 0) + { + operationLog.info("No data set location has been migrated."); + } else + { + List<ExternalData> migrated = new ArrayList<ExternalData>(); + for (final ExternalData externalData : externalDatas) + { + String oldLocation = externalData.location; + String newLocation = getNewLocation(externalData.location); + if (newLocation.equals(oldLocation) == false) + { + final int updated = + simpleJdbcTemplate.update(String.format( + "update %s set location = ? where data_id = ?", + TableNames.EXTERNAL_DATA_TABLE), newLocation, externalData.id); + if (updated != 1) + { + throw new IncorrectResultSizeDataAccessException(1, updated); + } + migrated.add(externalData); + } + } + operationLog.info(String.format( + "Following data set locations '%s' have been migrated.", CollectionUtils + .abbreviate(migrated, 10))); + } + } + + final static class ExternalData + { + final long id; + + final String location; + + ExternalData(final long id, final String location) + { + this.id = id; + this.location = location; + } + + @Override + public final String toString() + { + return ToStringBuilder.reflectionToString(this, + ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE); + } + } +} diff --git a/openbis/source/sql/postgresql/migration/migration-022-023.sql b/openbis/source/sql/postgresql/migration/migration-022-023.sql index c2d5502c6e30323fb9f66fe6a05c422d331a1450..3418135781ad94ec41f7404695be8ee25774d32d 100644 --- a/openbis/source/sql/postgresql/migration/migration-022-023.sql +++ b/openbis/source/sql/postgresql/migration/migration-022-023.sql @@ -1,4 +1,4 @@ --- JAVA ch.systemsx.cisd.lims.server.dataaccess.migration.MigrationStepFrom022To023 +-- JAVA ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom022To023 -- Add column GLOBAL_CODE to the DATABASE_INSTANCES table. -- Set it's value from the code, it will be updated later from java. diff --git a/openbis/source/sql/postgresql/migration/migration-023-024.sql b/openbis/source/sql/postgresql/migration/migration-023-024.sql index 2e229e846aec8e5f67540c22190d607a95bac60b..e4c33a67d246b981399587e4e0766ff00f3c104d 100644 --- a/openbis/source/sql/postgresql/migration/migration-023-024.sql +++ b/openbis/source/sql/postgresql/migration/migration-023-024.sql @@ -1,4 +1,4 @@ --- JAVA ch.systemsx.cisd.lims.server.dataaccess.migration.MigrationStepFrom023To024 +-- JAVA ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom023To024 -- Drop constraint DBIN_GLOBAL_CODE_UK of DATABASE_INSTANCES table diff --git a/openbis/source/sql/postgresql/migration/migration-025-026.sql b/openbis/source/sql/postgresql/migration/migration-025-026.sql index 176435b689d564026ab6a69af9d219d37d44d3ea..95b93bcd8f8d8fc9f8a92b4b7029723f24777139 100644 --- a/openbis/source/sql/postgresql/migration/migration-025-026.sql +++ b/openbis/source/sql/postgresql/migration/migration-025-026.sql @@ -1,4 +1,4 @@ --- JAVA ch.systemsx.cisd.lims.server.dataaccess.migration.MigrationStepFrom025To026 +-- JAVA ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom025To026 -- Remove ID column from SAMPLE_INPUTS table DROP SEQUENCE SAMPLE_INPUT_ID_SEQ; -- There was a bug in migration to db 23 - the constraint was not created. So we drop it only if it exists. diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024Test.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024Test.java new file mode 100644 index 0000000000000000000000000000000000000000..2a8fc1bf7873f0144e3936eb32ff45af98fe5a76 --- /dev/null +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024Test.java @@ -0,0 +1,44 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration; + +import static org.testng.AssertJUnit.assertEquals; + +import org.testng.annotations.Test; + +import ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom023To024; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom023To024.DatabaseInstance; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom023To024.ExternalData; + +/** + * Test cases for the {@link MigrationStepFrom023To024}. + * + * @author Christian Ribeaud + */ +public final class MigrationStepFrom023To024Test +{ + + @Test + public final void testGetNewLocation() + { + final DatabaseInstance databaseInstance = new DatabaseInstance("DB1", "111-222"); + final ExternalData externalData = new ExternalData(1L, "Instance_DB1/Group_G/Project_P"); + final String newLocation = + MigrationStepFrom023To024.getNewLocation(externalData, databaseInstance); + assertEquals("Instance_111-222/Group_G/Project_P", newLocation); + } +} diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026Test.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026Test.java new file mode 100644 index 0000000000000000000000000000000000000000..64bc78532cac6fc06b351755dbc2acbffe1638aa --- /dev/null +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026Test.java @@ -0,0 +1,77 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration; + +import static org.testng.AssertJUnit.assertEquals; + +import org.testng.annotations.Test; + +import ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom025To026; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.migration.MigrationStepFrom025To026.ExternalData; + +/** + * Test cases for the {@link MigrationStepFrom025To026}. + * + * @author Izabela Adamczyk + */ +public final class MigrationStepFrom025To026Test +{ + + @Test + public final void testGetNewLocationWithRealLocation() + { + + final ExternalData externalData = + new ExternalData( + 1L, + "Instance_C199AD7D-5AC0-4DE1-BC19-682DE43CD0CA/Group_CISD/Project_NEMO/Experiment_EXP1/ObservableType_HCS_IMAGE/Sample_3VCP1/Dataset_microX-3VCP1"); + final String newLocation = MigrationStepFrom025To026.getNewLocation(externalData.location); + assertEquals( + "Instance_C199AD7D-5AC0-4DE1-BC19-682DE43CD0CA/Group_CISD/Project_NEMO/Experiment_EXP1/DataSetType_HCS_IMAGE/Sample_3VCP1/Dataset_microX-3VCP1", + newLocation); + } + + @Test + public final void testGetNewLocationNoObservableType() + { + + String location = "Instance_DB1/Group_G/Project_P/NotObservableType_XXX"; + final ExternalData externalData = new ExternalData(1L, location); + assertEquals(location, MigrationStepFrom025To026.getNewLocation(externalData.location)); + } + + @Test + public final void testGetNewLocationAlreadyMigrated() + { + + String location = "Instance_DB1/Group_G/Project_P/DataSetType_XXX"; + final ExternalData externalData = new ExternalData(1L, location); + assertEquals(location, MigrationStepFrom025To026.getNewLocation(externalData.location)); + } + + @Test + public final void testGetNewLocationDuplicatedObservableType() + { + + final ExternalData externalData = + new ExternalData(1L, + "Instance_DB1/Group_G/Project_P/ObservableType_XXX/ObservableType_XXX/"); + final String newLocation = MigrationStepFrom025To026.getNewLocation(externalData.location); + assertEquals("Instance_DB1/Group_G/Project_P/DataSetType_XXX/ObservableType_XXX/", + newLocation); + } +}