diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java index bc8df673d0..8c76bdabaa 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java @@ -13,8 +13,9 @@ public abstract class RepositoryLocationResolver { return create(type); } - @FunctionalInterface public interface RepositoryLocationResolverInstance { T getLocation(String repositoryId); + + void setLocation(String repositoryId, T location); } } diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java index a1ce516069..dccdbc197b 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/PathBasedRepositoryLocationResolver.java @@ -7,6 +7,7 @@ import sonia.scm.repository.InternalRepositoryException; import sonia.scm.store.StoreConstants; import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -28,6 +29,7 @@ import static sonia.scm.ContextEntry.ContextBuilder.entity; * * @since 2.0.0 */ +@Singleton public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocationResolver { public static final String STORE_NAME = "repository-paths"; @@ -64,19 +66,26 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation @Override protected RepositoryLocationResolverInstance create(Class type) { - return repositoryId -> { - if (pathById.containsKey(repositoryId)) { - return (T) contextProvider.resolve(pathById.get(repositoryId)); - } else { - return (T) create(repositoryId); + return new RepositoryLocationResolverInstance() { + @Override + public T getLocation(String repositoryId) { + if (pathById.containsKey(repositoryId)) { + return (T) contextProvider.resolve(pathById.get(repositoryId)); + } else { + return (T) create(repositoryId); + } + } + + @Override + public void setLocation(String repositoryId, T location) { + PathBasedRepositoryLocationResolver.this.setLocation(repositoryId, (Path) location); } }; } Path create(String repositoryId) { Path path = initialRepositoryLocationResolver.getPath(repositoryId); - pathById.put(repositoryId, path); - writePathDatabase(); + setLocation(repositoryId, path); Path resolvedPath = contextProvider.resolve(path); try { Files.createDirectories(resolvedPath); @@ -138,4 +147,9 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation .resolve(StoreConstants.CONFIG_DIRECTORY_NAME) .resolve(STORE_NAME.concat(StoreConstants.FILE_EXTENSION)); } + + public void setLocation(String repositoryId, Path repositoryBasePath) { + pathById.put(repositoryId, repositoryBasePath); + writePathDatabase(); + } } diff --git a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java index 5b9a00aec8..36c9db33e2 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java @@ -19,6 +19,7 @@ import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.FileSystem; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.repository.RepositoryPermission; import java.io.IOException; @@ -56,7 +57,18 @@ class XmlRepositoryDAOTest { @BeforeEach void createDAO(@TempDirectory.TempDir Path basePath) { - when(locationResolver.create(Path.class)).thenReturn(locationResolver::create); + when(locationResolver.create(Path.class)).thenReturn( + new RepositoryLocationResolver.RepositoryLocationResolverInstance() { + @Override + public Path getLocation(String repositoryId) { + return locationResolver.create(repositoryId); + } + + @Override + public void setLocation(String repositoryId, Path location) { + } + } + ); when(locationResolver.create(anyString())).thenAnswer(invocation -> createMockedRepoPath(basePath, invocation)); when(locationResolver.remove(anyString())).thenAnswer(invocation -> basePath.resolve(invocation.getArgument(0).toString())); } diff --git a/scm-test/src/main/java/sonia/scm/TempDirRepositoryLocationResolver.java b/scm-test/src/main/java/sonia/scm/TempDirRepositoryLocationResolver.java index 1dfc22e15a..77b09ff707 100644 --- a/scm-test/src/main/java/sonia/scm/TempDirRepositoryLocationResolver.java +++ b/scm-test/src/main/java/sonia/scm/TempDirRepositoryLocationResolver.java @@ -1,7 +1,6 @@ package sonia.scm; import sonia.scm.repository.BasicRepositoryLocationResolver; -import sonia.scm.repository.RepositoryLocationResolver; import java.io.File; import java.nio.file.Path; @@ -16,6 +15,16 @@ public class TempDirRepositoryLocationResolver extends BasicRepositoryLocationRe @Override protected RepositoryLocationResolverInstance create(Class type) { - return repositoryId -> (T) tempDirectory.toPath(); + return new RepositoryLocationResolverInstance() { + @Override + public T getLocation(String repositoryId) { + return (T) tempDirectory.toPath(); + } + + @Override + public void setLocation(String repositoryId, T location) { + throw new UnsupportedOperationException("not implemented for tests"); + } + }; } } diff --git a/scm-webapp/src/main/java/sonia/scm/update/MigrationWizardModule.java b/scm-webapp/src/main/java/sonia/scm/update/MigrationWizardModule.java index 3362496330..f067fa799b 100644 --- a/scm-webapp/src/main/java/sonia/scm/update/MigrationWizardModule.java +++ b/scm-webapp/src/main/java/sonia/scm/update/MigrationWizardModule.java @@ -1,14 +1,20 @@ package sonia.scm.update; import com.google.inject.servlet.ServletModule; -import sonia.scm.update.repository.XmlRepositoryV1UpdateStep; - -import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class MigrationWizardModule extends ServletModule { + private static final Logger LOG = LoggerFactory.getLogger(MigrationWizardModule.class); + @Override protected void configureServlets() { + LOG.info("=========================================================="); + LOG.info("= ="); + LOG.info("= STARTING MIGRATION SERVLET ="); + LOG.info("= ="); + LOG.info("=========================================================="); serve("/*").with(MigrationWizardServlet.class); } } diff --git a/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java index 060ed6704e..89394060f5 100644 --- a/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java @@ -1,5 +1,7 @@ package sonia.scm.update.repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; import sonia.scm.repository.RepositoryDirectoryHandler; import sonia.scm.repository.RepositoryLocationResolver; @@ -10,6 +12,8 @@ import java.nio.file.Path; class CopyMigrationStrategy extends BaseMigrationStrategy { + private static final Logger LOG = LoggerFactory.getLogger(CopyMigrationStrategy.class); + private final RepositoryLocationResolver locationResolver; @Inject @@ -24,6 +28,7 @@ class CopyMigrationStrategy extends BaseMigrationStrategy { Path targetDataPath = repositoryBasePath .resolve(RepositoryDirectoryHandler.REPOSITORIES_NATIVE_DIRECTORY); Path sourceDataPath = getSourceDataPath(name, type); + LOG.info("copying repository data from {} to {}", sourceDataPath, targetDataPath); copyData(sourceDataPath, targetDataPath); return repositoryBasePath; } diff --git a/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java index 62dd67d86a..2f891fff71 100644 --- a/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java @@ -1,7 +1,10 @@ package sonia.scm.update.repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; import sonia.scm.repository.RepositoryDirectoryHandler; +import sonia.scm.repository.RepositoryLocationResolver; import javax.inject.Inject; import java.nio.file.Files; @@ -9,16 +12,23 @@ import java.nio.file.Path; class InlineMigrationStrategy extends BaseMigrationStrategy { + private static final Logger LOG = LoggerFactory.getLogger(InlineMigrationStrategy.class); + + private final RepositoryLocationResolver locationResolver; + @Inject - public InlineMigrationStrategy(SCMContextProvider contextProvider) { + public InlineMigrationStrategy(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) { super(contextProvider); + this.locationResolver = locationResolver; } @Override public Path migrate(String id, String name, String type) { Path repositoryBasePath = getSourceDataPath(name, type); + locationResolver.forClass(Path.class).setLocation(id, repositoryBasePath); Path targetDataPath = repositoryBasePath .resolve(RepositoryDirectoryHandler.REPOSITORIES_NATIVE_DIRECTORY); + LOG.info("moving repository data from {} to {}", repositoryBasePath, targetDataPath); moveData(repositoryBasePath, targetDataPath); return repositoryBasePath; } diff --git a/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java index 08d71dd376..c571b8ad4c 100644 --- a/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java @@ -32,6 +32,7 @@ class MoveMigrationStrategy extends BaseMigrationStrategy { Path targetDataPath = repositoryBasePath .resolve(RepositoryDirectoryHandler.REPOSITORIES_NATIVE_DIRECTORY); Path sourceDataPath = getSourceDataPath(name, type); + LOG.info("moving repository data from {} to {}", sourceDataPath, targetDataPath); moveData(sourceDataPath, targetDataPath); deleteOldDataDir(getTypeDependentPath(type), name); return repositoryBasePath; diff --git a/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java index acb28ca432..b7037d0e05 100644 --- a/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java @@ -157,6 +157,7 @@ public class XmlRepositoryV1UpdateStep implements UpdateStep { private Path handleDataDirectory(V1Repository v1Repository) { MigrationStrategy dataMigrationStrategy = readMigrationStrategy(v1Repository); + LOG.info("using strategy {} to migrate repository {} with id {}", dataMigrationStrategy.getClass(), v1Repository.name, v1Repository.id); return dataMigrationStrategy.from(injector).migrate(v1Repository.id, v1Repository.name, v1Repository.type); } @@ -231,6 +232,10 @@ public class XmlRepositoryV1UpdateStep implements UpdateStep { return name; } + public String getType() { + return type; + } + public String getNewNamespace() { String[] nameParts = getNameParts(name); return nameParts.length > 1 ? nameParts[0] : type; diff --git a/scm-webapp/src/main/resources/templates/repository-migration.mustache b/scm-webapp/src/main/resources/templates/repository-migration.mustache index 641e718136..07447bedbc 100644 --- a/scm-webapp/src/main/resources/templates/repository-migration.mustache +++ b/scm-webapp/src/main/resources/templates/repository-migration.mustache @@ -11,6 +11,7 @@ You have migrated from SCM-Manager v1 to SCM-Manager v2. + @@ -19,6 +20,9 @@ You have migrated from SCM-Manager v1 to SCM-Manager v2. + diff --git a/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java index 6abddae3fb..fa237e78b0 100644 --- a/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java @@ -7,11 +7,14 @@ import org.junitpioneer.jupiter.TempDirectory; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import sonia.scm.SCMContextProvider; +import sonia.scm.repository.RepositoryLocationResolver; +import sonia.scm.repository.xml.PathBasedRepositoryLocationResolver; import java.io.IOException; import java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith(TempDirectory.class) @@ -20,9 +23,14 @@ class InlineMigrationStrategyTest { @Mock SCMContextProvider contextProvider; + @Mock + PathBasedRepositoryLocationResolver locationResolver; + @Mock + RepositoryLocationResolver.RepositoryLocationResolverInstance locationResolverInstance; @BeforeEach void mockContextProvider(@TempDirectory.TempDir Path tempDir) { + when(locationResolver.forClass(Path.class)).thenReturn(locationResolverInstance); when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); } @@ -33,13 +41,14 @@ class InlineMigrationStrategyTest { @Test void shouldUseExistingDirectory(@TempDirectory.TempDir Path tempDir) { - Path target = new InlineMigrationStrategy(contextProvider).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git"); + Path target = new InlineMigrationStrategy(contextProvider, locationResolver).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git"); assertThat(target).isEqualTo(resolveOldDirectory(tempDir)); + verify(locationResolverInstance).setLocation("b4f-a9f0-49f7-ad1f-37d3aae1c55f", target); } @Test void shouldMoveDataDirectory(@TempDirectory.TempDir Path tempDir) { - new InlineMigrationStrategy(contextProvider).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git"); + new InlineMigrationStrategy(contextProvider, locationResolver).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git"); assertThat(resolveOldDirectory(tempDir).resolve("data")).exists(); }
original nametype new namespace/name Strategy
{{name}} + {{type}} + {{newNamespace}}/{{newName}}