From 00ab764dab09b748f9cd39dfac6d6476cc695af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 26 Nov 2018 17:22:17 +0100 Subject: [PATCH] Store repository id in native config file Hooks can read this repository type dependant config file and handle the changes for the correct repository id --- .../sonia/scm/repository/RepositoryDAO.java | 9 --- .../scm/repository/spi/HookEventFacade.java | 9 +++ .../scm/repository/xml/XmlRepositoryDAO.java | 20 ------- .../repository/xml/XmlRepositoryDAOTest.java | 44 --------------- .../jgit/transport/ScmTransportProtocol.java | 55 ++++++++++++++----- .../scm/repository/GitRepositoryHandler.java | 20 +++++-- .../java/sonia/scm/web/GitReceiveHook.java | 44 +++++++-------- .../sonia/scm/web/GitReceivePackFactory.java | 21 +++++-- .../spi/AbstractRemoteCommandTestBase.java | 10 +++- .../scm/repository/HgRepositoryHandler.java | 27 +++++++++ .../spi/HgHookChangesetProvider.java | 10 ++-- .../repository/spi/HgHookContextProvider.java | 7 ++- .../sonia/scm/web/HgHookCallbackServlet.java | 49 +++++++---------- .../scm/web/HgHookCallbackServletTest.java | 4 +- .../scm/repository/SvnRepositoryHandler.java | 31 ++++++++++- .../scm/repository/SvnRepositoryHook.java | 15 +++-- .../repository/SvnRepositoryHandlerTest.java | 4 +- 17 files changed, 204 insertions(+), 175 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryDAO.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryDAO.java index c78a4e9ff6..53a03ab8d2 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryDAO.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryDAO.java @@ -69,13 +69,4 @@ public interface RepositoryDAO extends GenericDAO * @return repository with the specified namespace and name or null */ Repository get(NamespaceAndName namespaceAndName); - - /** - * Returns the repository that is associated with the given path. This path - * may be the root directory of the repository or any other directory or file - * inside the root directory. - * - * @throws {@link sonia.scm.NotFoundException} when there is no repository for the given path. - */ - Repository getRepositoryForDirectory(File path); } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/HookEventFacade.java b/scm-core/src/main/java/sonia/scm/repository/spi/HookEventFacade.java index dc814f079e..27cafd1a16 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/HookEventFacade.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/HookEventFacade.java @@ -73,6 +73,15 @@ public final class HookEventFacade //~--- methods -------------------------------------------------------------- + public HookEventHandler handle(String id) { + Repository repository = repositoryManagerProvider.get().get(id); + if (repository == null) + { + throw notFound(entity("repository", id)); + } + return handle(repository); + } + public HookEventHandler handle(NamespaceAndName namespaceAndName) { Repository repository = repositoryManagerProvider.get().get(namespaceAndName); if (repository == null) diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java index 158c20906f..0ae24a0b93 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryDAO.java @@ -183,26 +183,6 @@ public class XmlRepositoryDAO .orElseThrow(() -> new InternalRepositoryException(repository, "could not find base directory for repository"))); } - @Override - public Repository getRepositoryForDirectory(File path) { - for (RepositoryPath p : db.values()) { - if (toRealPath(path.toPath()).startsWith(toRealPath(context.getBaseDirectory().toPath().resolve(p.getPath())))) { - return p.getRepository(); - } - } - throw new NotFoundException("directory", path.getPath()); - } - - private Path toRealPath(Path path) { - try { - // resolve links and other indirections - // (see issue #82, https://bitbucket.org/sdorra/scm-manager/issues/82/symbolic-link-in-hg-repository-path) - return path.toRealPath(); - } catch (IOException e) { - throw new InternalRepositoryException(entity("directory", path.toString()), "could not get Path$toRealPath for path: " + path); - } - } - private Optional findExistingRepositoryPath(Repository repository) { return db.values().stream() .filter(repoPath -> repoPath.getId().equals(repository.getId())) 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 3e48c237c2..25a4566ed1 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 @@ -106,48 +106,4 @@ public class XmlRepositoryDAOTest { assertThat(path.toString()).isEqualTo("/tmp/path"); } - - @Test - public void shouldFindRepositoryForRelativePath() { - new File(context.getBaseDirectory(), "relative/path/data").mkdirs(); - Repository existingRepository = new Repository("id", "old", null, null); - RepositoryPath repositoryPath = new RepositoryPath("relative/path", "id", existingRepository); - when(db.values()).thenReturn(asList(repositoryPath)); - - XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context); - - Repository repository = dao.getRepositoryForDirectory(new File(context.getBaseDirectory(), "relative/path/data")); - - assertThat(repository).isSameAs(existingRepository); - } - - @Test - public void shouldFindRepositoryForAbsolutePath() throws IOException { - Repository existingRepository = new Repository("id", "old", null, null); - File folder = temporaryFolder.newFolder("somewhere", "data"); - RepositoryPath repositoryPath = new RepositoryPath(folder.getParent(), "id", existingRepository); - when(db.values()).thenReturn(asList(repositoryPath)); - - XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context); - - Repository repository = dao.getRepositoryForDirectory(folder); - - assertThat(repository).isSameAs(existingRepository); - } - - @Test - public void shouldFindRepositoryForLinks() throws IOException { - Repository existingRepository = new Repository("id", "old", null, null); - File folder = temporaryFolder.newFolder("somewhere", "else", "data"); - File link = new File(folder.getParentFile().getParentFile(), "link"); - Files.createSymbolicLink(link.toPath(), folder.getParentFile().toPath()); - RepositoryPath repositoryPath = new RepositoryPath(new File(link, "data").getPath(), "id", existingRepository); - when(db.values()).thenReturn(asList(repositoryPath)); - - XmlRepositoryDAO dao = new XmlRepositoryDAO(storeFactory, new InitialRepositoryLocationResolver(context), fileSystem, context); - - Repository repository = dao.getRepositoryForDirectory(folder); - - assertThat(repository).isSameAs(existingRepository); - } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/org/eclipse/jgit/transport/ScmTransportProtocol.java b/scm-plugins/scm-git-plugin/src/main/java/org/eclipse/jgit/transport/ScmTransportProtocol.java index 24353f0fcc..3481ccd0d1 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/org/eclipse/jgit/transport/ScmTransportProtocol.java +++ b/scm-plugins/scm-git-plugin/src/main/java/org/eclipse/jgit/transport/ScmTransportProtocol.java @@ -38,21 +38,24 @@ package org.eclipse.jgit.transport; import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import com.google.inject.Provider; + import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; -import sonia.scm.repository.RepositoryDAO; + +import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.spi.HookEventFacade; import sonia.scm.web.GitReceiveHook; -import java.io.File; -import java.util.Set; - //~--- JDK imports ------------------------------------------------------------ +import java.io.File; + +import java.util.Set; + /** * * @author Sebastian Sdorra @@ -72,15 +75,24 @@ public class ScmTransportProtocol extends TransportProtocol * Constructs ... * */ -// public ScmTransportProtocol() {} + public ScmTransportProtocol() {} + /** + * Constructs ... + * + * + * + * @param hookEventFacadeProvider + * + * @param repositoryHandlerProvider + */ @Inject public ScmTransportProtocol( Provider hookEventFacadeProvider, - RepositoryDAO repositoryDAO) + Provider repositoryHandlerProvider) { this.hookEventFacadeProvider = hookEventFacadeProvider; - this.repositoryDAO = repositoryDAO; + this.repositoryHandlerProvider = repositoryHandlerProvider; } //~--- methods -------------------------------------------------------------- @@ -138,7 +150,8 @@ public class ScmTransportProtocol extends TransportProtocol //J- return new TransportLocalWithHooks( hookEventFacadeProvider.get(), - local, uri, gitDir, repositoryDAO + repositoryHandlerProvider.get(), + local, uri, gitDir ); //J+ } @@ -181,12 +194,23 @@ public class ScmTransportProtocol extends TransportProtocol private static class TransportLocalWithHooks extends TransportLocal { + /** + * Constructs ... + * + * + * + * @param hookEventFacade + * @param handler + * @param local + * @param uri + * @param gitDir + */ public TransportLocalWithHooks(HookEventFacade hookEventFacade, - Repository local, URIish uri, File gitDir, RepositoryDAO repositoryDAO) + GitRepositoryHandler handler, Repository local, URIish uri, File gitDir) { super(local, uri, gitDir); this.hookEventFacade = hookEventFacade; - this.repositoryDAO = repositoryDAO; + this.handler = handler; } //~--- methods ------------------------------------------------------------ @@ -204,9 +228,9 @@ public class ScmTransportProtocol extends TransportProtocol { ReceivePack pack = new ReceivePack(dst); - if (hookEventFacade != null) + if ((hookEventFacade != null) && (handler != null)) { - GitReceiveHook hook = new GitReceiveHook(hookEventFacade, repositoryDAO); + GitReceiveHook hook = new GitReceiveHook(hookEventFacade, handler); pack.setPreReceiveHook(hook); pack.setPostReceiveHook(hook); @@ -217,9 +241,11 @@ public class ScmTransportProtocol extends TransportProtocol //~--- fields ------------------------------------------------------------- + /** Field description */ + private GitRepositoryHandler handler; + /** Field description */ private HookEventFacade hookEventFacade; - private RepositoryDAO repositoryDAO; } @@ -228,5 +254,6 @@ public class ScmTransportProtocol extends TransportProtocol /** Field description */ private Provider hookEventFacadeProvider; - private RepositoryDAO repositoryDAO; + /** Field description */ + private Provider repositoryHandlerProvider; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java index de55953729..4d83d14d5d 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java @@ -38,6 +38,7 @@ package sonia.scm.repository; import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Singleton; +import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,6 +89,8 @@ public class GitRepositoryHandler GitRepositoryServiceProvider.COMMANDS); private static final Object LOCK = new Object(); + private static final String CONFIG_SECTION_SCMM = "scmm"; + private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid"; private final Scheduler scheduler; @@ -176,15 +179,26 @@ public class GitRepositoryHandler return getStringFromResource(RESOURCE_VERSION, DEFAULT_VERSION_INFORMATION); } + public GitWorkdirFactory getWorkdirFactory() { + return workdirFactory; + } + + public String getRepositoryId(StoredConfig gitConfig) { + return gitConfig.getString(GitRepositoryHandler.CONFIG_SECTION_SCMM, null, GitRepositoryHandler.CONFIG_KEY_REPOSITORY_ID); + } + //~--- methods -------------------------------------------------------------- @Override protected void create(Repository repository, File directory) throws IOException { try (org.eclipse.jgit.lib.Repository gitRepository = build(directory)) { gitRepository.create(true); + StoredConfig config = gitRepository.getConfig(); + config.setString(CONFIG_SECTION_SCMM, null, CONFIG_KEY_REPOSITORY_ID, repository.getId()); + config.save(); } } - + private org.eclipse.jgit.lib.Repository build(File directory) throws IOException { return new FileRepositoryBuilder() .setGitDir(directory) @@ -218,8 +232,4 @@ public class GitRepositoryHandler { return GitConfig.class; } - - public GitWorkdirFactory getWorkdirFactory() { - return workdirFactory; - } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java index 0772249561..74a5039516 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java @@ -36,18 +36,18 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.transport.PostReceiveHook; import org.eclipse.jgit.transport.PreReceiveHook; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceivePack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.repository.RepositoryDAO; +import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.RepositoryHookType; import sonia.scm.repository.spi.GitHookContextProvider; import sonia.scm.repository.spi.HookEventFacade; -import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.List; @@ -67,10 +67,19 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook //~--- constructors --------------------------------------------------------- - public GitReceiveHook(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO) + /** + * Constructs ... + * + * + * + * @param hookEventFacade + * @param handler + */ + public GitReceiveHook(HookEventFacade hookEventFacade, + GitRepositoryHandler handler) { this.hookEventFacade = hookEventFacade; - this.repositoryDAO = repositoryDAO; + this.handler = handler; } //~--- methods -------------------------------------------------------------- @@ -118,14 +127,14 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook try { Repository repository = rpack.getRepository(); - sonia.scm.repository.Repository scmRepository = resolveRepositoryId(repository); + String repositoryId = resolveRepositoryId(repository); - logger.trace("resolved repository to {}", scmRepository.getNamespaceAndName()); + logger.trace("resolved repository to {}", repositoryId); GitHookContextProvider context = new GitHookContextProvider(rpack, receiveCommands); - hookEventFacade.handle(scmRepository).fireHookEvent(type, context); + hookEventFacade.handle(repositoryId).fireHookEvent(type, context); } catch (Exception ex) @@ -177,26 +186,17 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook * * @throws IOException */ - private sonia.scm.repository.Repository resolveRepositoryId(Repository repository) + private String resolveRepositoryId(Repository repository) { - File directory; - - if (repository.isBare()) - { - directory = repository.getDirectory(); - } - else - { - directory = repository.getWorkTree(); - } - - return repositoryDAO.getRepositoryForDirectory(directory); + StoredConfig gitConfig = repository.getConfig(); + return handler.getRepositoryId(gitConfig); } //~--- fields --------------------------------------------------------------- /** Field description */ - private HookEventFacade hookEventFacade; + private GitRepositoryHandler handler; - private final RepositoryDAO repositoryDAO; + /** Field description */ + private HookEventFacade hookEventFacade; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java index d50316fc97..25bbe04cfc 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java @@ -36,19 +36,21 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; + import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; -import sonia.scm.repository.RepositoryDAO; + +import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.spi.HookEventFacade; -import javax.servlet.http.HttpServletRequest; - //~--- JDK imports ------------------------------------------------------------ +import javax.servlet.http.HttpServletRequest; + /** * * @author Sebastian Sdorra @@ -57,10 +59,19 @@ public class GitReceivePackFactory implements ReceivePackFactory { + /** + * Constructs ... + * + * + * + * @param hookEventFacade + * @param handler + */ @Inject - public GitReceivePackFactory(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO) + public GitReceivePackFactory(HookEventFacade hookEventFacade, + GitRepositoryHandler handler) { - hook = new GitReceiveHook(hookEventFacade, repositoryDAO); + hook = new GitReceiveHook(hookEventFacade, handler); } //~--- methods -------------------------------------------------------------- diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java index 63ade30d07..97e09c0708 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java @@ -127,7 +127,15 @@ public class AbstractRemoteCommandTestBase { return null; } - }, null); + }, new Provider() + { + + @Override + public GitRepositoryHandler get() + { + return null; + } + }); Transport.register(proto); } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java index a92cc4f462..533adbac82 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java @@ -41,10 +41,15 @@ import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.ConfigurationException; +import sonia.scm.ContextEntry; import sonia.scm.SCMContextProvider; import sonia.scm.installer.HgInstaller; import sonia.scm.installer.HgInstallerFactory; import sonia.scm.io.ExtendedCommand; +import sonia.scm.io.INIConfiguration; +import sonia.scm.io.INIConfigurationReader; +import sonia.scm.io.INIConfigurationWriter; +import sonia.scm.io.INISection; import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.HgRepositoryServiceProvider; import sonia.scm.store.ConfigurationStoreFactory; @@ -98,6 +103,8 @@ public class HgRepositoryHandler /** Field description */ public static final String PATH_HGRC = ".hg".concat(File.separator).concat("hgrc"); + private static final String CONFIG_SECTION_SCMM = "scmm"; + private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid"; //~--- constructors --------------------------------------------------------- @@ -322,6 +329,26 @@ public class HgRepositoryHandler protected void postCreate(Repository repository, File directory) throws IOException { + File hgrcFile = new File(directory, PATH_HGRC); + INIConfiguration hgrc = new INIConfiguration(); + + INISection iniSection = new INISection(CONFIG_SECTION_SCMM); + iniSection.setParameter(CONFIG_KEY_REPOSITORY_ID, repository.getId()); + INIConfiguration iniConfiguration = new INIConfiguration(); + iniConfiguration.addSection(iniSection); + hgrc.addSection(iniSection); + + INIConfigurationWriter writer = new INIConfigurationWriter(); + + writer.write(hgrc, hgrcFile); + } + + public String getRepositoryId(File directory) { + try { + return new INIConfigurationReader().read(new File(directory, PATH_HGRC)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID); + } catch (IOException e) { + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e); + } } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookChangesetProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookChangesetProvider.java index 695328f268..e4e3dc238e 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookChangesetProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookChangesetProvider.java @@ -62,11 +62,11 @@ public class HgHookChangesetProvider implements HookChangesetProvider //~--- constructors --------------------------------------------------------- public HgHookChangesetProvider(HgRepositoryHandler handler, - sonia.scm.repository.Repository repository, HgHookManager hookManager, String startRev, - RepositoryHookType type) + File repositoryDirectory, HgHookManager hookManager, String startRev, + RepositoryHookType type) { this.handler = handler; - this.repository = repository; + this.repositoryDirectory = repositoryDirectory; this.hookManager = hookManager; this.startRev = startRev; this.type = type; @@ -123,8 +123,6 @@ public class HgHookChangesetProvider implements HookChangesetProvider */ private Repository open() { - File repositoryDirectory = handler.getDirectory(repository); - // use HG_PENDING only for pre receive hooks boolean pending = type == RepositoryHookType.PRE_RECEIVE; @@ -142,7 +140,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider private HgHookManager hookManager; /** Field description */ - private sonia.scm.repository.Repository repository; + private File repositoryDirectory; /** Field description */ private HookChangesetResponse response; diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookContextProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookContextProvider.java index 2bc75eaffa..b2674e7e95 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookContextProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgHookContextProvider.java @@ -45,6 +45,7 @@ import sonia.scm.repository.api.HookFeature; import sonia.scm.repository.api.HookMessageProvider; import sonia.scm.repository.api.HookTagProvider; +import java.io.File; import java.util.EnumSet; import java.util.Set; @@ -68,16 +69,16 @@ public class HgHookContextProvider extends HookContextProvider * Constructs a new instance. * * @param handler mercurial repository handler - * @param repository the changed repository + * @param repositoryDirectory the directory of the changed repository * @param hookManager mercurial hook manager * @param startRev start revision * @param type type of hook */ public HgHookContextProvider(HgRepositoryHandler handler, - Repository repository, HgHookManager hookManager, String startRev, + File repositoryDirectory, HgHookManager hookManager, String startRev, RepositoryHookType type) { - this.hookChangesetProvider = new HgHookChangesetProvider(handler, repository, hookManager, startRev, type); + this.hookChangesetProvider = new HgHookChangesetProvider(handler, repositoryDirectory, hookManager, startRev, type); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgHookCallbackServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgHookCallbackServlet.java index 35b01b35cd..4483f74828 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgHookCallbackServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgHookCallbackServlet.java @@ -44,12 +44,12 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.ContextEntry; import sonia.scm.NotFoundException; import sonia.scm.repository.HgContext; import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgRepositoryHandler; -import sonia.scm.repository.Repository; -import sonia.scm.repository.RepositoryDAO; +import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.RepositoryHookType; import sonia.scm.repository.api.HgHookMessage; import sonia.scm.repository.api.HgHookMessage.Severity; @@ -118,13 +118,12 @@ public class HgHookCallbackServlet extends HttpServlet @Inject public HgHookCallbackServlet(HookEventFacade hookEventFacade, HgRepositoryHandler handler, HgHookManager hookManager, - Provider contextProvider, RepositoryDAO repositoryDAO) + Provider contextProvider) { this.hookEventFacade = hookEventFacade; this.handler = handler; this.hookManager = hookManager; this.contextProvider = contextProvider; - this.repositoryDAO = repositoryDAO; } //~--- methods -------------------------------------------------------------- @@ -171,7 +170,7 @@ public class HgHookCallbackServlet extends HttpServlet if (m.matches()) { - Repository repository = getRepositoryId(request); + File repositoryPath = getRepositoryPath(request); String type = m.group(1); String challenge = request.getParameter(PARAM_CHALLENGE); @@ -188,7 +187,7 @@ public class HgHookCallbackServlet extends HttpServlet authenticate(request, credentials); } - hookCallback(response, repository, type, challenge, node); + hookCallback(response, repositoryPath, type, challenge, node); } else if (logger.isDebugEnabled()) { @@ -247,8 +246,7 @@ public class HgHookCallbackServlet extends HttpServlet } } - private void fireHook(HttpServletResponse response, Repository repository, - String node, RepositoryHookType type) + private void fireHook(HttpServletResponse response, File repositoryDirectory, String node, RepositoryHookType type) throws IOException { HgHookContextProvider context = null; @@ -260,10 +258,11 @@ public class HgHookCallbackServlet extends HttpServlet contextProvider.get().setPending(true); } - context = new HgHookContextProvider(handler, repository, hookManager, + context = new HgHookContextProvider(handler, repositoryDirectory, hookManager, node, type); - hookEventFacade.handle(repository).fireHookEvent(type, context); + String repositoryId = getRepositoryId(repositoryDirectory); + hookEventFacade.handle(repositoryId).fireHookEvent(type, context); printMessages(response, context); } @@ -281,7 +280,7 @@ public class HgHookCallbackServlet extends HttpServlet } } - private void hookCallback(HttpServletResponse response, Repository repository, String typeName, String challenge, String node) throws IOException { + private void hookCallback(HttpServletResponse response, File repositoryDirectory, String typeName, String challenge, String node) throws IOException { if (hookManager.isAcceptAble(challenge)) { RepositoryHookType type = null; @@ -297,7 +296,7 @@ public class HgHookCallbackServlet extends HttpServlet if (type != null) { - fireHook(response, repository, node, type); + fireHook(response, repositoryDirectory, node, type); } else { @@ -442,29 +441,21 @@ public class HgHookCallbackServlet extends HttpServlet //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * - * @param request - * - * @return - */ @SuppressWarnings("squid:S2083") // we do nothing with the path given, so this should be no issue - private Repository getRepositoryId(HttpServletRequest request) + private String getRepositoryId(File repositoryPath) { - Repository repository = null; + return handler.getRepositoryId(repositoryPath); + } + + private File getRepositoryPath(HttpServletRequest request) { String path = request.getParameter(PARAM_REPOSITORYPATH); - if (Util.isNotEmpty(path)) { - repository = repositoryDAO.getRepositoryForDirectory(new File(path)); + return new File(path); } - else if (logger.isWarnEnabled()) + else { - logger.warn("no repository path parameter found"); + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", path), "could not find hgrc in directory"); } - - return repository; } //~--- fields --------------------------------------------------------------- @@ -480,6 +471,4 @@ public class HgHookCallbackServlet extends HttpServlet /** Field description */ private final HgHookManager hookManager; - - private final RepositoryDAO repositoryDAO; } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgHookCallbackServletTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgHookCallbackServletTest.java index d436d67490..eb5caea876 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgHookCallbackServletTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgHookCallbackServletTest.java @@ -23,9 +23,7 @@ public class HgHookCallbackServletTest { @Test public void shouldExtractCorrectRepositoryId() throws ServletException, IOException { HgRepositoryHandler handler = mock(HgRepositoryHandler.class); - RepositoryDAO repositoryDAO = mock(RepositoryDAO.class); - when(repositoryDAO.getRepositoryForDirectory(new File("/tmp/hg/12345"))).thenReturn(new Repository("12345", "git", "space", "name")); - HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null, repositoryDAO); + HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null); HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java index 88bbb55321..97698d7a77 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java @@ -46,6 +46,11 @@ import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import org.tmatesoft.svn.util.SVNDebugLog; +import sonia.scm.ContextEntry; +import sonia.scm.io.INIConfiguration; +import sonia.scm.io.INIConfigurationReader; +import sonia.scm.io.INIConfigurationWriter; +import sonia.scm.io.INISection; import sonia.scm.logging.SVNKitLogger; import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.HookEventFacade; @@ -54,6 +59,7 @@ import sonia.scm.store.ConfigurationStoreFactory; import sonia.scm.util.Util; import java.io.File; +import java.io.IOException; import static sonia.scm.ContextEntry.ContextBuilder.entity; @@ -80,6 +86,9 @@ public class SvnRepositoryHandler public static final RepositoryType TYPE = new RepositoryType(TYPE_NAME, TYPE_DISPLAYNAME, SvnRepositoryServiceProvider.COMMANDS); + private static final String CONFIG_FILE_NAME = "scm-manager.conf"; + private static final String CONFIG_SECTION_SCMM = "scmm"; + private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid"; private static final Logger logger = LoggerFactory.getLogger(SvnRepositoryHandler.class); @@ -87,8 +96,7 @@ public class SvnRepositoryHandler @Inject public SvnRepositoryHandler(ConfigurationStoreFactory storeFactory, HookEventFacade eventFacade, - RepositoryLocationResolver repositoryLocationResolver, - RepositoryDAO repositoryDAO) + RepositoryLocationResolver repositoryLocationResolver) { super(storeFactory, repositoryLocationResolver); @@ -101,7 +109,7 @@ public class SvnRepositoryHandler // register hook if (eventFacade != null) { - FSHooks.registerHook(new SvnRepositoryHook(eventFacade, repositoryDAO)); + FSHooks.registerHook(new SvnRepositoryHook(eventFacade, this)); } else if (logger.isWarnEnabled()) { @@ -210,4 +218,21 @@ public class SvnRepositoryHandler { return SvnConfig.class; } + + @Override + protected void postCreate(Repository repository, File directory) throws IOException { + INISection iniSection = new INISection(CONFIG_SECTION_SCMM); + iniSection.setParameter(CONFIG_KEY_REPOSITORY_ID, repository.getId()); + INIConfiguration iniConfiguration = new INIConfiguration(); + iniConfiguration.addSection(iniSection); + new INIConfigurationWriter().write(iniConfiguration, new File(directory, CONFIG_FILE_NAME)); + } + + String getRepositoryId(File directory) { + try { + return new INIConfigurationReader().read(new File(directory, CONFIG_FILE_NAME)).getSection(CONFIG_SECTION_SCMM).getParameter(CONFIG_KEY_REPOSITORY_ID); + } catch (IOException e) { + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity("directory", directory.toString()), "could not read scm configuration file", e); + } + } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHook.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHook.java index f1b9109239..c0a440f8d1 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHook.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHook.java @@ -70,10 +70,10 @@ public class SvnRepositoryHook implements FSHook //~--- constructors --------------------------------------------------------- - public SvnRepositoryHook(HookEventFacade hookEventFacade, RepositoryDAO repositoryDAO) + public SvnRepositoryHook(HookEventFacade hookEventFacade, SvnRepositoryHandler handler) { this.hookEventFacade = hookEventFacade; - this.repositoryDAO = repositoryDAO; + this.handler = handler; } //~--- methods -------------------------------------------------------------- @@ -154,10 +154,10 @@ public class SvnRepositoryHook implements FSHook { try { - Repository repository = getRepositoryId(directory); + String repositoryId = getRepositoryId(directory); //J- - hookEventFacade.handle(repository) + hookEventFacade.handle(repositoryId) .fireHookEvent( changesetProvider.getType(), new SvnHookContextProvider(changesetProvider) @@ -188,11 +188,10 @@ public class SvnRepositoryHook implements FSHook * * @throws IOException */ - private Repository getRepositoryId(File directory) + private String getRepositoryId(File directory) { AssertUtil.assertIsNotNull(directory); - - return repositoryDAO.getRepositoryForDirectory(directory); + return handler.getRepositoryId(directory); } //~--- fields --------------------------------------------------------------- @@ -200,5 +199,5 @@ public class SvnRepositoryHook implements FSHook /** Field description */ private HookEventFacade hookEventFacade; - private final RepositoryDAO repositoryDAO; + private final SvnRepositoryHandler handler; } diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/SvnRepositoryHandlerTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/SvnRepositoryHandlerTest.java index 9f63d69ab6..eaa7394ae5 100644 --- a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/SvnRepositoryHandlerTest.java +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/SvnRepositoryHandlerTest.java @@ -93,7 +93,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase { protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory, File directory) { repositoryLocationResolver = new RepositoryLocationResolver(repoDao, new InitialRepositoryLocationResolver(contextProvider)); - SvnRepositoryHandler handler = new SvnRepositoryHandler(factory, null, repositoryLocationResolver, repositoryDAO); + SvnRepositoryHandler handler = new SvnRepositoryHandler(factory, null, repositoryLocationResolver); handler.init(contextProvider); @@ -109,7 +109,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase { public void getDirectory() { when(factory.getStore(any(), any())).thenReturn(store); SvnRepositoryHandler repositoryHandler = new SvnRepositoryHandler(factory, - facade, repositoryLocationResolver, repositoryDAO); + facade, repositoryLocationResolver); SvnConfig svnConfig = new SvnConfig(); repositoryHandler.setConfig(svnConfig);