Store repository id in git config for each repository

This is needed after migration from v1 to v2 and is done in
GitV1UpdateStep.java. Therefore we hat to make the 'forAllPaths' method
in PathBasedRepositoryLocationResolver available in the interface of
RepositoryLocationResolver.
This commit is contained in:
René Pfeuffer
2019-07-03 07:48:06 +02:00
parent 8f7ca34fa2
commit c35363b79f
14 changed files with 158 additions and 52 deletions

View File

@@ -5,19 +5,21 @@ import org.slf4j.LoggerFactory;
import sonia.scm.ContextEntry;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository;
import sonia.scm.store.StoreConstants;
import sonia.scm.update.UpdateStepRepositoryMetadataAccess;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.nio.file.Path;
class MetadataStore {
public class MetadataStore implements UpdateStepRepositoryMetadataAccess<Path> {
private static final Logger LOG = LoggerFactory.getLogger(MetadataStore.class);
private final JAXBContext jaxbContext;
MetadataStore() {
public MetadataStore() {
try {
jaxbContext = JAXBContext.newInstance(Repository.class);
} catch (JAXBException ex) {
@@ -25,10 +27,10 @@ class MetadataStore {
}
}
Repository read(Path path) {
public Repository read(Path path) {
LOG.trace("read repository metadata from {}", path);
try {
return (Repository) jaxbContext.createUnmarshaller().unmarshal(path.toFile());
return (Repository) jaxbContext.createUnmarshaller().unmarshal(resolveDataPath(path).toFile());
} catch (JAXBException ex) {
throw new InternalRepositoryException(
ContextEntry.ContextBuilder.entity(Path.class, path.toString()).build(), "failed read repository metadata", ex
@@ -41,10 +43,13 @@ class MetadataStore {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(repository, path.toFile());
marshaller.marshal(repository, resolveDataPath(path).toFile());
} catch (JAXBException ex) {
throw new InternalRepositoryException(repository, "failed write repository metadata", ex);
}
}
private Path resolveDataPath(Path repositoryPath) {
return repositoryPath.resolve(StoreConstants.REPOSITORY_METADATA.concat(StoreConstants.FILE_EXTENSION));
}
}

View File

@@ -94,6 +94,11 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation
PathBasedRepositoryLocationResolver.this.setLocation(repositoryId, ((Path) location).toAbsolutePath());
}
}
@Override
public void forAllLocations(BiConsumer<String, T> consumer) {
pathById.forEach((id, path) -> consumer.accept(id, (T) contextProvider.resolve(path)));
}
};
}
@@ -115,10 +120,6 @@ public class PathBasedRepositoryLocationResolver extends BasicRepositoryLocation
return contextProvider.resolve(removedPath);
}
void forAllPaths(BiConsumer<String, Path> consumer) {
pathById.forEach((id, path) -> consumer.accept(id, contextProvider.resolve(path)));
}
void updateModificationDate() {
this.writePathDatabase();
}

View File

@@ -1,5 +1,7 @@
package sonia.scm.repository.xml;
import sonia.scm.repository.RepositoryLocationResolver;
import javax.inject.Inject;
import java.nio.file.Path;
import java.util.function.BiConsumer;
@@ -7,9 +9,9 @@ import java.util.function.BiConsumer;
public class SingleRepositoryUpdateProcessor {
@Inject
private PathBasedRepositoryLocationResolver locationResolver;
private RepositoryLocationResolver locationResolver;
public void doUpdate(BiConsumer<String, Path> forEachRepository) {
locationResolver.forAllPaths(forEachRepository);
locationResolver.forClass(Path.class).forAllLocations(forEachRepository);
}
}

View File

@@ -40,7 +40,7 @@ import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryDAO;
import sonia.scm.store.StoreConstants;
import sonia.scm.repository.RepositoryLocationResolver;
import javax.inject.Inject;
import java.io.IOException;
@@ -76,18 +76,14 @@ public class XmlRepositoryDAO implements RepositoryDAO {
}
private void init() {
repositoryLocationResolver.forAllPaths((repositoryId, repositoryPath) -> {
Path metadataPath = resolveDataPath(repositoryPath);
Repository repository = metadataStore.read(metadataPath);
RepositoryLocationResolver.RepositoryLocationResolverInstance<Path> pathRepositoryLocationResolverInstance = repositoryLocationResolver.create(Path.class);
pathRepositoryLocationResolverInstance.forAllLocations((repositoryId, repositoryPath) -> {
Repository repository = metadataStore.read(repositoryPath);
byNamespaceAndName.put(repository.getNamespaceAndName(), repository);
byId.put(repositoryId, repository);
});
}
private Path resolveDataPath(Path repositoryPath) {
return repositoryPath.resolve(StoreConstants.REPOSITORY_METADATA.concat(StoreConstants.FILE_EXTENSION));
}
@Override
public String getType() {
return "xml";
@@ -108,8 +104,7 @@ public class XmlRepositoryDAO implements RepositoryDAO {
Path repositoryPath = (Path) location;
try {
Path metadataPath = resolveDataPath(repositoryPath);
metadataStore.write(metadataPath, repository);
metadataStore.write(repositoryPath, repository);
} catch (Exception e) {
repositoryLocationResolver.remove(repository.getId());
throw new InternalRepositoryException(repository, "failed to create filesystem", e);
@@ -166,9 +161,8 @@ public class XmlRepositoryDAO implements RepositoryDAO {
Path repositoryPath = repositoryLocationResolver
.create(Path.class)
.getLocation(repository.getId());
Path metadataPath = resolveDataPath(repositoryPath);
repositoryLocationResolver.updateModificationDate();
metadataStore.write(metadataPath, clone);
metadataStore.write(repositoryPath, clone);
}
@Override

View File

@@ -120,7 +120,7 @@ class PathBasedRepositoryLocationResolverTest {
@Test
void shouldInitWithExistingData() {
Map<String, Path> foundRepositories = new HashMap<>();
resolverWithExistingData.forAllPaths(
resolverWithExistingData.forClass(Path.class).forAllLocations(
foundRepositories::put
);
assertThat(foundRepositories)

View File

@@ -26,15 +26,13 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -47,6 +45,7 @@ class XmlRepositoryDAOTest {
@Mock
private PathBasedRepositoryLocationResolver locationResolver;
private Consumer<BiConsumer<String, Path>> triggeredOnForAllLocations = none -> {};
private FileSystem fileSystem = new DefaultFileSystem();
@@ -69,6 +68,11 @@ class XmlRepositoryDAOTest {
@Override
public void setLocation(String repositoryId, Path location) {
}
@Override
public void forAllLocations(BiConsumer<String, Path> consumer) {
triggeredOnForAllLocations.accept(consumer);
}
}
);
when(locationResolver.create(anyString())).thenAnswer(invocation -> createMockedRepoPath(basePath, invocation));
@@ -332,11 +336,10 @@ class XmlRepositoryDAOTest {
@Test
void shouldRefreshWithExistingRepositoriesFromPathDatabase() {
// given
doNothing().when(locationResolver).forAllPaths(any());
XmlRepositoryDAO dao = new XmlRepositoryDAO(locationResolver, fileSystem);
mockExistingPath();
XmlRepositoryDAO dao = new XmlRepositoryDAO(locationResolver, fileSystem);
// when
dao.refresh();
@@ -346,12 +349,7 @@ class XmlRepositoryDAOTest {
}
private void mockExistingPath() {
doAnswer(
invocation -> {
((BiConsumer<String, Path>) invocation.getArgument(0)).accept("existing", repositoryPath);
return null;
}
).when(locationResolver).forAllPaths(any());
triggeredOnForAllLocations = consumer -> consumer.accept("existing", repositoryPath);
}
}