From 0d033493d8eb55645d9b19359507c4367302ba46 Mon Sep 17 00:00:00 2001 From: Davide Grohmann Date: Thu, 29 Oct 2015 13:45:59 +0100 Subject: [PATCH] Bump the store version and add migration path from 2.3 to 3.0 --- .../org/neo4j/kernel/NeoStoreDataSource.java | 2 +- .../impl/store/CommonAbstractStore.java | 2 +- .../storemigration/SchemaIndexMigrator.java | 2 + .../storemigration/StoreMigrationTool.java | 2 +- .../impl/storemigration/StoreMigrator.java | 23 ++-- .../impl/storemigration/StoreUpgrader.java | 12 ++ .../storemigration/StoreVersionCheck.java | 5 +- .../storemigration/UpgradableDatabase.java | 82 +++++++++++--- .../legacystore/v22/Legacy22Store.java | 26 +---- .../legacystore/v23/Legacy23Store.java | 65 +++++++++++ .../storemigration/MigrationTestUtils.java | 38 +++++++ .../storemigration/StoreMigratorTest.java | 10 +- .../UpgradableDatabaseTest.java | 61 +++++++--- .../legacystore/v23/upgradeTest23Db.zip | Bin 0 -> 44801 bytes .../upgrade/StoreUpgradeOnStartupTest.java | 31 ++++-- .../StoreUpgraderInterruptionTestIT.java | 17 ++- .../test/java/upgrade/StoreUpgraderTest.java | 104 +++++++++++------- .../java/upgrade/StoreMigratorFrom19IT.java | 2 +- .../java/upgrade/StoreMigratorFrom20IT.java | 2 +- .../StoreUpgradeIntegrationTest.java | 20 +++- .../org/neo4j/storeupgrade/0.A.6-data.zip | Bin 0 -> 85737 bytes .../org/neo4j/storeupgrade/0.A.6-empty.zip | Bin 0 -> 29966 bytes 22 files changed, 382 insertions(+), 124 deletions(-) create mode 100644 community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v23/Legacy23Store.java create mode 100644 community/kernel/src/test/resources/org/neo4j/kernel/impl/storemigration/legacystore/v23/upgradeTest23Db.zip create mode 100644 integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-data.zip create mode 100644 integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-empty.zip diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java index 4cd900176657..a19ec649ec44 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -564,7 +564,7 @@ public void start() throws IOException private void upgradeStore( File storeDir, StoreUpgrader storeMigrationProcess, SchemaIndexProvider indexProvider ) { UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); storeMigrationProcess .addParticipant( indexProvider.storeMigrationParticipant( fs, pageCache ) ); storeMigrationProcess.migrateIfNeeded( storeDir, upgradableDatabase, indexProvider ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/CommonAbstractStore.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/CommonAbstractStore.java index 5854c8003f50..229678699a46 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/CommonAbstractStore.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/CommonAbstractStore.java @@ -51,7 +51,7 @@ */ public abstract class CommonAbstractStore implements IdSequence, AutoCloseable { - public static final String ALL_STORES_VERSION = "v0.A.6"; + public static final String ALL_STORES_VERSION = "v0.A.7"; public static final String UNKNOWN_VERSION = "Unknown"; protected final Config configuration; protected final PageCache pageCache; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java index 1e32fabbcf72..e7120a403fb6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java @@ -44,6 +44,7 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.logging.NullLogProvider; import static org.neo4j.kernel.api.index.SchemaIndexProvider.getRootDirectory; @@ -79,6 +80,7 @@ public void migrate( File storeDir, File migrationDir, SchemaIndexProvider schem deleteIndexesContainingArrayValues( storeDir, schemaIndexProvider ); break; case Legacy22Store.LEGACY_VERSION: + case Legacy23Store.LEGACY_VERSION: break; default: throw new IllegalStateException( "Unknown version to upgrade from: " + versionToMigrateFrom ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrationTool.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrationTool.java index fcbcedc9800e..75559398e5ba 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrationTool.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrationTool.java @@ -103,7 +103,7 @@ public File storeDir() try ( PageCache pageCache = createPageCache( fs, config ) ) { UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); migrationProcess.addParticipant( new StoreMigrator( new VisibleMigrationProgressMonitor( logService.getInternalLog( StoreMigrationTool.class ) ), fs, pageCache, config, logService ) ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java index b76e0cd09b62..566c8be8a9de 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java @@ -74,6 +74,7 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.propertydeduplication.PropertyDeduplicator; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.kernel.impl.storemigration.monitoring.MigrationProgressMonitor; import org.neo4j.kernel.impl.transaction.log.LogPosition; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; @@ -114,10 +115,10 @@ /** * Migrates a neo4j kernel database from one version to the next. - *

+ *

* Since only one store migration is supported at any given version (migration from the previous store version) * the migration code is specific for the current upgrade and changes with each store format version. - *

+ *

* Just one out of many potential participants in a {@link StoreUpgrader migration}. * * @see StoreUpgrader @@ -163,9 +164,9 @@ public void migrate( File storeDir, File migrationDir, SchemaIndexProvider schem writeLastTxChecksum( migrationDir, lastTxChecksum ); writeLastTxLogPosition( migrationDir, lastTxLogPosition ); - switch ( versionToMigrateFrom ) { + case Legacy23Store.LEGACY_VERSION: case Legacy22Store.LEGACY_VERSION: // nothing to do break; @@ -370,7 +371,7 @@ private void migrateWithBatchImporter( File storeDir, File migrationDir, long la Configuration importConfig = new Configuration.Overridden( config ); AdditionalInitialIds additionalInitialIds = - readAdditionalIds( storeDir, lastTxId, lastTxChecksum, lastTxLogVersion, lastTxLogByteOffset ); + readAdditionalIds( storeDir, lastTxId, lastTxChecksum, lastTxLogVersion, lastTxLogByteOffset ); BatchImporter importer = new ParallelBatchImporter( migrationDir.getAbsoluteFile(), fileSystem, importConfig, logService, withDynamicProcessorAssignment( migrationBatchImporterMonitor( legacyStore ), importConfig ), @@ -776,6 +777,7 @@ public void moveMigratedFiles( File migrationDir, File storeDir, String versionT idFilesToDelete = new StoreFile[]{}; break; case Legacy22Store.LEGACY_VERSION: + case Legacy23Store.LEGACY_VERSION: filesToMove = Collections.emptyList(); idFilesToDelete = new StoreFile[]{}; break; @@ -795,7 +797,10 @@ public void moveMigratedFiles( File migrationDir, File storeDir, String versionT true, // allow to overwrite target files StoreFileType.values() ); - StoreFile.removeTrailers( versionToUpgradeFrom, fileSystem, storeDir, pageCache.pageSize() ); + if ( !Legacy23Store.LEGACY_VERSION.equals( versionToUpgradeFrom ) ) + { + StoreFile.removeTrailers( versionToUpgradeFrom, fileSystem, storeDir, pageCache.pageSize() ); + } File neoStore = new File( storeDir, MetaDataStore.DEFAULT_NAME ); long logVersion = MetaDataStore.getRecord( pageCache, neoStore, Position.LOG_VERSION ); @@ -807,8 +812,11 @@ public void moveMigratedFiles( File migrationDir, File storeDir, String versionT // delete old logs legacyLogs.deleteUnusedLogFiles( storeDir ); - // write a check point in the log in order to make recovery work in the newer version - new StoreMigratorCheckPointer( storeDir, fileSystem ).checkPoint( logVersion, lastCommittedTx ); + if ( !Legacy23Store.LEGACY_VERSION.equals( versionToUpgradeFrom ) ) + { + // write a check point in the log in order to make recovery work in the newer version + new StoreMigratorCheckPointer( storeDir, fileSystem ).checkPoint( logVersion, lastCommittedTx ); + } } @Override @@ -818,6 +826,7 @@ public void rebuildCounts( File storeDir, String versionToMigrateFrom ) throws I { case Legacy19Store.LEGACY_VERSION: case Legacy20Store.LEGACY_VERSION: + case Legacy23Store.LEGACY_VERSION: // nothing to do break; case Legacy21Store.LEGACY_VERSION: diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java index cfed7c5fa748..1a4d793ea17a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java @@ -333,4 +333,16 @@ public UnexpectedUpgradingStoreVersionException( String filename, String expecte super( String.format( MESSAGE, filename, expectedVersion, actualVersion ) ); } } + + public static class DatabaseNotCleanlyShutDown extends UnableToUpgradeException + { + private static final String MESSAGE = + "The database is not cleanly shutdown. The database needs recovery, in order to recover the database, " + + "please run the old version of the database on this store."; + + public DatabaseNotCleanlyShutDown() + { + super( MESSAGE ); + } + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreVersionCheck.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreVersionCheck.java index 52f88f4c0f56..5ba0ba3f1a06 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreVersionCheck.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreVersionCheck.java @@ -59,7 +59,7 @@ record = MetaDataStore.getRecord( pageCache, neostoreFile, STORE_VERSION ); String storeVersion = MetaDataStore.versionLongToString( record ); if ( !expectedVersion.equals( storeVersion ) ) { - return new Result( Outcome.unexpectedUpgradingStoreVersion, storeVersion, expectedVersion ); + return new Result( Outcome.unexpectedUpgradingStoreVersion, storeVersion, neostoreFile.getName() ); } return new Result( Outcome.ok, null, neostoreFile.getName() ); @@ -83,7 +83,8 @@ public enum Outcome ok( true ), missingStoreFile( false ), storeVersionNotFound( false ), - unexpectedUpgradingStoreVersion( false ); + unexpectedUpgradingStoreVersion( false ), + storeNotCleanlyShutDown( false ); private final boolean success; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java index f5e9a71387fa..3cc8e8d3728b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java @@ -20,7 +20,9 @@ package org.neo4j.kernel.impl.storemigration; import java.io.File; +import java.io.IOException; +import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.kernel.impl.store.CommonAbstractStore; import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.storemigration.StoreVersionCheck.Result; @@ -29,6 +31,11 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; +import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; +import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; +import org.neo4j.kernel.recovery.LatestCheckPointFinder; +import org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint; /** * Logic to check whether a database version is upgradable to the current version. It looks at the @@ -36,11 +43,14 @@ */ public class UpgradableDatabase { + private final FileSystemAbstraction fs; private final StoreVersionCheck storeVersionCheck; private final LegacyStoreVersionCheck legacyStoreVersionCheck; - public UpgradableDatabase( StoreVersionCheck storeVersionCheck, LegacyStoreVersionCheck legacyStoreVersionCheck ) + public UpgradableDatabase( FileSystemAbstraction fs, + StoreVersionCheck storeVersionCheck, LegacyStoreVersionCheck legacyStoreVersionCheck ) { + this.fs = fs; this.storeVersionCheck = storeVersionCheck; this.legacyStoreVersionCheck = legacyStoreVersionCheck; } @@ -84,36 +94,82 @@ public String checkUpgradeable( File storeDirectory ) return Legacy22Store.LEGACY_VERSION; } + result = checkUpgradeableFor( storeDirectory, Legacy23Store.LEGACY_VERSION ); + if ( result.outcome.isSuccessful() ) + { + return Legacy23Store.LEGACY_VERSION; + } + // report error - String path = new File( storeDirectory, result.storeFilename ).getAbsolutePath(); switch ( result.outcome ) { - case missingStoreFile: - throw new StoreUpgrader.UpgradeMissingStoreFilesException( path ); + case missingStoreFile: + throw new StoreUpgrader.UpgradeMissingStoreFilesException( getPathToStoreFile( storeDirectory, result ) ); case storeVersionNotFound: - throw new StoreUpgrader.UpgradingStoreVersionNotFoundException( path ); + throw new StoreUpgrader.UpgradingStoreVersionNotFoundException( + getPathToStoreFile( storeDirectory, result ) ); case unexpectedUpgradingStoreVersion: throw new StoreUpgrader.UnexpectedUpgradingStoreVersionException( - path, Legacy21Store.LEGACY_VERSION, result.actualVersion ); + getPathToStoreFile( storeDirectory, result ), + Legacy23Store.LEGACY_VERSION, result.actualVersion ); + case storeNotCleanlyShutDown: + throw new StoreUpgrader.DatabaseNotCleanlyShutDown(); default: throw new IllegalArgumentException( "Unexpected outcome: " + result.outcome.name() ); } } + private String getPathToStoreFile( File storeDirectory, Result result ) + { + return new File( storeDirectory, result.storeFilename ).getAbsolutePath(); + } + private Result checkUpgradeableFor( File storeDirectory, String version ) { - Result result = null; - for ( StoreFile store : StoreFile.legacyStoreFilesForVersion( version ) ) + if ( Legacy23Store.LEGACY_VERSION.equals( version ) ) { - String expectedVersion = store.forVersion( version ); - File storeFile = new File( storeDirectory, store.storeFileName() ); - result = legacyStoreVersionCheck.hasVersion( storeFile, expectedVersion, store.isOptional() ); + // check version + File neoStore = new File( storeDirectory, MetaDataStore.DEFAULT_NAME ); + Result result = storeVersionCheck.hasVersion( neoStore, version ); + if ( !result.outcome.isSuccessful() ) { - break; + return result; + } + + PhysicalLogFiles logFiles = new PhysicalLogFiles( storeDirectory, fs ); + LatestCheckPointFinder latestCheckPointFinder = + new LatestCheckPointFinder( logFiles, fs, new VersionAwareLogEntryReader<>() ); + try + { + LatestCheckPoint latestCheckPoint = latestCheckPointFinder.find( logFiles.getHighestLogVersion() ); + if ( !latestCheckPoint.commitsAfterCheckPoint ) + { + return new Result( Result.Outcome.ok, null, null ); + } + } + catch ( IOException e ) + { + // ignore exception and return db not cleanly shutdown + } + + return new Result( Result.Outcome.storeNotCleanlyShutDown, null, null ); + } + else + { + Result result = null; + for ( StoreFile store : StoreFile.legacyStoreFilesForVersion( version ) ) + { + String expectedVersion = store.forVersion( version ); + File storeFile = new File( storeDirectory, store.storeFileName() ); + result = legacyStoreVersionCheck.hasVersion( storeFile, expectedVersion, store.isOptional() ); + if ( !result.outcome.isSuccessful() ) + { + break; + } } + return result; } - return result; } public boolean hasCurrentVersion( File storeDir ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v22/Legacy22Store.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v22/Legacy22Store.java index b3bcbc838028..dca825c36505 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v22/Legacy22Store.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v22/Legacy22Store.java @@ -22,8 +22,6 @@ import java.io.File; import java.io.IOException; -import org.neo4j.helpers.UTF8; -import org.neo4j.kernel.impl.store.CommonAbstractStore; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyStore; /** @@ -38,31 +36,11 @@ public class Legacy22Store implements LegacyStore { public static final String LEGACY_VERSION = "v0.A.5"; - private final File storageFileName; - - public Legacy22Store( File storageFileName ) throws IOException - { - this.storageFileName = storageFileName; - assertLegacyAndCurrentVersionHaveSameLength( LEGACY_VERSION, CommonAbstractStore.ALL_STORES_VERSION ); - } - - /** - * Store files that don't need migration are just copied and have their trailing versions replaced - * by the current version. For this to work the legacy version and the current version must have the - * same encoded length. - */ - static void assertLegacyAndCurrentVersionHaveSameLength( String legacyVersion, String currentVersion ) - { - if ( UTF8.encode( legacyVersion ).length != UTF8.encode( currentVersion ).length ) - { - throw new IllegalStateException( "Encoded version string length must remain the same between versions" ); - } - } - @Override public File getStorageFileName() { - return storageFileName; + // not needed + throw new UnsupportedOperationException(); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v23/Legacy23Store.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v23/Legacy23Store.java new file mode 100644 index 000000000000..b6042ed6656d --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v23/Legacy23Store.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2002-2015 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.storemigration.legacystore.v23; + +import java.io.File; +import java.io.IOException; + +import org.neo4j.kernel.impl.storemigration.legacystore.LegacyStore; + +/** + * Reader for a database in an older store format version. + *

+ * Since only one store migration is supported at any given version (migration from the previous store version) + * the reader code is specific for the current upgrade and changes with each store format version. + *

+ * {@link #LEGACY_VERSION} marks which version it's able to read. + */ +public class Legacy23Store implements LegacyStore +{ + public static final String LEGACY_VERSION = "v0.A.6"; + + @Override + public File getStorageFileName() + { + // not needed + throw new UnsupportedOperationException(); + } + + @Override + public void close() throws IOException + { + // nothing to close + } + + @Override + public org.neo4j.kernel.impl.storemigration.legacystore.LegacyNodeStoreReader getNodeStoreReader() + { + // not needed + throw new UnsupportedOperationException(); + } + + @Override + public org.neo4j.kernel.impl.storemigration.legacystore.LegacyRelationshipStoreReader getRelStoreReader() + { + // not needed + throw new UnsupportedOperationException(); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java index 4e5fcbe1a360..3388d4e185f4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java @@ -41,9 +41,15 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; +import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; +import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; +import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.test.Unzip; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.neo4j.kernel.impl.store.CommonAbstractStore.ALL_STORES_VERSION; import static org.neo4j.kernel.impl.util.IoPrimitiveUtils.readAndFlip; @@ -151,6 +157,8 @@ public static File findFormatStoreDirectoryForVersion( String version, File targ { switch ( version ) { + case Legacy23Store.LEGACY_VERSION: + return find23FormatStoreDirectory( targetDir ); case Legacy22Store.LEGACY_VERSION: return find22FormatStoreDirectory( targetDir ); case Legacy21Store.LEGACY_VERSION: @@ -164,6 +172,11 @@ public static File findFormatStoreDirectoryForVersion( String version, File targ } } + private static File find23FormatStoreDirectory( File targetDir ) throws IOException + { + return Unzip.unzip( Legacy23Store.class, "upgradeTest23Db.zip", targetDir ); + } + public static File find22FormatStoreDirectory( File targetDir ) throws IOException { return Unzip.unzip( Legacy22Store.class, "upgradeTest22Db.zip", targetDir ); @@ -297,4 +310,29 @@ public boolean test( StoreFile item ) return item != StoreFile.COUNTS_STORE_LEFT && item != StoreFile.COUNTS_STORE_RIGHT; } }; + + public static void removeCheckPointFromTxLog( FileSystemAbstraction fileSystem, File workingDirectory ) + throws IOException + { + PhysicalLogFiles logFiles = new PhysicalLogFiles( workingDirectory, fileSystem ); + LatestCheckPointFinder finder = + new LatestCheckPointFinder( logFiles, fileSystem, new VersionAwareLogEntryReader<>() ); + LatestCheckPointFinder.LatestCheckPoint latestCheckPoint = finder.find( logFiles.getHighestLogVersion() ); + + if ( latestCheckPoint.commitsAfterCheckPoint ) + { + // done already + return; + } + + // let's assume there is at least a checkpoint + assertNotNull( latestCheckPoint.checkPoint ); + + LogPosition logPosition = latestCheckPoint.checkPoint.getLogPosition(); + File logFile = logFiles.getLogFileForVersion( logPosition.getLogVersion() ); + fileSystem.truncate( logFile, logPosition.getByteOffset() ); +// +// // do it again in case there are multiple checkpoints at the end of the tx log +// removeCheckPointFromTxLog( fileSystem, workingDirectory ); + } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java index 00f28c9b7f34..34835672be45 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java @@ -42,6 +42,7 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.kernel.impl.storemigration.monitoring.SilentMigrationProgressMonitor; import org.neo4j.kernel.impl.transaction.log.LogPosition; import org.neo4j.test.PageCacheRule; @@ -80,7 +81,8 @@ Legacy20Store.LEGACY_VERSION, new LogPosition( BASE_TX_LOG_VERSION, BASE_TX_LOG_ new Object[]{ Legacy21Store.LEGACY_VERSION, new LogPosition( BASE_TX_LOG_VERSION, BASE_TX_LOG_BYTE_OFFSET )}, new Object[]{ - Legacy22Store.LEGACY_VERSION, new LogPosition( 2, BASE_TX_LOG_BYTE_OFFSET )} + Legacy22Store.LEGACY_VERSION, new LogPosition( 2, BASE_TX_LOG_BYTE_OFFSET )}, + new Object[]{Legacy23Store.LEGACY_VERSION, new LogPosition( 3, 169 )} ); } @@ -95,7 +97,7 @@ public void shouldBeAbleToResumeMigrationOnMoving() throws Exception LogService logService = NullLogService.getInstance(); PageCache pageCache = pageCacheRule.getPageCache( fs ); UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); String versionToMigrateFrom = upgradableDatabase.checkUpgradeable( storeDirectory ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); @@ -126,7 +128,7 @@ public void shouldBeAbleToResumeMigrationOnRebuildingCounts() throws Exception LogService logService = NullLogService.getInstance(); PageCache pageCache = pageCacheRule.getPageCache( fs ); UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); String versionToMigrateFrom = upgradableDatabase.checkUpgradeable( storeDirectory ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); @@ -158,7 +160,7 @@ public void shouldComputeTheLastTxLogPositionCorrectly() throws Throwable LogService logService = NullLogService.getInstance(); PageCache pageCache = pageCacheRule.getPageCache( fs ); UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); String versionToMigrateFrom = upgradableDatabase.checkUpgradeable( storeDirectory ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabaseTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabaseTest.java index e53d16f0050e..7fa2d4b14361 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabaseTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabaseTest.java @@ -19,6 +19,7 @@ */ package org.neo4j.kernel.impl.storemigration; +import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -34,11 +35,13 @@ import org.neo4j.helpers.UTF8; import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyStoreVersionCheck; import org.neo4j.kernel.impl.storemigration.legacystore.v19.Legacy19Store; import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.test.PageCacheRule; import org.neo4j.test.TargetDirectory; @@ -47,7 +50,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.neo4j.kernel.impl.store.MetaDataStore.Position.STORE_VERSION; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.changeVersionNumber; +import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.removeCheckPointFromTxLog; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.truncateToFixedLength; @RunWith( Enclosed.class ) @@ -72,7 +77,8 @@ public static Collection versions() new Object[]{Legacy19Store.LEGACY_VERSION}, new Object[]{Legacy20Store.LEGACY_VERSION}, new Object[]{Legacy21Store.LEGACY_VERSION}, - new Object[]{Legacy22Store.LEGACY_VERSION} + new Object[]{Legacy22Store.LEGACY_VERSION}, + new Object[]{Legacy23Store.LEGACY_VERSION} ); } @@ -90,7 +96,7 @@ public void setup() throws IOException public void shouldAcceptTheStoresInTheSampleDatabaseAsBeingEligibleForUpgrade() throws IOException { // given - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); @@ -104,9 +110,12 @@ public void shouldAcceptTheStoresInTheSampleDatabaseAsBeingEligibleForUpgrade() @Test public void shouldRejectStoresIfOneFileHasIncorrectVersion() throws IOException { + // there are no store trailers in 2.3 + Assume.assumeFalse( Legacy23Store.LEGACY_VERSION.equals( version ) ); + // given changeVersionNumber( fileSystem, new File( workingDirectory, "neostore.nodestore.db" ), "v0.9.5" ); - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); @@ -121,7 +130,7 @@ public void shouldRejectStoresIfOneFileHasIncorrectVersion() throws IOException public void shouldDetectOldVersionAsDifferentFromCurrent() throws Exception { // given - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); @@ -135,12 +144,34 @@ public void shouldDetectOldVersionAsDifferentFromCurrent() throws Exception @Test public void shouldRejectStoresIfOneFileShorterThanExpectedVersionString() throws IOException { + // there are no store trailers in 2.3 + Assume.assumeFalse( Legacy23Store.LEGACY_VERSION.equals( version ) ); + // given final int shortFileLength = 5 /* (RelationshipTypeStore.RECORD_SIZE) */ * 3; assertTrue( shortFileLength < UTF8.encode( "StringPropertyStore " + version ).length ); truncateToFixedLength( fileSystem, new File( workingDirectory, "neostore.relationshiptypestore.db" ), shortFileLength ); - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), + new LegacyStoreVersionCheck( fileSystem ) ); + + // when + final boolean result = upgradableDatabase.storeFilesUpgradeable( workingDirectory ); + + // then + assertFalse( result ); + } + + @Test + public void shouldRejectStoresIfDBIsNotShutdownCleanly() throws IOException + { + // checkpoint has been introduced in 2.3 + Assume.assumeTrue( Legacy23Store.LEGACY_VERSION.equals( version ) ); + + // given + removeCheckPointFromTxLog( fileSystem, workingDirectory ); + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); @@ -161,14 +192,14 @@ public static class UnsupportedVersions @Parameterized.Parameter( 0 ) public String version; private File workingDirectory; - private static final String neostoreFilename = "neostore.nodestore.db"; + private static final String neostoreFilename = "neostore"; @Parameterized.Parameters( name = "{0}" ) public static Collection versions() { return Arrays.asList( - new Object[]{"v0.9.5" }, - new Object[]{"v0.A.4" } + new Object[]{"v0.9.5"}, + new Object[]{"v0.A.4"} ); } @@ -182,13 +213,16 @@ public void setup() throws IOException // doesn't matter which version we pick we are changing it to the wrong one... MigrationTestUtils.findFormatStoreDirectoryForVersion( Legacy21Store.LEGACY_VERSION, workingDirectory ); changeVersionNumber( fileSystem, new File( workingDirectory, neostoreFilename ), version ); + File metadataStore = new File( workingDirectory, MetaDataStore.DEFAULT_NAME ); + MetaDataStore.setRecord( pageCacheRule.getPageCache( fileSystem ), metadataStore, STORE_VERSION, + MetaDataStore.versionStringToLong( version ) ); } @Test public void shouldDetectOldVersionAsDifferentFromCurrent() throws Exception { // given - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); @@ -203,7 +237,7 @@ public void shouldDetectOldVersionAsDifferentFromCurrent() throws Exception public void shouldCommunicateWhatCausesInabilityToUpgrade() throws IOException { // given - final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( + final UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, new StoreVersionCheck( pageCacheRule.getPageCache( fileSystem ) ), new LegacyStoreVersionCheck( fileSystem ) ); try @@ -216,10 +250,9 @@ public void shouldCommunicateWhatCausesInabilityToUpgrade() throws IOException { // then assertThat( e.getMessage(), containsString( neostoreFilename ) ); - assertThat( e.getMessage(), containsString( "has a store version number that we cannot upgrade from. " + - "Expected '" + Legacy21Store.LEGACY_VERSION + - "' but file is version 'NodeStore " + version + - "'." ) ); + assertThat( e.getMessage(), containsString( + "has a store version number that we cannot upgrade from. Expected '" + + Legacy23Store.LEGACY_VERSION + "' but file is version '" + version + "'." ) ); } } } diff --git a/community/kernel/src/test/resources/org/neo4j/kernel/impl/storemigration/legacystore/v23/upgradeTest23Db.zip b/community/kernel/src/test/resources/org/neo4j/kernel/impl/storemigration/legacystore/v23/upgradeTest23Db.zip new file mode 100644 index 0000000000000000000000000000000000000000..98aa9aab578695585ad0c811a587de1f17d99c61 GIT binary patch literal 44801 zcmaI61F&c@vn70NpL=ZEwr$>H+qP}nwr$(CZJYmnU;Q;RHS_9q?cO^{rB|<{DoJ&A z%S!=+Kmq)hQ2MKh{HO5$zrX;n0nBZTjNRx|lpz6tl@2l|St_2~==gq+l1u>*N<4-p|8e%e$p&AgDS`ZR^k0hhe>tPIvNfgEH*_+0 zG5(+20SNt{Bgl*b7ZGNQmIM0-i11I5|2t3@`u_l;W*;j3cl`DF0i*t}NdYH%QG@&+ zAsPNBj)wXGz@lK}u>S{YV3@hsOa=QpuM+^k#3?WU%s-;m#*U8qrpAu{HS+(!z5JWq z|Ayg~_Iculc*AdxuZZ`$+AJ0kF~Ly%{5`5GlZ$7^xex5i6z?dAf;gyhVW50CFX>C{ zZdJn2yf~0Q$VL4i7>>~oBh^2-R5TW;9Gi~V;*VIVS>BYCs#wM3o4fAiN(Z_Ri=<7HooMbV{;%Yuctq(sm%mu5#W)Nm!T+HB2t^#fi*>_)w(d7YO0FT#VW)j8@3*NBBolm+EC#yOhOgmb zTm9Yb7CgBiS;BL|1^bEyVYPoCtpl{Sj6M4+4_ZIB<#;;uNTGl2Hqp_=XB^sxvr42W z{>;+GD3%a?>SzFGZP2-M8C<}6*~-!2sFg@uSFw!c?(h&sLLDG;&MndALG*XO#R+l* zdS!H{Az9M`&I&X&U!ptmf=!fLmE|6pMdEqF+l3k}v+Ba`v7Gw4r$917IdIiWEBg)# z6d^X0fyjurX$z92ZkTU9_?AW-NSg${+F*9DR#Q^Na+fC4_@)3M>x)w@LD7zl(@!~$~ zqjhle=6ZXuHdN@$U$Z@fh#{u{ID;E+5Y99$IXi^#@D&{8%t|EI|3K5cR7t!G@+` zzEt!d$P0Cqp`3f{0(L8eIoS#a#yHdoilB$p+g1!1(OC$0W3uXurKLG*qyv~BU>30; zm1=_JV=ai?1GJzO>e^xwOLn2EZwybOHz-sy^&vm}yy%5o|i;OpQMqK>ZXLas^S+;C*AE#%pgzY_dR zPG~m3TwSi(kwVOXjI1Rf-e>Ky#*%#>fdlX5(NSfbx@8F?*B3+@{9@OFwk*WzVoYr< z_mjaZN6$fg&!xEfN~?@?Mm|*KTAJVm+sZf}cO-z-J4qH3P&VCQ+`}YdnziMM+P=WA zzR>&~>Sg0*nF7mD{a_K$c^4i}W@HPZA$nemK&mAvFbd{l2|E$s>WLQ4Wdon6KMMSX z7IlMa#^nmS{wm56e^ZBdl^ZcEQM+8{K>Gz+h#-($xIRTgdio>05CZK?E%G{fKfZI% zAUhzlpcReENz8wR*O*GIpB9!vIkhkzK`jeU?$O&mT~J@b+{SPU8JZyidOG&!Ioh~K z)+;l-xHESWK%FkL(0OHe{3SxfZ+0AE2ha;luvj!aq&`=Z&#)Vz&Ylx5XDIJNjM@<> zab~X;E9LS$LAE(?so}xcw)I+yuCWRC@2SnCR`k++(|a zHH6Zb=0SjXu7TC*-Xn|ZYW4EDe!~ZD=El{i@G9VeLJGUlq3P^~8$OV}&kTkPW0~9D zfNAe$jfFPLEf;ktVvILqJNfYJ@mj-`!1oEkifmxW9|$CQWAK_nURk6Uow+4~&c+Kq ze<-|vzrM`=O}gI_eKodG2>i&U<13h0u85o!MwF;bIs}!Y41z4K4*hD4m0w#JC`DbW z7zg22PYa221BLg&;aU44*a8i~;)sO)$#i+ba_hKUd(dk&eiIl^>@#hB! zg-uuI46a6DZXCG-%2Aq2rY(0Dz-h0U9rZu)&67F4`|SZghcH_$T_ULZFq`=U$;mL- zLD>IF`39Nm*>izb_O>h*3sDpc#-T*9!|R2^zrE8QNenE zxIZmv6@x$=UB^(V7wGB%P@Rx_OH=d#pay2)Jw%6#>|Cl~(w1X70KG+!f_Xx8zt8GS zMZ>R=ngd`WV?+7uV2B#Se5P=8F0#v6mc>ose&5bUBATAuu_FbYql%u3W2l@nUgp%7 zcxdg0+oi-gr8$A?e!~>mq;1ls@QL~|ETWm8MMwFj(J2WJ!3e`=d@?JPU>ZA1cporE ztN@)Z|7U#wdP6?mmF4~vuuCP`RVB3XavAvaHh>iiUgKOZ!a)~(h(MsDsHITK`-V|B zO;iFp%P`1hV=Oo~1I0uS8h$^Vx(qz#2yuKYx$fbg%r*5F z+NY&4Hsk}K1ecLNLMo5y>B*RH^k*u92--<#TxCl0>S;?ny0buSE+>wWPs3FqHNe_5 z2}BtO5ebNf`}e2Dwh2S>!EEt&S+jP?hs#U&tlsgW(4$Qd%2?1zI{Qi{8XI*}DBt#1 z+2u9dE7I7?NeRg}8QL35q>sVI*JJ&;IHt)!Y# ztWOP#ULqmtgP}{JxRS@i-F~<~TZOF0#}Kz+<#X7tGrYg;3Va)MB*SetyfBpq4_@B% z!Gi0ESvhj0gr17^Kv*ZQ#uPNpF3Q2`^mN#CK^Z{0xP=(><~m1TBH=hW%3I65?5@oa zs`uT28GymRgd(t(u$Zdq%vBKszlq6BWqVtkI?-n9?Vb|`V(h0(ffViOwulN$hR2qa zt5Yt$?#jj#_k8DGSt;h^>^JHl1Qrz0GU(tE86n;_@I)*3f32<@-ARW%(zK7m&g+f< ztJGF>e@N*p=*aOhsHr3L{?-*boUijJ&hw7sv?5pGmA74w_Yy_e-99e#Z>E18OQVP5JQms=)iSU7Iyd{N(O zS-J5}@h>@-U8~}HbAy<29c|LyWJ!Cu45DLnMau6tE7p>0XqcRosk(}-QkvNCk2{ev zehat_WG-sqnAPA%AB%FMI-3k-8L$S2br`ruLXBo6a)gkCFQllO;j;fi7SM`!oY2MkO5orcI!H5i7nmG-6eG*GjxCQ{UTfOJ>!YkN?2%DQgUu- zXdfAId$ne^t|TI#oBgH4?>%i%4&}`Fk`@4Pt(%k3nNZ`z(1ENs1Uj!iIZ{euP9w99 z+nQ>4WV1WU?2|AE_q)y*xIEjqPYU*NFx7ns#E~0V8SprHwX$lv z66tuqX54~5c2ga&Sjp@Pg0WLIR{9HcJ0Uj6YQ@<0OkwVNU8NPp@#;f5ytS;c^jZya zIVFrfdm;v&Br6D@vWnadhd`7>Rr89f`)(Kr&G$f>G->1lP612K zqphf1uEUq}B*~DXS!58DusbL*v?#D4F!!=gC*(u3AQXC&=u@`#$ z^e%wXtJkCSL{-=JBwp8CDU=h>A^1CS0?#^oStdGaFjQzUJW9h*=5qvSa2SX3>)gY+ z5j?7P1<(9Y#?X1>-2u(fcDBej9?UJ+e~!~Sbb^LAbURe2;rOIfWhKM0Q=g^PB2<(R zi*^BW99)tlWu!E+7s#V@wuJPv>?{xj0(d~RSq{n$;qi4s8jO(?EH?D8jbRT}O=_A- zxeL|M${w6DFYtoWn|JOs2M<_11Rm@gjw<|4)q-D&dcmx7^`&^MDel>t@E(@vgrr>{ zA5maV<1NJ8rjojEBefl;ppXcCy`>mo-nFJcY8Fb`8@rA z{EAu8RqJ=p6bg-OcW9+JkB@yM`efv|#bp}T%O9SwgsCB;baD9r()yIqVak!MMh&J= z6&-6{>P#bn`W&@?JLHJgX{j2aX3d?#XqZP$Isx=%W899iN5nk<)Ga%=6N- z+@0Aa*a-X|EJet$`>5U5|L5 zQMQ{P%(Vb`0B1IEeo|fD(cAl3A{s!ejJCnJ9FSbERDUu;xZ>V8K0;{9yS?L$F8Mj| zLBcf&@-GuDQa+Vlcz?;ZfR-ohbJSi!yjh5WGj~bkl**=z^vD;JO0B?$`+4xP&BXHO z2udg<8xD!Bx27^WSRK{GUhq}}SyuAqXfMyRUYKB?LyDGzP(iQrzxDAqXaO|7P{M&y z%qXj2h`E`o+qIj*D(VT(#A(4;DP`pQ?*`x*C}?@{`pw|Emb?EIBio*=$7<6pZEVbL z>;ltMze#)vd->xJTK&#yc{qVapzDjSqe0QZ1bS3M*SzP4dvLUS(-6H=9Uy!_(s+m zM%M0}5Ba5HEs5D(S<+~(i9YJEp=>Ze@Q^Y$FWD-K&Y)4p!YW)bt75?np=C34p<>qx zt8MKiYDt^bo{cqfYuW{W>T9wY{5B?f%Iuu!0T%c$z@WX@(iJLe+FCuq0pP20NL7fD zs_$0;;asliF#@kEU5< z6-n5QAcl@Vk}nF;s2+zctXYK-!C<*CTr?veLBBjvtI2fR!W@@TVzYo<9BbCgyAO!L zM#@y6gN@YfngmiPQdRWtD`Z3y2k_9xyp_84vK+LIe(WS^$ptq29U^H9@C}jSTzGr! za2@>FyUFMJ+VMWq-F^Px`ovauxzM#e5-L^SUe<=efL@sRn6q*(79u(V%AndWB z$aM$e(gnl#)~(o`&b@tJzSHb|Z10@BHQD#FE&vU@g@k*ME@H(lT(b=?T`O^7jLsBK z%Klgo2x&U@b0Hxuch8E>2^wE8M(sa~zNHQr4ryFV6bK2j$YP@jkc!gWo^@ifUw5em zr4M&)Y-gG{ds*1Fmi4-Acf5t~=$^c}YrWiA-nJe5?Ciwq!8p+~9rDCPAe$d_aV0|U z2&TQ9=?|esuOZJQU_H%bZ->h;oGmrLnuZ5n9Yw7u(B&2^i0%Dd64j_IrjThbp@7A? zse~0NpRAy*tN=@OzP80C+f9wNbsXI|1OEM!iO~{&o#7-Mtyd_E{0Y(#74;*56k^?A z-5mt$b7slT3&t}}GVEUfK4{1{Nhx26FA~4^sDvvm;=xxw9G$Bj*XF3qZh$Zi8HVUj z7Y8jocf^bcXMi15TkN3nWY7jCl1gi5lSL(-=0eHF!}qLF!ywf>qO5w)#DS!?9&`^7 zCvlIWCzGDBRFIVu)85@-_|x?uXzw zpk%+4Q3~t;mR%*+!?i^obLyRRrXJHGr-vt9B>f6no)U)@!en-E9ke$HOMv&YUv>GU zCQg&bj^u}}LaYuhlW?+<3J?&60pAkMt&k*&V}LP=2rGW07PBCok{F^m7c}V>Q{MYd z$PuWBR4QExq;N?l?2x3&2rE@oGsC`Bcoe!nRiUQq;x6lKMQu$JD;Wd3sF}Vn;W@w| z$_Ea#p{1CBTUBz5P5vU`pcYGXd|E6IW(wEIC6&%!$r1AMv2q z9xrsZUdTIJi4*TSF~iDHsR}dd-QZUK#aQefn?j4swvQPyilRpvVmT=(J8-|}AKR3V zCK4@#(5V_g*U%>1S|jAoT!!Vz%TSyKEY6syJ>ypb!*Rp(0Kuwjcy96Fk{c{h;v_UW zvhXZEk)*CBvEO586uH7pMcA& zFC{I4`q=+Am%t>T3l`|fur#!a(S)TTBs9B}TTl}9Me!F+=nYcouHK%i*{>Y8QAQ7F zu?AR~u;d%I=Dtyd5vM%aWLVSG(i&S4+^mqwjZJ$rJ*EQk)Zdmq(pH@@emjA*fy16( z!R=~iWTG0#jW%wOjc*&*~9lswy1p*L=`vU z_dWV|!1DXjv67rjcV~-m>fitbD5ecstyg zseDy^LOV@TbS{Vmw9^#w4eWAG`wBiInH&{hY=$$~Q?a$|_x8gIYW6_ASp_51*VY;c z<)cyk4C7$@Q+ED0m(`ZE)VPt`57%&RZzw$bjhcIi1H2y!(Yj)lqfQze&!MzqETx)F z@80#;@^ewl>B3yJsEx&&#jr#6YU*QPxpSfo_8-wvoLz6NX~Hguaj`WGh-g&Oy#FHk zq+8TLy?2Q><~>Fz+Jkgv3;X)l#;4@BA4}*XHPN_$LErMukDZ}-(%)aAZCA7Nc{9@| zzxrrvn98#li8PFtacH!)^zF?mLPOU8GQGwY2}aM3TOVy}EGs)M<|fGX-)gEy@Nuo0)Pa$U`K3l=5QR9Tq*B zg~MaR3w3^eIGDfLqJgLdS#fY;f3HNc(Ld_^qibzELtVAW2}z1__*HlrtBKRuz$yi7CPcB{S8L>!uot^?Aq#UBGOT|;Pji- zW{9LYjNfgEp(WJ*Y_sUOHxDM+8DId3*Kkch$DTi5^Yff;f5ruvEOyF`q2}759ksA$ zf9Pjz8q_*vUsBMZ*F|iJF*3GsnBa|QBQn?Mj$JRuv?ZRG|D z-Z~2MS{s0xN_wAA7~J79_6hi?8^&i-U)>L{Ja9 z*g?oGW)|wVMSUX_@2oiW=w>;|H-SWh`*m~oLP`94)KNiDydJ-aGn{19T?YKDUpvrPvdzH$;nH;DAXp%` z>jR)Wl|5bRBuBF|0)M*Za;tT<6c>0~HOwrz;Qr%u3QiESmHShO5L(~}f+^tmO!ryn z^V;>xXNgrLRjGHszs45cikk4HQ;8e^7s)Ip4(v&TWE$U{y^nGJNmfyz6K0f}x$;m2 zBSKy}K$U1Y(7ZNauQlTPPHCG{ZO|f87j0X^Ze!=L(Vh?dG#!j0QiHOSwSVXDbdw31 zPD~9R8#bYGY^7CRC9&3@5rQHUROTjoVveo0i0lzHR4``$P56l9fjVUg*lB2wup^GI z;l!>8inrSN2;D>Jw|w`yU*>A>Ip5jV@uLmUt=pm7c~GVe>#@3xn9go%m{kDabFCZe zbDguR<0RMnMCS=KmXqTeIw;`!Bmz+V_%nKW^L*PHFh(N7-3DeI^U<9TkdfLw-&%R; z8<{6e8m$yrg$g=1QQ}EnJdW5#Ph5zflkYYqG=~_d?u8R3u(j7Fhjj{uF6|SNe*(Yj zqmdB-P4$l6Yrw4s6zb!`;v#Q$tb2l&qtMz-@segj_!w!cR={{ z==DQBFh$QHu6Mx-b2PIzjcjUR=Cp>U5d4w52~Vz>N%UQa+dg>JQngU60PMb3hNIDvt$h=f|V4|&s^#(Y}qZ&8L!BOdP;|BvzodQ52-j> zz6w+e19K8|O$V9Ozxc@|3X4a@qRScjRpw1y?;KxU&Q<1eZv9%v8d9@+$(9v8L6#L= zClmg!5pGhdUZcc1G*(P&x59in(N1%0tBzl#2+ck^$9^ot$EHT0FGYb>>4s)}M4mkm z<41jhefveQKzJ>_c|U;ZR!)b#NVZM9>?r)-hp`aIrJ-%+b#FM)GoG#8lZ`&FiU8M+ zZTA6rDTBK`VkUt*Kv|n3V%XB!asb|G2d(Bda0x*N#VkZ>zV)~?Ps6bxj(i?`9dCXx z)j#vm3(yR@>OTl%jkRg$$O_*odh1GQ0|D)LolOO2rRotV5;d{OsFBpMSgUyX%#TiF z%L)~_@sYp{gffY$p+Ikl3?2R7K&(U(sUL+tVC!wfSL?h=8RgLcv)>4`-(O~L{oYuvb0NEX(^*?J^C{vcxd z5ndfr{lNHCM&r(EX@5a}9GLt>k3#7#JCyw@7R3(fOtZq*MOcQ}#V&H!y_^VPThv=V zE+00iC_NG55OYuB?H=AZ-Gb6M1W4#^x~T<>7@+&Y+a$a|vf-qUxNm7%xQ%1&#nZ9^ z06135NgedOpFHyF2-9mjgO1zGpU}JVKfaXJyvYf2#kWO{2O-qW#VszCR*%OXAIF7p z+s_ho(FJ(pvn56dmLEqRE6hGhvt1leeRFD#ROp{an===+9^zS4mnl!W>6n=cZ-^`% ze=qi&DDG32!>aah#b7^d!`*R$1sjRjLo^W|`(W*D{^)k|7Q}nubRKhSckt_*Mhc3?x3ppqF zlNEHjhvsuA5)MW90@CrghB~4#XOR^5$m4p#w%4QI=2hhzOWok5Y_rdzeN8@`JAW*@ z&iPoUXe?v2zs3=WKO2zgi`TRpp3TjcGXVBJ@k(z-36*3mqulLbKlGukvPr#m9k?o1 zbnSe_tSb!1>P>`x&)SHIff6tWwe5LJj)HQ#dtBP&CUuJ)b^J69?Rk7KD&}b*z&&T*L~nWN)GlOO)$L{9*)*JZ;B0&4gxAX3+;yCL!(KNQ zTGuRP^1LiR<#Ve1+9?}+^XGj-)EpbJ ztw%cp5|##M9Nw~Skt-nUNBV0N_1tjsl+&9Rv&pzpPQ)U02OB@P*UiySEaR~axv-&9 zjQfcd?2O@Y0*7q<=;v_SZhx41NU4O4CX+Ifa`gBTMTKDq%-1UmpcT3CXI`_GAoy(sMLFQp|nnF7bVtIz)(hG-Bfh$KvnA4r%F4vAeh$k&mOeA5L zezSwmVQXcVe%x)Pauy#bP}FzDzDcl;@2_%pyWl}lcSj3du`H;5y(TkgYYFKO3>tG7`GffwynemR6g>R*))+uH zS^=N%ehJBrTpYVKwI>7nRUF0}$hWbCkz~45_bG(uOt2>&-SzB9=5`?6HUu3l#NWuq ztXZ$n7jGftV)3;G4Swkx$N@qP9x*2t|KM04GflbpKkq+J{m}{PU_0EyF@8_he|(82 zoEn*qqw`Xnyv_I9>twPoG43lJ*&<4+tYEsbt~g-A;4q9K1IxuHWUVfPu9Vtu+kg$& zno4XSs-*&%K;?Ue<`eO_tq{G-9gfZuKT$Vyn%A@aCS+wv?qG zn?ifq0doY;-Z&7al2jxVxSc$l@9&{tWj~*BJFapg`r`1UHV_nz1~@WkGhT357wd;C z*q&p8WgZ4qt78t*R=9%e6BXkA zgFcQ2nt^wLf%&^nIqpPqw>>STRr$KjfZ{FV#XpT&a;?X4HXE8_mX)7l=3DN$g7-DA z$uBfqe_U@Bj9<^P+2yrEj4DJ$k1Us+E>U7@B~nUlZ^&Fp)&Mso6R%ZAKX=gu#K*9sF-z|cF0 zjT-6I8&6)5XFSLnvo8)5FYL&gR{pl~6>XmCrM-X%Ww++R;fuV6YKtCt*g$+8$qEdp z1vo@ucM@%S*m9Xk0ze(CcB2{|;NV3(t6pXu0zFtAWX#j1QaIQ8DX_&wvz_Jo#ZegWg!Q2?I5ZUR3 zR5(=DLYve<=0$2#xX$XZwlAV&j`@zNCr2<{Emd-ZFW5tSC_6z{pIr^@ezT6~0E+2~ zC}>QVU-8EPt&G%hk6~jNdLL;Rn=Kwm&N-$DH1 zP{6WhOiM3U=evb!qia@g^jis&-Sn1;j3kvQShbbc171c?s}ah&af=_I{<( zbjIV+N3Nr0m{G_Mi3&gRO$>9%(=yl`nkN6EXNo428^QeT%lQmLk5h07CF37;G6}a| zgMM*Zh$dN5NoZr#KjD|tBWw0`iBx6bXJPZMKdW%`)>rXdM3ICtHs%!-?ATD!MBAsdB>tHcY$ykq47+dj>yf>qLq;i35?2-<87n5X#|CpzWQ)aH!4q04evVRhx<`0N!c))pwVQ@Xeo%& z{Kz(J{qs4)n8l^;TGjcY#)>m&(}LZp82_hy8Y$e%X^D`=5xNIb^W$JAk@nuKeF)2` zG=1K}pgVYGPUeBSv~00!(iYGY=iA{P3kvP=&B{Yv|HxV|7JMaUELR+;}j6$5T{`jP!)t~z% z4H0Cw`0h}8*B02vKmc#CQg*JpzqwZp?3)mRLyH#ZZ-1YyFz*2jXicD9bjAhyCS&Glim*)YydLUkj*wj-pZcfpI|$&wb&>=PN1_-VX+}*dJ`! zRZ+Wn0rqnNhZYSC{f=AGotHD?@QFUx{h=<#3w6(Tm{Q#U4!f9;P~4DD)7DJ}FAvb`* zFT15q?(1!zOWho8?@k;o?QEfw`gv5U{lGl-C{k9Q_%}F+X@j={LiQWo-1dE7s8hSZ zt=G9ND8f{myl%Yrcoq@ZCyGAy@8=sKaF%43&ABJlMKi3UZo9GIf?VnmtGo1tpi~nJ43z-6I0KqKxROufj+?7233ri&F^vJ}sqkw;pI!0u*fExIqad1+GdX zxAm$<36f?jiwg_!K_tw?-VX$;3nb9RUo25;w3`zAvJLzAQ|pYc9oW%7DS|9_^)mJ9 zcvj30`mai{YOKT1gnnNxMhx=1LNw9@2#P%vo)yWlZ9ZA$Uo>)|02;Rii8tO_p}1UbhoAu==F1lo|--KkXYETNp9+!>_Jc?7W2$rCcwE=7|mtJlmd8C12O5 zmK!u~sBZf|R4I(Nl%+5nt+R%Hc|dJIG;=<$ARivLO=gwQD5)X~*ZtGz?y+A_OYN=Q z=jz{C7h{G`v5T+E961)#(O0)+LPL*dN)3;}or3cxgBg@`>QhAA*wuw&evgX#Td6Zd3@2Ok&~i{hTmPUJnLXn>$)3fze>PoJW=LXnH{EATSbE+d>0`r5ky8i_%yXa&nYAK zav)+X4Lyp!JshwEuAm;*sK-!-VuMy*M=IN?K_It8+iA^FZ4<6yjIFI2mfSl@rKnVC7i4hNa=Y-9(c>J``)#l2 z2ZhJ4U5TJKPm2m#{@~9%1tnG(a7g=8uT7xj8eFJ=N(5T^NKsd9osD6>J0$+qEu6fx zvhq#@YQnbxT3({emSlQ=wi&%zQA9<(%p+xvK4FVmRTcU}Sf`)f9VJ_Tj+78<6JF}b zg8oFucdC`$;OUbD*~+ETM|??p?z~<$Df5TRIfG*SaW)R3KD&*l1Yn(55E3~04 zIV+q8MtxlBh*~w1o3{fGTNVPO%RwH6!P_O)^X@Llyt3KfT=!rU-q+=H?2asbgx zbl6i8HPxTp;%}xkI~AFrvti;aP9>#Gfpo*&o!63@P}@U<{Z01LmGOoO0-3C4zQk~n zX|%=j>t7|;=4o@H$&b%(l#d4ItWHsJK?s2fXIhuAYiz?$pm7_@8=1vMABA{QTg@-?QGStHrd)xZtZV6% z`G%~WqOoX~MWWbf$+BFXldHEu=<=$mE){+BxW>P$gXCpJKMYZ)U3qvzf|fj1uq)X# z0xtJ1*mI!#w`6#QzY0zQB^9U;e6~w)jb64_Ths0F@w024Jazq*l1e=tT%|v+KY5Ed zE?nE0JFna0-sZlR&_phdo9E5o^qX)Tk^*-<+AmfKecMv**&iy=8Yw{aM z1n7jRvl%rLfY7Hp3jSThYEK~FOLQ4;B(5&gQJTH!0y3JFpdScSFzvZi)H-b`(nQi) zEKPX=))B|a^iah6d`8C;|8~DSt%DH^tD7)LQQ+)&>7ED*_;{RopEDq_UU%c2*K-Hm z_MM8A%xG)O7l*&|k<9s*1yNa7I!~OpKjeCi{1RN{L$e22ldp}I?c@~ize0bU(GjG% zYCLUZi)h^qR_S?&vgLaNcpg(whcA;IQ-{u(>kz)wjXqYfyAq?VZSWQ8dt^h>VZ=nm1S0Tu?tfnhe-{q7_T z95tsWF4|yj208H%dPmcB0gZeQ)4gN$0}t`E z^omD$2h!*s*2$H)m>M>)0GpC=HU;!PHq>tw3ulW zK)M<4eFd2O#mN=!th1|nNQ4}y-;xouPIrtbp7yJZ@3F8@;1&3Z|9C09sIBOuH7ZzJ zKxeni^w7%-8DVl5gEQ^jOPw~%OEFq170bf7s0_%+ha)cGps89|Fx&|YZbz@T%rX-d zj%Fvq#g5I?-Epr#+2^nB{e&|GIXf3eDp_vw4j6u9e9~?g5{&y`ZE-~C z>zc=@g*z5IW!oN{lo~F6jJ@u?HWB=iFG$XRUxWJ?#CK8B2Uu>^$N#Q3& zE|I&9ro&hZgDl|_h_>sy*MXdQzuxx4XbhUDn)eG1h`cD{Gc}&3`-AgcyMf7DY&4Li zII9Uw(q5EsBDJMFap~`9K*m#LP&Cl8f)AtTE+zV*Q?`P$LUNKX>26|_nHnU2NUSmF zcsE*zGgKn9=vcjEixw5$QZaWnMW-sFrCmg_C5*fbfWv8}$8i)8QkSy5v@+K$;&2A&WgXrt0lAxQfl#L|y*GT?bSM z*Fbrh2VhF02cCQg7PqsB-k`U01%4Jij`Co;tL?mgL%$t93kb8WMedR3tpDF*#UYf( zh6_e&i|W*6YFfa-(mhJ{*gqji(C>L;lklDsXN9GIKLBlIAZ~)7v2HyX3cI2{1xzzP zGh|L$4pZf1sS3YxMCYX#Co=DpQ}Gz?MOBiKI{sMp2|(&nDoxGxA?fV>I}EFEYienx z5I2!u-O=wvi8S5pZ9Vtto1{2`@n_mf&?1Ty6Qdn6b$Sea)szIX^2NUqsYuavi12(Y z{|ZL78I_G!1PsEKL?|9icS%9iiUR?^vH`)$O7nzrD^}dEzZ3$`@Im#MZ$xi*&nci!M`81a|Z+5^k4VD4|cuh zBXsf5)~~O?3>S?&IJ-pbT22Fl>sZ~sTt22wWB34cso*Zy`f{B4hKyX zG|M>&n>0RLUP0aA*X?5garwp`40qRgL$>a9DhzK2PdP<%~B2F_rh2cte(51*(YDC zbC3CL&5&JrA=UA%Um9y~%PsZH)PHI4y-ZbUz$S|LGZ@A4-gt=k%1;VaC%u1rm&5+< zzdmTWzwt(4zFGsyR~0(v>`&z4%_R!N7=ee8i+I7dB*5l;)pf4QmTDNXKW7%sL zs-Hk9R#|eRWj^@I5Nf5_nP@KTo>=u99g;jlX+N>eg0W|BNNGL(Q#n&sRMx&%`y~?F z$Md^xA31KV481H0x+6EYyv+Sm$*|{FYH4e77Ka|IY+;4?r$}H8IU5MAnx6pJejTC` ztI6^y=qtM$Py)zou3K9@HEX&j$qSDCd1uB!MK~t=d=$Kx*DlsKTnE0B@YI+ysd0r_FNX(7!<<1-wY$bXV1DC;NzWDz3#J z5C=1x7F>A-)Uon3a6%9n-WYge%kEYUe%d-}214?-Y7=vBC{ zf3}Nl%P()f+T4!VsAAZllrMm6HATsEVp16yvC_#3y56?|X9PwXj%T|e`tA#~0BUm; zs@foqvo>V=2x>bPZ@O;1oQ!RNf8UGc>IDoBLNJy+BIky80#E!@h~x19v;ip_R8=K% zc(wrl?S`Xho1OeGmZI7x1(?&4w(UkY{TJZHbH5%uSMVFFxf|Vb2JCMHF@G!xJD=h^ z`V4M(-1GoJ!iQWCS`dJh{G2u1>HHAU-Zrv*B=wn;zo!;V0+RYO>6Xx(VJ-v0^Si2O z2+3-A>D_dnJAkSfBuPDcMyEzWxkWsOW59n-d)+}tf6GLbRxUhLSoR8!u>>~4L3ea2 zOYs*Z^u_Rdjg3cNH5lzH`uq+-efbrW=uuT+a2yWS`8^DKIAsEC8>>FyBOHc4${D!~ zIG?ReR$#Q_yy%r2;qU-tDElN6O2uQ|+LPTl9dhp)DeAxO)O$Xzsd<+P#Vu7&m#Ut6 z0tQ^X+;2GAPMb>-zX}(tCYd4}>P^hPtwQt4owLauM9j!w#_vApQO&xgj{r@^>(wqT zQOh(ts%k09wnfs&HjaXZoCUF6Iv1l>lQfq$S)i9nOk0(s>mfMY8?;3LM81TqxbpNN zp!j8qhkqAQ3YwUWxox7&x6R5U%)b-<9Ram~OPgd~LP{1iiTPwj#!(k5bQmu`+gnQ^ zU_te0DB4M_3hj=5cT~cR%V)Tx!h$b&IQ-=V3n^o^9d0dQlDto}0aM(PKO{?38-EL?+ zMG)&MLDA6WOSeE$JY2hno~{;tT2bVEz6q$wWtFwf&oW9XrbP$2Q}}tTe4!}wDxN!3 zYcDg(FH9O&mawJ`efG7s2;Yns%_vz^7N;|6R%PV#juzx)+f)N*RThKLBE_WJe{5Y5 zhc=qqPW^Pb)!a!kjx5D0RaSYi>3mZde$hk*+YbfNR!nu0=Hwy;3C+9xu<&UzUV7EI z`8y6uyAnyORsO7*t&36Q#m-EC(|m1OEmc4jm*l6jGGMYY(46rUuw=FfgjFzOg>V#v zm}9yK83EU*3F1gAyJf%3ncXMK4)ov9@S z$AS7$zVyrkp7LqtZ)ZKHZFMHuhOOqtGa0>;z!nu6yOP581!6vKUmCriAY?Pj)>^cg zd!&<^z;=-3LI10PR4LSE2Gm1Aa_1^a!UVh$$Om6m&SEo7AcYl*o^H8-u#$5Lps&l>J4=2ac#elOM zdyK#qBv=pu`c6Qj;H@VtspR9$CcpStiliX3#3xgLphAVBBpAWbh9nZ z%E3)&^|9BF19VR6V-t00wg_NVq5`_ANNiqXam7(t2T_Ezn<<9Jp>gB>+$U6Y(zX@C z<&g3UEm?1oC2?#DlTVAX06&N1kkj3}zm1_?(xcLs8zLAoZo&B)DK@A`OD?AW5xpdN zv~UkXd2$9(ow2Us#v(NJ5ll~_$$plxyTaac&*vlr0%ihK+C$7`(@X|WNgh3G88M4T zUS%p_Y(i1hS`3b_o_JQLA>4u~pvErRvnPT+Akjr=%q1ms3Mgp57KK&5Y2#q#W@yO# z;Ettn2S{)Ss01yS0>q3{xlBNpGyr!dDT+oLvr_F%39u@UQ;ew3{WUTvb}>P%98^oI z_7<2G`%x^jLT0@ALVyp8H|ZLpC$)NkZ^0%&{u?o)J`h|)4YKA@oaCDXz}ZjI0(fM= zAX}8%PGVLWNJE8veigAC{y?rDtxXG)x9vm03Q_( zE8qrVWq3dd(&sN&Eci1=6OVkdi-T4AH}n#vLP$XE80oLyQV5B~B<4}SS3-bA6q1Sw z4B@EFzHd(^E45Zmgpbo_oV#?g|)vMF;cv#ZXQD^VzxYec%>)=v74+ zCP{*!C)@)Xt1gwaTfwQw6N6NYb>-c_=I zS@jOfH<*a|pwh)^=UtVItG}o9l2;aQcuf;m&@Az_H?Dod#2p7vKlkFZj?Dm*(@C>r zQ6{s)ZeK8Q44EJzk_zeTcOj%D3NYo9@|S0ovrZhiapebPCnXTLUI*e2j~@(lKhxEQ zOYkmlrF&8=>RM6iQWEQkE!w^cP3Dg*@lcMJ$3rDc0?NE61hY$6@ktc7#w6Iey<8An z+*vC{ggoC^TYE-#k)$;etrPc2sup-e(k= zU9^GHnnFdTHDe(CAX6(b%KXk|H-~S2b1b2A#Diw#z!0H6?QBq&DD@j&@$n-S=WDwe8*y@;Mm|i4hMf;WcAB z%xY9pdUE4o7KwoNRqvY5_vs%R&URRQJ0c?mqSPe_V+5h7SSah_gD ziY$~7Hza+IWUs*?-D0T6F3w6`0E69QG-PJH*|1V1M#iwH&J&3FZSMlaHC`#1E5H?% z>HIfuH8jgI&{@#sk}D4TP~sN3&sg;~;wU&s3#6bez`ARVkKYD3+W_LqYpOn#(*n_ zhdFH?dnhvTzEKHmdQ%1^WI)t!?4I+Qdv==dF&j5j)z&Q6N}O38>R^M!wpH{VBYbZg zT&i+$s&nRBC+fZsTpWHR@oI01kmM|gZJqmX%%zXutDefEei1?|BlBPV; zN<*D358K^S+>fla52()3LjIfGV$+3Z-79cQ@8F0?2Zsaq4-l_DYj@Jg(ac^)whtbe;_QDo+T5Du!Fy@+~4Zs{~e2HR(l`7xfIQvy?cZ}8T*bz>`2V@>? z1w|!pF%{P~BF>bakr8gODGTgcLVDn?sbKR#4fnI%_n9Ul}YNT1tMxYyu?d zF|v$}Y;bS5pOyK~Lfj^X7L znt9n(*g+hSi!Chk2edcAdp8bKRqpm}%zA8%2aOQ}@8Db8rtkX#${O_75AS^vtscx0=Z8t6g!HUgU)E2XWdR2R$hw&2krEoRc z&lArK?bVD?zo|Zk>U}Fti|Zgq@eS?NNZk&RLC{vfv@lMC&Yq*W^&4>LL;QQIB>Kp5 zxj9~5OXw4Insf}tn(5_Jax0t?YDCMzF0&)*R{u}6;*~j8j3Jc@ETiR19DXVAT9Rb| zs$Wx|mwPI0KM~lU-b@CbWOOFer>IYzhEgzkZyd|!M7}zvaaHYbW6ix}iWhP_v&(XB z!{4en7euDzF4Xv{(VIA4JXM}pNl&T35Ia`m=%tUXKqZ8lPr=6~Y_*i73cs2z{3s-* zbAEVByFmm86QVx(JH*JZstPh6g*p^$IZt1E&_ww5E~r?xR}P1J%#v+W z6m2Z_E^+K_&@O-u2Ct+lQ?qIKZxRyd{ker3VJVvZ10C{|e`&@3gV6oSLI&&~!l}I;SSM z9GgS4q{{i$6cI)QIOXa~)tsxmSTggcr?SpUfee9L%Dg_ec9nZLd!`Vm%l*&YM|{a) z$b_%P6|wc})FRB)Dpr=hd}6?`?P$Tzfu%=lmW7aqrk#U-CwDsQoI?|s)Mw9c50SF& zdLY>1KJ2dOjOytPg`zz-KYN%BW61SE4C@c@Ft?~U_?xt zy|T~rl@FzG8=opwhIe5K8@I&3m>5-YJM4)2Qd#*C{=>V%(_;?LVSdn%rQDDzq=-D5 zE{buWaRJHClN zeNsna2{#)sj^@hn2H|40SAQB|9Ig}D70qZ#Ji`Ba`&RKx(J))GyH*}~fCd{!RQ*%x zeUt)Id}Apf|L~(?dsgnU08vk(l<<7+Qy;8d3HjM2`;Ms^e~rWR6EYNaTcQW0CbYE# zm?qJa-vhZ>{3|N3`c22(P*d}%N>vR@F1k@!`))_Ax~(r_>i3we@Ux=ZUj`ZTh?NF_ zn!?jbbLs4K#OUYHO!P-Ow_njPg2{z`V3Q)Qj(-hJ0}GoU zB}fO6&Q1F=VlBJ~!x=fsZGlZUD$O%rW)W3cMunD{)qO6p)9;r31>GLMNvBORW5uad z+h0vG#R6m_LRA1zUE0$J63r|sY11Rs8(KJEXekec#0b zTa4_=F`g^NYryvPQyh7Amiu1i-Yu`w1rk5+)t>P=K^vEg``%kW{K+Zwj~Mqn61HpY zwdxAf?VV#d=cFg@yF=t1IGpaKkPa0z2)Xc$jH;@p$O$DRHP|4uyn#eT`wgh z2@zO2F&D-b1bDlW1WogmDJ3!L(p@z@u?o`ciWmp$vAF(?rLE#CnU*DymiL_nQiV6W zcyDE^dKQpZK)$4yarHBi&}JptZl_Jc25G9A&)K4$e9@3}86(H~0JhLcV=){NntQ~% z)%s?KP;{Nj$w9d|H`r+ncz5VvHuSLXzKD4&TJ1bQ)h%^e`#p-<@RzPrlhT`w08Vd`%+@Pb6*RUJ9$sX2Lj=g<3VH?(? zjdxSGm;FLQ7v6hmhhbQ+!-mjfdnc2oiLtFfaig#>&au+D6jL5wD3Z*hx34lK)c|44;82qaKR0K4ped4>%FDgAitli?7RK{ic|Q)n$hZ zHn8N-vB)b83J9#I>GoEj@(XzdK-a>%inO{NHkyJP-9!-wEjI$zQ;PrvZv!jFr3qk@ z;Wt1*dOjC2c7V+b?g@N(kSj;>Xe2O3)f|NL6$R)wkkp(!Vv&&dcWo+)`CbEz$5}-m zVl@16H~G1M7y%WV$YgJLU_%7~&jlv4#&A{S*&9T89Vl@&q#Dh*ZjOhicD`&d5JD{m zDK#2l0HC#wqCtDQ#%pNf9|>fP;}6bNHX%4XNYNi8YF8x-wsEz$0c&@qh`xF)0vn>F zsO$hnIf6B@9S?ea+>XsA?#T$^d67|c)M`TP!lQ5T1ij@!mD--{h`<>_|H}APjYCPy zaQ^D!5oS6dVILLvTnhEgzK&6OxtjG1)1*VMdxF)IBQoavpztMgp)_E>htan}#;&uH zahQ+0?R*AVc@4RsD&s_X-Y#l{x6ldbT@w})eYr>K&8~^f&F{h9j_hsaAH`;4Z#IwR z>^QVbjE_@{pWWDfz%*D9IV?p>1SKuRbM{A8sA2AUYYg`OX&kzXD1919C`Zex@=2(% zkV({)!HiG8W;S2xgLLzSInHVD5E0ksfL_csb1_xRDYAp)sbWsW3u%tc1`@g(4ZxGG z_X!JMVBPvq23T>`XS`1HcILv|^=AMw=(CY++E&~4bp&PoGaLicrYyI;=B9ls?!!k8 zwbt)MFeiIzrP9TmDa_qo*LUzTc*Y`sf{`mEB16zAL6EHOg^pmimr%|+0;*Aj*V2j7 zfly(9NN0!ypODK8Rjv-!E)qJTw${DTo6BVeOu*wrk!cf~*mw$0AAb~MfUiKWSm z^cD8#aQ0uajy^8@U^)CK+L%Mc26~=caMbxN7Ji|qM}pU9QQ-McibflQn+UGefPv~! z$g{pp@EtaiEFr^0&$^v(dqpno4kSMORG(yC3YeOr-j2rb5M@ktV{X+r!HJkV2Xzv! zF)_2OmP4jtU1MwVK0Z3y0a=UiN^rd3Ab4|vyOkO+B^_XiBPtsW2Xm(H2(ep~9<}zi zD;xq?T#crb+-njV+AQ(`!dU1N!3wDS7)n~#?LP0-tG7K^>t2pKWQ+qHDNRwl1PVxk z@fh3N7sI|#2rCloJpmM5KuRS_ag7=U%o9SJ%_m6^&OB!U&_@H4c9I>Dg;|~2V2Jnt z8m!dQi@k0A2L0vhgzML@PeJms9_C^nCoj>G+4QzRLccR|J zy>s5^rwJ4bM2j36^&z@r{rL{RhSE#h;jDQaz~jn^m@JDKhp46%l?_N6fTBcBF7Oh( z5!kKcd(HP;3nN${CK)Oe*bKDBUT;v!#yIX1A1pU+l-%*BMqKfnT9Nh;=_X-&RxzfN zNM46;1bH`h_aSTb8xp>|=*O_!zCF<$X*503Xo(>>^hP`EP+nrQhZX_SK4GNIG0`CH z?8cO)%JQhL&S!d40pQn9V*`DufO@Tl>!q<^NafXYupd8Y^8qR<2rFNXkW08UtS>PE z6w10_u#KBNXqTsDPD3Jcgr1Qncgu&;tpkSkgCE(#muziybDPKJP|dhA;kpX3AaJ11 zBxelTr-bEkd&c*bY0Pu)?h2>dmJaNRd!gKdn8ntBhr77d%IQ!h-51uJrai|3>NyZX2r}4n#QwA$3!qWlDMEq*SIGh*FKi*4|d1O|bH#%t0os?E(u2f*t zv!xa_Q?tLI)J;aeM4iTUewn-6_;l;Ce6(11*TwB$MV$+^2!rsA3kVJQm?qX}4z)R_ zmn*=q2Wy1*bSfh*wGF5UvwnHE6ozjByci*ngk<#tgk7dIgS&+2I$8Th9OnXXXz9GV z9<4@ZCxbuPJ(?ZVXS%TPHq&$fjn0bh>&lGCW(x4ED(v-eRGHc+VL&~$8)f{co8i!+ zvV)>!P&j8AD34q`Ggf0X{%(Vh@vQYFT zctOucwoq$>9%R}$-K=JlM%aw^RHF@zATGf5FNA;5ymNREsaxt*N4wF{+$8ppgvStx za8~5(AUzHX+W>Hn=VcO-vgBd5=^D&o@n;^-pa4mzL&phm6oj6+R07v5X;*y=I%-Q4)h|S?*PmtI*u0d|HSMnYt03l(PJOWE7C;H-7hV4H&*WaEqq`)G)Zb z;8Loxk3IZI#^ItcN&Vqh^ zLJ#t2yK<0iChF5!$Z;osGO_SySdUgx{|k6stfoYAHm9X_zZ-nhihM(e`x_706d{Tp zp#_)2fRRqz$VlFFMxu@bJ4Pk(4FNu4rkwl@RB>Q4H|yzZ<(u^ka;(qx-A*HRqPPej zzVX`P)NNbvIKB5lFEWx>U<>(#he&XVj~`}Ch~U>~XLBDDn1as^%3ttCu=fOv5b9M8 z67yoOEKm64%c@#&EtdnuAOk;$L$kF;fj7S)OGb!(|X zN{Ar*M2zTsnbn((u@&r}gTiiT*PdQ*)khFUeyyBU@Ln5YB*9!y6|3Jd%ts+sP{XdH z%t%Jn^th?CVphIkp?e&USNc=n+l5V^U>F(_kR-?$T$ybm92wn@;b4@S7D!K5D)B;r zI5-tWy^zoM|17WD_T0$1XI1B&kWSXOe@$muY}2zXv^ylVWNuBVh^5sWVQ$|^F{0=( z+gCXZ9t#yLP|!n5!Oj!zaoOsR?dgu_#UvNFBY3BoT4e+WoZ3^|t5iB4I|y z*}{5UPZMV644!FCxypgml^wjim=w?0UOEmE4>E^9?7>f*o$|T% zchBj0EI5McB*;Fvl&Os!+jAoEF{0#CyQ2~HFt+ie3(b#|K$d(Kt>zKE=bagOkssun z@T#5^_LfsRPjP8m-f1Pi@}d;PmZ3_{U3p)@ctz~tn?(@Aidg*-SlH9(b!j3Bzf?Pp zB@=-}wUQ9^my!+z^km=lHvLA>1TQg%2`Xh@^}gMO&&&8%LwurRn$J zXM@GI+?J=xd^pLgWJ;d7L%XxRtq}A7<`k?uN{(Ha?}|+vlx>E^Vy{dxps$(!Q9Yv9 zQ0~+dxR&tZ@aXx@;2K6Uu1(@MNU}xf6c-)R$$fm_vYjwQs3Yt1t*WCMNo;Uv$`utlhBkDq3 zpf){!MuLFkO!Vk;kIqM8mrElJrgk7l-)D<2kzntfL_w)90>H+!$wTTJQW zKSC7;uS%eQiK8#_#z025ZW@5Sowjxk4j^Le6Gtm3ijmtMPw_Ylqh<9kQaCO<^LEc` zff9GauwzBBI(`2bzQv{Mbn!u76@;=S*M=J&wDD4GpEhhG<9LGUJtee_0rz-<{nez0 zqsG+v0}tVX>EXaic$6v-x{3TSoj-=&_|a8&+8S_V{f6uTJF)v!g#K!p1ZY%nV5H5I zqlGOW&&F)x{e(t3cB4#=*elR&dUh+dBF3CXistq+1^2f6iP?#3=y&)m=!m^^RQPM! z;(D=VTjt%Rw2~}${h2jNx-m!yMIs@5IMGUqWI@&m-H*0 z54~X>d>#P!apN44$Y(RG)yXU4uBMF6y(7Q!hdPs9QldiZZYG<>gN9_QRk8iAm|LS; zz?_K=VuFPUpGj1|em(js11=8CAg>6jq9<WKmKL0nCimlMVa! zROCLj)nkj8|nbe@1Hj%`y+6(dnMni*g?CkU>1b0D&I5h;$P zgJh{z5q5Xk)PdH!^uP;kU4^k-kZi3}zTUfrfr`6k-lirfNAD9n-!)fTS5T}DCzd;O zuXEYfO|;feDWLZpOU`HXrlOHN-&MWbVGngcg>{9otnIUPOnuVOGqsoueQ`KX<<-7j<=9YA(MOt?7VHC!Y zb1eBQ>@dk$hYWhWn~ikciT)x}a@zAHY-LZr=ol)ogy&*$qP8@9U(vm8b-OO|ST=Wy zBpU6@^O*_})JrNGg;Pl3&Ah}^iN|pfP@Gdi!~+cgN-Pgba;vAX4bKB6;u3Q)5N{O4 z7dofq*NIFjhO-)=8UYiNUMoY9$EKRUBUt%@j$6&t7A$H-kt#NARcpc^!2vfH6INZZ zVE~uUcTx= zJTr^hrY)|u*dgb1P@wxxp|911Js@`#y_>>p5YX_=j1LoK7;etnvze1}Qk`p%+8{`} zVu)n$D|WgYsoB(+0s2@>=i)n~m~j0_=Uj=;))p9An50qf({78#!DTwbtJ!&G7XR`Cw)h~-R&J}$=d zLj#jMlJk2GWH!RbqmB1M{lwYGsI^HCuTSk_`48xXd_Cx|p6oQHO+dE>eZ<@fdN$(Ov^2p-4o1n*WvL)&)y}~FL3G4>+BYpaQ1223HS`;SGmRa*~75d?DwYM=%VXx%!OAp zxY#ZkYFt?2Z_UpsrG!~J8V*e0Xw!=Nwfh$2c`=UU_p!IDAuZM(NGE@(AseJ#=9LQS zUbs6szKT9-qL!MJn>!g*2;th%p0&}WVQr^4B2$hqt}iljZD|NJCp^}6p8BGuUNZd! z-)0Loo*k$q+yDs?o0T?K_#0ZjzCe2?$FNAaOpOav36JcnXk#OfwoK9-klk2&AQ;4c z1D6Yd=rjL!>@jPm`bKJ!x$ma;tdj7Jo~muX)T%PwT!ZDDTk1&5$mqEcLmO7f=7#%@ zP|aG=8@r@poOGKBu0d9@>m<k~g*G z;+ti4^pqnl`RI+jZz+`bP;bTf6U18gn<*7{$Di}tabWkLmdG}Laa zlBFTh21J>0Aydhj{Z2&_qV?z>FXaI5#4SPNts9wo@064M^@Jd~F^+iau?Qv5uX@06 z0zE2JTKTPH^AU0U1Me+Z8Fjp|GIZRI#sj5kTCPkpq{|tqJK|99jwQ`6tXvge>9ov> z6oX?=z513Hl5kHLEXK4zW)GGR=w?sAw`BB6C>8W`YQx-awK<05UCisEPi9LJWqc~> z$KYM3e39#t+#o~z)FXY!J(}P4OHC!|v$qh@dY0BcLo0rr#0Zd~yz8WhHNHr|4`3oV z)xq;C;D8;cX=aV@;1zy;etW6XQQAd|jNl_|Jwsp=2bt+PuG`wkjP+qHA_)KqP_3Ge zSm?NKiScYP&$!(C0mZ_;*0^YogxVwJk^ywSc<$E{6BgQ8>u-(;lvsU7nAQQ#C{nqplto8BC9e|* zu+s+ZE~Bi8m*{z@Ga0!ixgfZoSMXJqVAYLz61s{W#qNK!tT4mtUE~Va33)FakOrSnlw#na35!YsV-foY0&}?!=~mM+xDCq@v0X79??;AZJ|o*W8DxS z{qvI(L3Wi9)(1O7a9UDe-Z(q&Jf3V(DHeyrmd=5V>G>%vaq2N)qGN<-mGP@Y5_CGr zOq$*Xo5v#YM76$ejJh|u*ZWwZcS{@pM#;qIb-PufW@EWXuRIPTO=8VeWM;T$<(?JF zE=nKR6uya&iz}>y`#sXZRGGI`h41H4&TJ$tlsp*}YWW>hw9b=&uNddI^i3f8vQnQN zn+RW>b_~zwt?uk!uI;b#fdk+aH3@A=*d8d)zXGqgTD!3hW1|t=)n$F}aAUV#&-d1w zE?(|6y^mJ20gC}taZu+Di`ORDzKi2!X^s%`xtEM#Do~W{nGDA=f!+qY2P%+E%-iGP zr!2+H#{#GJ5UVprT-lLmBL1ch(JSTr!UMEVN9H|O3 zF1?*?Gy@|L$v(Nu%y=solym5#FOY#19OS$?Ge@;(vG{{MX7!NJ4?(Lgsn+Akf?iJ$ zUZN*%D$H~rQ;|x{%K9SU$-8=?q9o!=qUfIMB6MAdX@&D>J#60^D+dCjj3CW>0Xu4e z6O|jK@yXe4=@fsAJFM;=L{ER}IfmAp>!tTSK_PoBIVi!TbOkfN6}TI8)Iao;PGXv( z=i*g#i{y<|B{yAz7H_F(0fdFagbzkJ1VhV{(n<&U{>>{rDx0DT%r5?*H&$d=&#d#VRR)a|3biLUrh|JVO+B z!3LK&Fl&Feb0T-w>)e7Lx|b0}ah`D-ESqv71FpUZMO+QK#eC1+s;(NpYCfI4SCz8& z)YKeRJn5V>Fb{RlfhfeB-Fc^R!<(I(5P^{@Kw@ViJ4cwKCQHW#k}F$+?0sE#c6YY$V?k?3=O0qojwLxu%Ek4`n&UpQAK}&PhwSMf)@j6g*>g4kYD7kO;*2 zhM>wI%i;B6M_Ok^w7{@hvT1F;oXVuN_!=36@v?_-wSE@T;S^J@fWn|E6jvExDt`(~ z^G;+KTX3o1hfqwfcsN5S6 ztLs+hJk5)mR|weeLAUy|K{*WJS>t69Zta&m?SHk-#H_L}M z2m+!)3Kbsh38kv}F$Tp0=cbnB8~~Q~3~hC71!VtsO^ai0W<}G}cO_O&%)z8zAiioV zTsO~JIWc$u(xbgg+xaTmTVhoOmUzW>@OVnFqk8nPx5Gy{;+*PvNO`wba#ZzVqN-R|qhdw`;rG$NTe}ON->(E9T-M z{4N7?#)UhgdQh!^jjP4f$qe?nRn)3ZlCm=MDJnp`dGIQb?ytcu$Z)Yy>{Ae>>sz|y z$cl-9m3;OZFHik=WP$lbeKN{t5#)wCoj(a>=M=7xI5x2)zyCHEm5hN4b? z#imGiT99PLsRydlvp5wMp0vC^M!QkKAQFfj6DDW4PJUO_*=ru4 z+*qzl`vL~rO`{%s=B4{=JeX5J}-GhQKbkC@eVA0ICc zdI*n=bg*a#nfxO$SD@^TT;zSx`2kSc_qREtcGm2ID22>bSmGIiGVp4mC=tCf&W-#L zWFWQ?9tNUO->KpYC~@9mjAriRha;Emo|7;f;WTN)YaQ(cfe!J9p9p#*7XW#z7c=<}OBVgF*54t|W@ zY?dw&n!%MFU4wLoHyFYd59vjQ;J%Ggk}gfl%rXFnjV`{bI;3c6_h`b-rH0l+sY^k+ zD?Um5IwICm4C-`L=FDH=Do}T?5s5*+9m;~wmXvvSU194xo(flLv#f?9Q5~ybf(N73 zz-C@;N8_NCPDGUg%}Z%>b$m0qxEoT+o8ET@;Nc(RIofkj*Q}YIT&Y;Rg%dy|$grUd z1m2}@jlr!26yY04$`Q_r2NYL{=i8>fvlfQqj}ggw8+sAqKqx9|gfL2nY!2;PQc!D9 zLuOv`+G!4Fr3Mq-fmFOC7pP1d&E~APx^(4j`x2zxL(x!>2SR(<5Qs??33C%c4f_Z? zFvnsx&*WFrkA(}FA%1Vg{mU9g8aqD@9l&#@;YCDyOWg8T#ymbY6(B^Zi7TGRpLYT! zKRGDIG!gMi1*U{|}5wPVA|lCq#@<8->oLQ|P20=jEanDq8%S+NJqY!7Yo0%$s% z3hZpm!Xpgg)iucR!9xm1XNu5Zz=6e`ueRP;S8Z#PVsFZKpUK+ybs&^nit6Gpp5n_I z%#QT=@9P4mksArF%5dSyc?nT5?U<4Tm7%(jRvOb)W5Y$__j2AHvzYO9Xa(Wjya#cAAI?*UsJ+h3mlXWVh*nat8VVvOuy1+hZaAnGft-bDSNBxUkEq{}NmEmS zaDx{gL>CSL=2jCDDBd=n^MeqwbwIx{$V?{;My1wk6vML2a*NH$%cZNpZ|yDZHC)kq zoFN)?=8~Wq#snQpIph7t(fieh#*e#!#!-<)gn9)omK+++7nK$E4ZhdIn=^W9-aw70 z9Y179`s%zyd*rwB^XvRubfc@@84O%1E#xRv>DgJ_%O0z2O#u;3i#HyjNHj!u*Y72`!j}N@qS};ZvaG9w zxs;*R9dVhUhXlZhdB z5>+?@2Ef%=CJtC`OaD3)(f9>FN;IU4NItBcvzM3Woh3iSYOe|eV00nv6X<`+y}r~S zg`@Erba}39`iS#V02UL#%Fz0^BCr3hKl)OG^rwQc2ZMN!el|$GCs(NNN9id{5P8cZ zh&l|8LA2VpcsT-?j>@Ywb;=2SQLB?DS07C$uOD)#n{lKC8LWcTOC!>%?u;*dMR2Re=AI{5sH7c$0Yj z*zfsU@8{yNNZ(0LrEl$Mnj5{w}j2SSrfCu+O9Ii?yraa&6IkR*fW4Zrll-b0RlzZ~uix6WF02*b4nI z>opJuh_-K8`}7LNG37O^2i!Y=$aei>kbCfS-;DO>5}C*3*D&|6j{sg$H^w3jN1hMD z3oOp23A^n2mm7c##j)bKAt?=ecfDXapJ;q;{WJ26J=5PgTs zn3y{t?4%fzj^5mqSnQ9t&b5BCoPJ+m*xZS=HQZid$2ooIGu-a^!p8%m6-fJ;+`sv7 z`v$GNc7c8eB;78549x+??Wf&dw!(aT7uVKCcGc41)g5l1;FNTD@|}rZ7$KU}C%#nT zeJPy_^}UHq4gT$47ys>F`a0eKTHn>meX(}&rt=xcGfez*!}uP`LRZhw!ok|y(CUZc z#D8LRER=^u)Y9DAfwBCn`HThf^lP=*{B!@2x|`?l$>GcFBHlO8|MyWCY$T5&h{#nG6r62 zayI&xA~u3Lq>VCW?fI6HH|BaN-+e+qIS9FS67*=oZ`FLgT>9Qxxx0>hZ65jM@$R{D_RGr~$KpqNbt49= zf6znyv#$REC6wy!KgZZAFm1A<21sqkg+eDB9UoGAW_puK~gsg?2nsU!cj693i5Kj87b zC%^Cr$GO@9e>M`@bNj&+>`hEs!T6Q6*6vO}S;6@N0!_vgyDe`fyg6-V`3r~iQ7&+(av zPjlhr494@^-hAJay}pT|rS2cb|I4`iJRi{c_%VBmkokO`Y!|h<-(2bH>tl8TPuQe|JUWGz99fGG5F_?KM!xdN=*J2 zTQ~g;IQ?(nFO$Dtf$IYR8$E+xrlbKX3II@bg1phaf0>P6(wTZKtD zU!^_{4ZhbyBIxpBX!izrM-PP$LHlSFP&tvQbl+_=BlewEC7-$TniY^Qz&^XKn|H%ci_LqUj|+phY+hzU zUgla)*UMMdQ>r~Tm9AV5lWj}WY){wI!+RYh1GsJJ^F}R4Dch5cUW42?n!VO7j|2(U zrMHr;15I0Idq?|0_n*)fxm0?so8Pr~Y}~GEFlV^VUUPFdX$>kRl?|73U!OOWgmHQH zE`+BTOT-Y0{`|A?G_EAHx$fO$yKF4|^Ow)NduY|t-JZ9>H(*?OUjFytgniq(Jq=$? zsW67oi+T%RdS#~9A|Y|!{FY~tQ+L!7_0usM@|4z9Xq=-zeM|_~b1KM`O_Kc6=Nlb~ zwx#yT13gte-zo~8_=BM5Nr)+N6s#wfoE^ zi8wW2(ZhN2le_$Dvrj7VJEe``5Ry0>Mk#4E?{;eatgq98`08K8S6x-=@sMfp{_!^>i&5G^si&t zb%|Mr1q&^|n@agrpZ>{ADhKNqF?PT$>6h~>`aV~xKVociaZJ%Xoyf}!;=gBT{|`r< zpY8cqgN#E;eC~ht1VW8^yx(RnfHC@ih{b=V89Dy++lBG(xh7B_6~X7r^?$#>o-d4l z&tFjgc9kxnDW-t>-zk8Xe8sN;VEzN}+j_`9gn3C1{#%IWH!lmy|B~Z(7z;;zLo37I z(Oyyqe@Qd2ePwT`O`OvB}}21p_rSngbfOIs``x(&gli4m3a0;*Oe~>(i~@<lbUy&xtS{BX5B37ph*s8< z<;4)DFA2`)g~Goyk)7?orTvA8^mW>yzVql8V2BAl&F6(%fS2|cwzsnTj~adfEF~xT z^rP+2-9|UapD`K!8rQ+p^xp#iLcMoSPfs|Y;5wjsT(~FzdQ_l+Pdx2#24XZcXlOLF zr*wq0G|BX|r?iCMFKN8cnzJqdmwfK}~{pu~l4h`mw+Y^U)R3=XV zD3%hQnzGi9`a$u`tcQ9Q?qw9dWW|3q=IjlPEe&7p4>2~h`a3OgKWoW%^t(LXixyP- zf-!2JJ2-f5FAM*F)rt1+iOfII#ET)6pI0fbV5G4G(7d7HjToos$LaM#m;r1b2>`)^ z03m0RPD5F{=+ER%2SSkt8%{$n`sG4H=+Dj)ht8pAL(arQW8_uG?ZiUqukFNQ<;bkf9~R!iK^nkR6ai?8NCqy{n^rGNY-$RY_6R)RGd_l2FTm!zC%izUoL0O48D= z_K8u5`=fQ4DXmntt2|G$Bs7cKv#-0y*D|B1veC(N&fEH_*Z008~lz|W_X->vqH z_^j!o=U>k^rP%8l8`{4}`y1jfLeclOdqMp1ZnQuA;02M|3EyWlfTWS=r1wo z7Ma_Ng}Q>&9&?qTFBtcQIIio=SVUcqOfStKOLqr z=1IfLE@+s9ud+tAO5r{2b7DC(uo$bQvlUzN6o`hdND|psDGnQ9KQ_On3RZ3nEM1wD z@r-2r$dee$rQPSy5sG=-%ZeFAkZd!6Lq^DSU}S0`3n%pgl&^3%NwO+pDtF67^01^t>5Obk=3SiAJRbyQePz+DDGYd^tkUy5FAWkEpphxl+LspQF z30Y;~g8hnST+dF{LL6t2P~0{0`J?jxOt>c`W_=GT$Kb}n*F#BR@IyC1{CY%5{{0$J z%A6HAmW1&C67UjI$}eK|SP{ba_a*nLAtM3OkWu3}n_bk0Rhjh+etz5;yBsB$nzAjx zrU~pefR(#8f3D9!>eE{emeps5AlFW+@p;I~tj(8D-3PX6LkSCa5J4Urw}NkQB-nCA z{CRnurO7`k@x_3(;j`05mK>YAqTgRR1LsmB)sK~DX9as1Le zP2u~cSNqGhDUSbd9KSSCZTReqBL3^|(fWLN=TAh2`NOs*;@?H^+2pjTU|$ni-t?PQ rj9Jv>OmX;5*WE(ocz-G!;2jE{dWW@T=7CydofY}6N`rsOuR5K30{PeW literal 0 HcmV?d00001 diff --git a/community/neo4j/src/test/java/upgrade/StoreUpgradeOnStartupTest.java b/community/neo4j/src/test/java/upgrade/StoreUpgradeOnStartupTest.java index 02624ce9596a..a4f387fdce73 100644 --- a/community/neo4j/src/test/java/upgrade/StoreUpgradeOnStartupTest.java +++ b/community/neo4j/src/test/java/upgrade/StoreUpgradeOnStartupTest.java @@ -45,10 +45,12 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.test.PageCacheRule; import org.neo4j.test.TargetDirectory; import org.neo4j.test.TestGraphDatabaseFactory; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -57,6 +59,7 @@ import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.allStoreFilesHaveNoTrailer; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.checkNeoStoreHasLatestVersion; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.prepareSampleLegacyDatabase; +import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.removeCheckPointFromTxLog; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.truncateFile; @Ignore @@ -67,7 +70,7 @@ public class StoreUpgradeOnStartupTest public TargetDirectory.TestDirectory testDir = TargetDirectory.testDirForTest( getClass() ); @Rule public PageCacheRule pageCacheRule = new PageCacheRule(); - @Parameterized.Parameter(0) + @Parameterized.Parameter( 0 ) public String version; private final FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); @@ -81,7 +84,8 @@ public static Collection versions() new Object[]{Legacy19Store.LEGACY_VERSION}, new Object[]{Legacy20Store.LEGACY_VERSION}, new Object[]{Legacy21Store.LEGACY_VERSION}, - new Object[]{Legacy22Store.LEGACY_VERSION} + new Object[]{Legacy22Store.LEGACY_VERSION}, + new Object[]{Legacy23Store.LEGACY_VERSION} ); } @@ -93,8 +97,8 @@ public void setup() throws IOException check = new StoreVersionCheck( pageCache ); File prepareDirectory = testDir.directory( "prepare_" + version ); prepareSampleLegacyDatabase( version, fileSystem, workingDirectory, prepareDirectory ); - assertTrue( allLegacyStoreFilesHaveVersion( fileSystem, workingDirectory, version ) ); - + assertEquals( !Legacy23Store.LEGACY_VERSION.equals( version ), + allLegacyStoreFilesHaveVersion( fileSystem, workingDirectory, version ) ); } @Test @@ -115,8 +119,7 @@ public void shouldUpgradeAutomaticallyOnDatabaseStartup() throws IOException, Co public void shouldAbortOnNonCleanlyShutdown() throws Throwable { // given - File file = new File( workingDirectory, "neostore.propertystore.db.index.keys" ); - truncateFile( fileSystem, file, "StringPropertyStore " + version ); + makeDbNotCleanlyShutdown(); try { // when @@ -127,7 +130,21 @@ public void shouldAbortOnNonCleanlyShutdown() throws Throwable catch ( RuntimeException e ) { // then - assertThat( Exceptions.rootCause( e ), Matchers.instanceOf( StoreUpgrader.UnableToUpgradeException.class ) ); + assertThat( Exceptions.rootCause( e ), + Matchers.instanceOf( StoreUpgrader.UnableToUpgradeException.class ) ); + } + } + + private void makeDbNotCleanlyShutdown() throws IOException + { + if ( Legacy23Store.LEGACY_VERSION.equals( version ) ) + { + removeCheckPointFromTxLog( fileSystem, workingDirectory ); + } + else + { + File file = new File( workingDirectory, "neostore.propertystore.db.index.keys" ); + truncateFile( fileSystem, file, "StringPropertyStore " + version ); } } diff --git a/community/neo4j/src/test/java/upgrade/StoreUpgraderInterruptionTestIT.java b/community/neo4j/src/test/java/upgrade/StoreUpgraderInterruptionTestIT.java index 062059c37b3e..9b46e05124ee 100644 --- a/community/neo4j/src/test/java/upgrade/StoreUpgraderInterruptionTestIT.java +++ b/community/neo4j/src/test/java/upgrade/StoreUpgraderInterruptionTestIT.java @@ -50,6 +50,7 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.kernel.impl.storemigration.monitoring.SilentMigrationProgressMonitor; import org.neo4j.logging.NullLogProvider; import org.neo4j.test.PageCacheRule; @@ -80,7 +81,8 @@ public static Collection versions() new Object[]{Legacy19Store.LEGACY_VERSION}, new Object[]{Legacy20Store.LEGACY_VERSION}, new Object[]{Legacy21Store.LEGACY_VERSION}, - new Object[]{Legacy22Store.LEGACY_VERSION} + new Object[]{Legacy22Store.LEGACY_VERSION}, + new Object[]{Legacy23Store.LEGACY_VERSION} ); } @@ -94,7 +96,7 @@ public void shouldSucceedWithUpgradeAfterPreviousAttemptDiedDuringMigration() PageCache pageCache = pageCacheRule.getPageCache( fs ); StoreVersionCheck check = new StoreVersionCheck( pageCache ); UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( check, new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, check, new LegacyStoreVersionCheck( fs ) ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); LogService logService = NullLogService.getInstance(); final Config config = new Config(); @@ -109,7 +111,8 @@ public void migrate( File sourceStoreDir, File targetStoreDir, SchemaIndexProvid } }; - assertTrue( allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); + assertEquals( !Legacy23Store.LEGACY_VERSION.equals( version ), + allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); try { @@ -122,7 +125,8 @@ public void migrate( File sourceStoreDir, File targetStoreDir, SchemaIndexProvid assertEquals( "This upgrade is failing", e.getMessage() ); } - assertTrue( allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); + assertEquals( !Legacy23Store.LEGACY_VERSION.equals( version ), + allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); progressMonitor = new SilentMigrationProgressMonitor(); StoreMigrator migrator = new StoreMigrator( progressMonitor, fs, pageCache, config, logService ); @@ -144,7 +148,7 @@ public void shouldSucceedWithUpgradeAfterPreviousAttemptDiedDuringMovingFiles() PageCache pageCache = pageCacheRule.getPageCache( fs ); StoreVersionCheck check = new StoreVersionCheck( pageCache ); UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( check, new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, check, new LegacyStoreVersionCheck( fs ) ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); LogService logService = NullLogService.getInstance(); final Config config = new Config(); @@ -158,7 +162,8 @@ public void moveMigratedFiles( File migrationDir, File storeDir, String versionT } }; - assertTrue( allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); + assertEquals( !Legacy23Store.LEGACY_VERSION.equals( version ), + allLegacyStoreFilesHaveVersion( fs, workingDirectory, version ) ); try { diff --git a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java index 9cc7f473b362..7e71ea366c98 100644 --- a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java +++ b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java @@ -19,6 +19,7 @@ */ package upgrade; +import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -60,12 +61,14 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v20.Legacy20Store; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; import org.neo4j.kernel.impl.storemigration.legacystore.v22.Legacy22Store; +import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.kernel.impl.storemigration.monitoring.SilentMigrationProgressMonitor; import org.neo4j.logging.NullLogProvider; import org.neo4j.test.PageCacheRule; import org.neo4j.test.TargetDirectory; import org.neo4j.test.TargetDirectory.TestDirectory; +import static java.util.concurrent.TimeUnit.MINUTES; import static org.hamcrest.Matchers.emptyCollectionOf; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -81,9 +84,6 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; - -import static java.util.concurrent.TimeUnit.MINUTES; - import static org.neo4j.consistency.store.StoreAssertions.assertConsistentStore; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.allLegacyStoreFilesHaveVersion; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.allStoreFilesHaveNoTrailer; @@ -92,11 +92,13 @@ import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.containsAnyStoreFiles; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.isolatedMigrationDirectoryOf; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.prepareSampleLegacyDatabase; +import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.removeCheckPointFromTxLog; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.truncateAllFiles; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.truncateFile; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.verifyFilesHaveSameContent; import static org.neo4j.kernel.impl.storemigration.UpgradeConfiguration.ALLOW_UPGRADE; + @Ignore @RunWith(Parameterized.class) public class StoreUpgraderTest @@ -109,14 +111,15 @@ public StoreUpgraderTest( String version ) this.version = version; } - @Parameterized.Parameters(name = "{0}") + @Parameterized.Parameters( name = "{0}" ) public static Collection versions() { return Arrays.asList( new Object[]{Legacy19Store.LEGACY_VERSION}, new Object[]{Legacy20Store.LEGACY_VERSION}, new Object[]{Legacy21Store.LEGACY_VERSION}, - new Object[]{Legacy22Store.LEGACY_VERSION} + new Object[]{Legacy22Store.LEGACY_VERSION}, + new Object[]{Legacy23Store.LEGACY_VERSION} ); } @@ -124,7 +127,7 @@ public static Collection versions() public void prepareDb() throws IOException { dbDirectory = directory.directory( "db_" + version ); - File prepareDirectory = directory.directory("prepare_" + version); + File prepareDirectory = directory.directory( "prepare_" + version ); prepareSampleLegacyDatabase( version, fileSystem, dbDirectory, prepareDirectory ); } @@ -133,9 +136,10 @@ public void shouldUpgradeAnOldFormatStore() throws IOException, ConsistencyCheck { // Given PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); - assertTrue( allLegacyStoreFilesHaveVersion( fileSystem, dbDirectory, version ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + assertEquals( !Legacy23Store.LEGACY_VERSION.equals( version ), + allLegacyStoreFilesHaveVersion( fileSystem, dbDirectory, version ) ); // When newUpgrader( ALLOW_UPGRADE, pageCache ).migrateIfNeeded( dbDirectory, upgradableDatabase, schemaIndexProvider ); @@ -162,8 +166,8 @@ public void checkConfigurationAllowsAutomaticUpgrade() throw new UpgradeNotAllowedByConfigurationException( "vetoed" ); } }; - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); try { @@ -181,15 +185,17 @@ public void checkConfigurationAllowsAutomaticUpgrade() public void shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound() throws IOException, ConsistencyCheckIncompleteException { + Assume.assumeFalse( Legacy23Store.LEGACY_VERSION.equals( version ) ); + File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() - + "shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound-comparison" ); + + "shouldLeaveAllFilesUntouchedIfWrongVersionNumberFound-comparison" ); changeVersionNumber( fileSystem, new File( dbDirectory, "neostore.nodestore.db" ), "v0.9.5" ); fileSystem.deleteRecursively( comparisonDirectory ); fileSystem.copyRecursively( dbDirectory, comparisonDirectory ); PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); try { @@ -210,15 +216,13 @@ public void shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly() throws IOException, ConsistencyCheckIncompleteException { File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() - + "shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly-comparison" ); - - truncateFile( fileSystem, new File( dbDirectory, "neostore.propertystore.db.index.keys" ), - "StringPropertyStore v0.9.9" ); + + "shouldRefuseToUpgradeIfAnyOfTheStoresWeNotShutDownCleanly-comparison" ); + makeDbNotCleanlyShutdown( false ); fileSystem.deleteRecursively( comparisonDirectory ); fileSystem.copyRecursively( dbDirectory, comparisonDirectory ); PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); try { @@ -239,14 +243,13 @@ public void shouldRefuseToUpgradeIfAllOfTheStoresWereNotShutDownCleanly() throws IOException, ConsistencyCheckIncompleteException { File comparisonDirectory = new File( "target/" + StoreUpgraderTest.class.getSimpleName() - + "shouldRefuseToUpgradeIfAllOfTheStoresWeNotShutDownCleanly-comparison" ); - - truncateAllFiles( fileSystem, dbDirectory, version ); + + "shouldRefuseToUpgradeIfAllOfTheStoresWeNotShutDownCleanly-comparison" ); + makeDbNotCleanlyShutdown( true ); fileSystem.deleteRecursively( comparisonDirectory ); fileSystem.copyRecursively( dbDirectory, comparisonDirectory ); PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); try { @@ -266,8 +269,8 @@ public void shouldRefuseToUpgradeIfAllOfTheStoresWereNotShutDownCleanly() public void shouldContinueMovingFilesIfUpgradeCancelledWhileMoving() throws Exception { PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); String versionToMigrateFrom = upgradableDatabase.checkUpgradeable( dbDirectory ); @@ -315,8 +318,8 @@ public void upgradedNeoStoreShouldHaveNewUpgradeTimeAndUpgradeId() throws Except // Given fileSystem.deleteFile( new File( dbDirectory, StoreLogService.INTERNAL_LOG_NAME ) ); PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); // When newUpgrader( ALLOW_UPGRADE, pageCache ).migrateIfNeeded( dbDirectory, upgradableDatabase, schemaIndexProvider ); @@ -327,8 +330,9 @@ public void upgradedNeoStoreShouldHaveNewUpgradeTimeAndUpgradeId() throws Except NeoStores neoStores = storeFactory.openAllNeoStores(); assertThat( neoStores.getMetaDataStore().getUpgradeTransaction(), - equalTo( neoStores.getMetaDataStore() .getLastCommittedTransaction() ) ); - assertThat( neoStores.getMetaDataStore().getUpgradeTime(), not( equalTo( MetaDataStore.FIELD_NOT_INITIALIZED ) ) ); + equalTo( neoStores.getMetaDataStore().getLastCommittedTransaction() ) ); + assertThat( neoStores.getMetaDataStore().getUpgradeTime(), + not( equalTo( MetaDataStore.FIELD_NOT_INITIALIZED ) ) ); long minuteAgo = System.currentTimeMillis() - MINUTES.toMillis( 1 ); assertThat( neoStores.getMetaDataStore().getUpgradeTime(), greaterThan( minuteAgo ) ); @@ -341,8 +345,8 @@ public void upgradeShouldNotLeaveLeftoverAndMigrationDirs() throws Exception // Given fileSystem.deleteFile( new File( dbDirectory, StoreLogService.INTERNAL_LOG_NAME ) ); PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); // When newUpgrader( ALLOW_UPGRADE, pageCache ).migrateIfNeeded( dbDirectory, upgradableDatabase, schemaIndexProvider ); @@ -364,12 +368,12 @@ public void upgraderShouldCleanupLegacyLeftoverAndMigrationDirs() throws Excepti PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); // When - UpgradableDatabase upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); + UpgradableDatabase upgradableDatabase = new UpgradableDatabase( fileSystem, + new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fileSystem ) ); SilentMigrationProgressMonitor progressMonitor = new SilentMigrationProgressMonitor(); NullLogService instance = NullLogService.getInstance(); StoreMigrator migrator = spy( new StoreMigrator( - progressMonitor, fileSystem, pageCache, new Config(), instance ) ); + progressMonitor, fileSystem, pageCache, new Config(), instance ) ); newUpgrader( ALLOW_UPGRADE, migrator, StoreUpgrader.NO_MONITOR ) .migrateIfNeeded( dbDirectory, upgradableDatabase, schemaIndexProvider ); @@ -388,7 +392,8 @@ public void migrate( File storeDir, File migrationDir, SchemaIndexProvider schem } @Override - public void moveMigratedFiles( File migrationDir, File storeDir, String versionToUpgradeFrom ) throws IOException + public void moveMigratedFiles( File migrationDir, File storeDir, String versionToUpgradeFrom ) + throws IOException { throw new IOException( failureMessage ); } @@ -448,11 +453,32 @@ private List migrationHelperDirs() public boolean accept( File file, String name ) { return file.isDirectory() && - (name.equals( StoreUpgrader.MIGRATION_DIRECTORY ) || - name.startsWith( StoreUpgrader.MIGRATION_LEFT_OVERS_DIRECTORY )); + (name.equals( StoreUpgrader.MIGRATION_DIRECTORY ) || + name.startsWith( StoreUpgrader.MIGRATION_LEFT_OVERS_DIRECTORY )); } } ); assertNotNull( "Some IO errors occurred", tmpDirs ); return Arrays.asList( tmpDirs ); } + + private void makeDbNotCleanlyShutdown( boolean truncateAll ) throws IOException + { + if ( Legacy23Store.LEGACY_VERSION.equals( version ) ) + { + removeCheckPointFromTxLog( fileSystem, dbDirectory ); + } + else + { + if ( truncateAll ) + { + truncateAllFiles( fileSystem, dbDirectory, version ); + + } + else + { + File storeFile = new File( dbDirectory, "neostore.propertystore.db.index.keys" ); + truncateFile( fileSystem, storeFile, "StringPropertyStore " + version ); + } + } + } } diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java index 1ba42be36044..fe8c2eed59a7 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java @@ -268,7 +268,7 @@ public void setUp() storeFactory = new StoreFactory( storeDir.directory(), config, new DefaultIdGeneratorFactory( fs ), pageCache, fs, NullLogProvider.getInstance() ); upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); } @After diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java index fc87c689fffd..beeaf1a9f3e7 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java @@ -179,7 +179,7 @@ public void setUp() storeFactory = new StoreFactory( storeDir.directory(), config, new DefaultIdGeneratorFactory( fs ), pageCache, fs, NullLogProvider.getInstance() ); upgradableDatabase = - new UpgradableDatabase( new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); + new UpgradableDatabase( fs, new StoreVersionCheck( pageCache ), new LegacyStoreVersionCheck( fs ) ); } @After diff --git a/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIntegrationTest.java b/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIntegrationTest.java index 26c97c4ea71e..28338a1639e8 100644 --- a/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIntegrationTest.java +++ b/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIntegrationTest.java @@ -59,6 +59,7 @@ import org.neo4j.kernel.impl.AbstractNeo4jTestCase; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.ha.ClusterManager; +import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.store.NeoStores; import org.neo4j.kernel.impl.store.counts.CountsTracker; import org.neo4j.kernel.impl.storemigration.StoreFile; @@ -138,6 +139,19 @@ public class StoreUpgradeIntegrationTest selectivities( 1.0, 1.0, 1.0 ), indexCounts( counts( 0, 38, 38, 38 ), counts( 0, 1, 1, 1 ), counts( 0, 133, 133, 133 ) ) )} ); + private static final List STORES23 = Arrays.asList( + new Store[]{new Store( "0.A.6-empty.zip", + 0 /* node count */, + 1 /* last txId */, + selectivities(), + indexCounts() + )}, + new Store[]{new Store( "0.A.6-data.zip", + 174 /* node count */, + 30 /* last txId */, + selectivities( 1.0, 1.0, 1.0 ), + indexCounts( counts( 0, 38, 38, 38 ), counts( 0, 1, 1, 1 ), counts( 0, 133, 133, 133 ) ) + )} ); @RunWith( Parameterized.class ) public static class StoreUpgradeTest @@ -148,7 +162,7 @@ public static class StoreUpgradeTest @Parameterized.Parameters( name = "{0}" ) public static Collection stores() { - return IteratorUtil.asCollection( Iterables.concat( STORES19, STORES20, STORES21, STORES22 ) ); + return IteratorUtil.asCollection( Iterables.concat( STORES19, STORES20, STORES21, STORES22, STORES23 ) ); } @Rule @@ -289,7 +303,7 @@ public void migratingFromANotCleanlyShutdownStoreShouldNotStartAndFail() throws { assertTrue( ex.getCause() instanceof LifecycleException ); Throwable realException = ex.getCause().getCause(); - assertTrue( Exceptions.contains( realException, StoreFile.NODE_STORE.storeFileName(), + assertTrue( Exceptions.contains( realException, MetaDataStore.DEFAULT_NAME, StoreUpgrader.UnexpectedUpgradingStoreVersionException.class ) ); } } @@ -304,7 +318,7 @@ public static class StoreUpgrade22Test @Parameterized.Parameters( name = "{0}" ) public static Collection stores() { - return IteratorUtil.asCollection( Iterables.concat( STORES21, STORES22 ) ); + return IteratorUtil.asCollection( Iterables.concat( STORES21, STORES22, STORES23 ) ); } @Rule diff --git a/integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-data.zip b/integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-data.zip new file mode 100644 index 0000000000000000000000000000000000000000..5765e57b415600433dd555ea3f4abcb4c9bfd966 GIT binary patch literal 85737 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 W>4KCrTz5Ky-$HE`OKl2VGyETu-Q%nP literal 0 HcmV?d00001 diff --git a/integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-empty.zip b/integrationtests/src/test/resources/org/neo4j/storeupgrade/0.A.6-empty.zip new file mode 100644 index 0000000000000000000000000000000000000000..f842e82a1533a39f0908f56522b8dad6be60f673 GIT binary patch literal 29966 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