Implement inline strategy

This commit is contained in:
René Pfeuffer
2019-05-23 15:06:40 +02:00
parent 3e46aefb4b
commit 31e56a6672
5 changed files with 141 additions and 88 deletions

View File

@@ -0,0 +1,60 @@
package sonia.scm.repository.update;
import sonia.scm.SCMContextProvider;
import sonia.scm.migration.UpdateException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Stream;
abstract class BaseMigrationStrategy implements MigrationStrategy.Instance {
private final SCMContextProvider contextProvider;
BaseMigrationStrategy(SCMContextProvider contextProvider) {
this.contextProvider = contextProvider;
}
Path getSourceDataPath(String name, String type) {
return Arrays.stream(name.split("/"))
.reduce(getTypeDependentPath(type), (path, namePart) -> path.resolve(namePart), (p1, p2) -> p1);
}
Path getTypeDependentPath(String type) {
return contextProvider.getBaseDirectory().toPath().resolve("repositories").resolve(type);
}
Stream<Path> listSourceDirectory(Path sourceDirectory) {
try {
return Files.list(sourceDirectory);
} catch (IOException e) {
throw new UpdateException("could not read original directory", e);
}
}
void createDataDirectory(Path target) {
try {
Files.createDirectories(target);
} catch (IOException e) {
throw new UpdateException("could not create data directory " + target, e);
}
}
void moveFile(Path sourceFile, Path targetFile) {
try {
Files.move(sourceFile, targetFile);
} catch (IOException e) {
throw new UpdateException("could not move data file from " + sourceFile + " to " + targetFile, e);
}
}
void copyFile(Path sourceFile, Path targetFile) {
try {
Files.copy(sourceFile, targetFile);
} catch (IOException e) {
throw new UpdateException("could not copy original file from " + sourceFile + " to " + targetFile, e);
}
}
}

View File

@@ -1,25 +1,20 @@
package sonia.scm.repository.update; package sonia.scm.repository.update;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.migration.UpdateException;
import sonia.scm.repository.AbstractSimpleRepositoryHandler; import sonia.scm.repository.AbstractSimpleRepositoryHandler;
import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.repository.RepositoryLocationResolver;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Stream;
class CopyMigrationStrategy implements MigrationStrategy.Instance { class CopyMigrationStrategy extends BaseMigrationStrategy {
private final SCMContextProvider contextProvider;
private final RepositoryLocationResolver locationResolver; private final RepositoryLocationResolver locationResolver;
@Inject @Inject
public CopyMigrationStrategy(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) { public CopyMigrationStrategy(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) {
this.contextProvider = contextProvider; super(contextProvider);
this.locationResolver = locationResolver; this.locationResolver = locationResolver;
} }
@@ -33,19 +28,9 @@ class CopyMigrationStrategy implements MigrationStrategy.Instance {
return repositoryBasePath; return repositoryBasePath;
} }
private Path getSourceDataPath(String name, String type) {
return Arrays.stream(name.split("/"))
.reduce(getTypeDependentPath(type), (path, namePart) -> path.resolve(namePart), (p1, p2) -> p1);
}
private Path getTypeDependentPath(String type) {
return contextProvider.getBaseDirectory().toPath().resolve("repositories").resolve(type);
}
private void copyData(Path sourceDirectory, Path targetDirectory) { private void copyData(Path sourceDirectory, Path targetDirectory) {
createDataDirectory(targetDirectory); createDataDirectory(targetDirectory);
Stream<Path> list = listSourceDirectory(sourceDirectory); listSourceDirectory(sourceDirectory).forEach(
list.forEach(
sourceFile -> { sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName()); Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) { if (Files.isDirectory(sourceFile)) {
@@ -56,28 +41,4 @@ class CopyMigrationStrategy implements MigrationStrategy.Instance {
} }
); );
} }
private Stream<Path> listSourceDirectory(Path sourceDirectory) {
try {
return Files.list(sourceDirectory);
} catch (IOException e) {
throw new UpdateException("could not read original directory", e);
}
}
private void copyFile(Path sourceFile, Path targetFile) {
try {
Files.copy(sourceFile, targetFile);
} catch (IOException e) {
throw new UpdateException("could not copy original file from " + sourceFile + " to " + targetFile, e);
}
}
private void createDataDirectory(Path target) {
try {
Files.createDirectories(target);
} catch (IOException e) {
throw new UpdateException("could not create data directory " + target, e);
}
}
} }

View File

@@ -1,21 +1,42 @@
package sonia.scm.repository.update; package sonia.scm.repository.update;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.repository.AbstractSimpleRepositoryHandler;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
class InlineMigrationStrategy implements MigrationStrategy.Instance { class InlineMigrationStrategy extends BaseMigrationStrategy {
private final SCMContextProvider contextProvider;
@Inject @Inject
public InlineMigrationStrategy(SCMContextProvider contextProvider) { public InlineMigrationStrategy(SCMContextProvider contextProvider) {
this.contextProvider = contextProvider; super(contextProvider);
} }
@Override @Override
public Path migrate(String id, String name, String type) { public Path migrate(String id, String name, String type) {
return null; Path repositoryBasePath = getSourceDataPath(name, type);
Path targetDataPath = repositoryBasePath
.resolve(AbstractSimpleRepositoryHandler.REPOSITORIES_NATIVE_DIRECTORY);
moveData(repositoryBasePath, targetDataPath);
return repositoryBasePath;
}
private void moveData(Path sourceDirectory, Path targetDirectory) {
createDataDirectory(targetDirectory);
listSourceDirectory(sourceDirectory)
.filter(sourceFile -> !targetDirectory.equals(sourceFile))
.forEach(
sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) {
moveData(sourceFile, targetFile);
} else {
moveFile(sourceFile, targetFile);
}
}
);
} }
} }

View File

@@ -3,7 +3,6 @@ package sonia.scm.repository.update;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.migration.UpdateException;
import sonia.scm.repository.AbstractSimpleRepositoryHandler; import sonia.scm.repository.AbstractSimpleRepositoryHandler;
import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.repository.RepositoryLocationResolver;
@@ -11,22 +10,19 @@ import javax.inject.Inject;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
class MoveMigrationStrategy implements MigrationStrategy.Instance { class MoveMigrationStrategy extends BaseMigrationStrategy {
private static final Logger LOG = LoggerFactory.getLogger(MoveMigrationStrategy.class); private static final Logger LOG = LoggerFactory.getLogger(MoveMigrationStrategy.class);
private final SCMContextProvider contextProvider;
private final RepositoryLocationResolver locationResolver; private final RepositoryLocationResolver locationResolver;
@Inject @Inject
public MoveMigrationStrategy(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) { public MoveMigrationStrategy(SCMContextProvider contextProvider, RepositoryLocationResolver locationResolver) {
this.contextProvider = contextProvider; super(contextProvider);
this.locationResolver = locationResolver; this.locationResolver = locationResolver;
} }
@@ -58,19 +54,9 @@ class MoveMigrationStrategy implements MigrationStrategy.Instance {
} }
} }
private Path getSourceDataPath(String name, String type) {
return Arrays.stream(name.split("/"))
.reduce(getTypeDependentPath(type), (path, namePart) -> path.resolve(namePart), (p1, p2) -> p1);
}
private Path getTypeDependentPath(String type) {
return contextProvider.getBaseDirectory().toPath().resolve("repositories").resolve(type);
}
private void moveData(Path sourceDirectory, Path targetDirectory) { private void moveData(Path sourceDirectory, Path targetDirectory) {
createDataDirectory(targetDirectory); createDataDirectory(targetDirectory);
Stream<Path> list = listSourceDirectory(sourceDirectory); listSourceDirectory(sourceDirectory).forEach(
list.forEach(
sourceFile -> { sourceFile -> {
Path targetFile = targetDirectory.resolve(sourceFile.getFileName()); Path targetFile = targetDirectory.resolve(sourceFile.getFileName());
if (Files.isDirectory(sourceFile)) { if (Files.isDirectory(sourceFile)) {
@@ -86,28 +72,4 @@ class MoveMigrationStrategy implements MigrationStrategy.Instance {
LOG.warn("could not delete source repository directory {}", sourceDirectory); LOG.warn("could not delete source repository directory {}", sourceDirectory);
} }
} }
private Stream<Path> listSourceDirectory(Path sourceDirectory) {
try {
return Files.list(sourceDirectory);
} catch (IOException e) {
throw new UpdateException("could not read original directory", e);
}
}
private void moveFile(Path sourceFile, Path targetFile) {
try {
Files.move(sourceFile, targetFile);
} catch (IOException e) {
throw new UpdateException("could not move data file from " + sourceFile + " to " + targetFile, e);
}
}
private void createDataDirectory(Path target) {
try {
Files.createDirectories(target);
} catch (IOException e) {
throw new UpdateException("could not create data directory " + target, e);
}
}
} }

View File

@@ -0,0 +1,49 @@
package sonia.scm.repository.update;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junitpioneer.jupiter.TempDirectory;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.SCMContextProvider;
import java.io.IOException;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
@ExtendWith(TempDirectory.class)
@ExtendWith(MockitoExtension.class)
class InlineMigrationStrategyTest {
@Mock
SCMContextProvider contextProvider;
@BeforeEach
void mockContextProvider(@TempDirectory.TempDir Path tempDir) {
when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile());
}
@BeforeEach
void createV1Home(@TempDirectory.TempDir Path tempDir) throws IOException {
V1RepositoryFileSystem.createV1Home(tempDir);
}
@Test
void shouldUseExistingDirectory(@TempDirectory.TempDir Path tempDir) {
Path target = new InlineMigrationStrategy(contextProvider).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git");
assertThat(target).isEqualTo(resolveOldDirectory(tempDir));
}
@Test
void shouldMoveDataDirectory(@TempDirectory.TempDir Path tempDir) {
new InlineMigrationStrategy(contextProvider).migrate("b4f-a9f0-49f7-ad1f-37d3aae1c55f", "some/more/directories/than/one", "git");
assertThat(resolveOldDirectory(tempDir).resolve("data")).exists();
}
private Path resolveOldDirectory(Path tempDir) {
return tempDir.resolve("repositories").resolve("git").resolve("some").resolve("more").resolve("directories").resolve("than").resolve("one");
}
}