From 7a1de0f67b243cafdd8be8cb9c6c153516ef89ff Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Tue, 27 Nov 2018 11:35:02 +0100 Subject: [PATCH] add the interface StoreFactory and refactor storeFactories --- .../repository/AbstractRepositoryHandler.java | 10 ++- .../InitialRepositoryLocationResolver.java | 7 +- .../RepositoryLocationResolver.java | 22 ++++++ .../sonia/scm/store/BlobStoreFactory.java | 12 +-- .../store/ConfigurationEntryStoreFactory.java | 23 ++---- .../scm/store/ConfigurationStoreFactory.java | 19 +---- .../sonia/scm/store/DataStoreFactory.java | 15 +--- .../java/sonia/scm/store/StoreFactory.java | 6 ++ .../java/sonia/scm/store/StoreParameters.java | 67 +++++++++++++++++ .../java/sonia/scm/group/xml/XmlGroupDAO.java | 9 ++- .../scm/repository/xml/XmlRepositoryDAO.java | 16 ++-- .../scm/store/FileBasedStoreFactory.java | 49 +++++++++---- .../sonia/scm/store/FileBlobStoreFactory.java | 18 ++--- .../JAXBConfigurationEntryStoreFactory.java | 20 ++++- .../scm/store/JAXBConfigurationStore.java | 2 +- .../store/JAXBConfigurationStoreFactory.java | 73 ++++++++++++++----- .../sonia/scm/store/JAXBDataStoreFactory.java | 55 +++----------- .../java/sonia/scm/user/xml/XmlUserDAO.java | 6 +- .../sonia/scm/store/FileBlobStoreTest.java | 2 +- .../JAXBConfigurationEntryStoreTest.java | 35 ++++----- .../scm/store/JAXBConfigurationStoreTest.java | 4 +- .../sonia/scm/store/JAXBDataStoreTest.java | 25 ++++++- .../scm/web/lfs/LfsBlobStoreFactory.java | 10 ++- .../repository/GitRepositoryHandlerTest.java | 3 + .../scm/web/lfs/LfsBlobStoreFactoryTest.java | 14 +++- .../repository/HgRepositoryHandlerTest.java | 3 + .../scm/repository/SvnRepositoryHandler.java | 1 + .../repository/SvnRepositoryHandlerTest.java | 2 +- .../main/java/sonia/scm/AbstractTestBase.java | 55 +++++++------- .../main/java/sonia/scm/ManagerTestBase.java | 7 +- .../sonia/scm/store/BlobStoreTestBase.java | 29 ++++---- .../ConfigurationEntryStoreTestBase.java | 32 ++++---- .../sonia/scm/store/DataStoreTestBase.java | 41 ++++++++--- .../InMemoryConfigurationStoreFactory.java | 3 +- .../scm/store/KeyValueStoreTestBase.java | 17 +++-- .../java/sonia/scm/store/StoreTestBase.java | 19 +++-- .../scm/security/DefaultSecuritySystem.java | 7 +- .../sonia/scm/security/SecureKeyResolver.java | 7 +- .../resources/AutoCompleteResourceTest.java | 2 +- .../DefaultRepositoryManagerTest.java | 4 +- .../scm/security/SecureKeyResolverTest.java | 23 +++--- .../scm/user/DefaultUserManagerTest.java | 2 +- 42 files changed, 485 insertions(+), 291 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/store/StoreFactory.java create mode 100644 scm-core/src/main/java/sonia/scm/store/StoreParameters.java diff --git a/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java b/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java index 42c8f22a0f..d494858494 100644 --- a/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java +++ b/scm-core/src/main/java/sonia/scm/repository/AbstractRepositoryHandler.java @@ -48,6 +48,7 @@ import java.io.File; import java.io.IOException; import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.store.StoreParameters; /** @@ -72,9 +73,12 @@ public abstract class AbstractRepositoryHandler * * @param storeFactory */ - protected AbstractRepositoryHandler(ConfigurationStoreFactory storeFactory) - { - this.store = storeFactory.getStore(getConfigClass(), getType().getName()); + protected AbstractRepositoryHandler(ConfigurationStoreFactory storeFactory) { + this.store = storeFactory.getStore(new StoreParameters() + .withType(getConfigClass()) + .withName(getType().getName()) + .build() + ); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/repository/InitialRepositoryLocationResolver.java b/scm-core/src/main/java/sonia/scm/repository/InitialRepositoryLocationResolver.java index 51aba9bc25..a579df4e21 100644 --- a/scm-core/src/main/java/sonia/scm/repository/InitialRepositoryLocationResolver.java +++ b/scm-core/src/main/java/sonia/scm/repository/InitialRepositoryLocationResolver.java @@ -6,6 +6,7 @@ import sonia.scm.io.FileSystem; import javax.inject.Inject; import java.io.File; import java.io.IOException; +import java.text.MessageFormat; /** * @@ -44,7 +45,11 @@ public final class InitialRepositoryLocationResolver { return new File(context.getBaseDirectory(), REPOSITORIES_DIRECTORY); } - public File createDirectory(Repository repository) throws IOException { + File getContextBaseDirectory() { + return context.getBaseDirectory(); + } + + public File createDirectory(Repository repository) throws IOException { File initialRepoFolder = getDirectory(repository); fileSystem.create(initialRepoFolder); return initialRepoFolder; 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 5515c3eb88..64d38fbe6d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryLocationResolver.java @@ -24,6 +24,10 @@ import static sonia.scm.repository.InitialRepositoryLocationResolver.REPOSITORIE @Singleton public class RepositoryLocationResolver { + private static final String REPOSITORIES_STORES_DIRECTORY = "stores"; + private static final String REPOSITORIES_CONFIG_DIRECTORY = "config"; + private static final String GLOBAL_STORE_BASE_DIRECTORY = "var"; + private RepositoryDAO repositoryDAO; private InitialRepositoryLocationResolver initialRepositoryLocationResolver; @@ -70,4 +74,22 @@ public class RepositoryLocationResolver { public File getInitialNativeDirectory(Repository repository) { return new File (getInitialDirectory(repository), REPOSITORIES_NATIVE_DIRECTORY); } + + /** + * Get the store directory of a specific repository + * @param repository + * @return the store directory of a specific repository + */ + public File getStoresDirectory(Repository repository) throws IOException{ + return new File (getRepositoryDirectory(repository), REPOSITORIES_STORES_DIRECTORY); + } + + public File getConfigDirectory(Repository repository) throws IOException { + return new File (getRepositoryDirectory(repository), REPOSITORIES_CONFIG_DIRECTORY); + } + + public File getGlobalStoreDirectory() { + return new File(initialRepositoryLocationResolver.getContextBaseDirectory(), + GLOBAL_STORE_BASE_DIRECTORY.concat(File.separator)); + } } diff --git a/scm-core/src/main/java/sonia/scm/store/BlobStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/BlobStoreFactory.java index 941b3923d1..7d0462d371 100644 --- a/scm-core/src/main/java/sonia/scm/store/BlobStoreFactory.java +++ b/scm-core/src/main/java/sonia/scm/store/BlobStoreFactory.java @@ -42,16 +42,6 @@ package sonia.scm.store; * @apiviz.landmark * @apiviz.uses sonia.scm.store.BlobStore */ -public interface BlobStoreFactory { +public interface BlobStoreFactory extends StoreFactory { - /** - * Returns a {@link BlobStore} with the given name, if the {@link BlobStore} - * with the given name does not exists the factory will create a new one. - * - * - * @param name name of the {@link BlobStore} - * - * @return {@link BlobStore} with the given name - */ - public BlobStore getBlobStore(String name); } diff --git a/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java index 7cfebd69c1..4a1202e28c 100644 --- a/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java +++ b/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java @@ -34,10 +34,10 @@ package sonia.scm.store; /** * The ConfigurationEntryStoreFactory can be used to create new or get existing - * {@link ConfigurationEntryStore}s. Note: the default implementation - * uses the same location as the {@link StoreFactory}, so be sure that the - * store names are unique for all {@link ConfigurationEntryStore}s and - * {@link Store}s. + * {@link ConfigurationEntryStore}s. + * + * Note: the default implementation uses the same location as the {@link ConfigurationStoreFactory}, so be sure that the + * store names are unique for all {@link ConfigurationEntryStore}s and {@link ConfigurationStore}s. * * @author Sebastian Sdorra * @since 1.31 @@ -45,18 +45,5 @@ package sonia.scm.store; * @apiviz.landmark * @apiviz.uses sonia.scm.store.ConfigurationEntryStore */ -public interface ConfigurationEntryStoreFactory -{ - - /** - * Get an existing {@link ConfigurationEntryStore} or create a new one. - * - * - * @param type type of the store objects - * @param name name of the store - * @param type of the store objects - * - * @return {@link ConfigurationEntryStore} with given name and type - */ - public ConfigurationEntryStore getStore(Class type, String name); +public interface ConfigurationEntryStoreFactory extends StoreFactory { } diff --git a/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java index d9a97de98d..6cf9541139 100644 --- a/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java +++ b/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java @@ -37,23 +37,12 @@ package sonia.scm.store; * The ConfigurationStoreFactory can be used to create new or get existing * {@link ConfigurationStore} objects. * + * Note: the default implementation uses the same location as the {@link ConfigurationEntryStoreFactory}, so be sure that the + * store names are unique for all {@link ConfigurationEntryStore}s and {@link ConfigurationStore}s. + * * @author Sebastian Sdorra * * @apiviz.landmark * @apiviz.uses sonia.scm.store.ConfigurationStore */ -public interface ConfigurationStoreFactory -{ - - /** - * Get an existing {@link ConfigurationStore} or create a new one. - * - * - * @param type type of the store objects - * @param name name of the store - * @param type of the store objects - * - * @return {@link ConfigurationStore} of the given type and name - */ - public ConfigurationStore getStore(Class type, String name); -} +public interface ConfigurationStoreFactory extends StoreFactory{} diff --git a/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java index caed974ee4..c1e171a74b 100644 --- a/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java +++ b/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java @@ -42,17 +42,4 @@ package sonia.scm.store; * @apiviz.landmark * @apiviz.uses sonia.scm.store.DataStore */ -public interface DataStoreFactory { - - /** - * Get an existing {@link DataStore} or create a new one. - * - * - * @param type type of the store objects - * @param name name of the store - * @param type of the store objects - * - * @return {@link DataStore} with given name and type - */ - public DataStore getStore(Class type, String name); -} +public interface DataStoreFactory extends StoreFactory{} diff --git a/scm-core/src/main/java/sonia/scm/store/StoreFactory.java b/scm-core/src/main/java/sonia/scm/store/StoreFactory.java new file mode 100644 index 0000000000..a40e8cfeba --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/store/StoreFactory.java @@ -0,0 +1,6 @@ +package sonia.scm.store; + +public interface StoreFactory { + + STORE getStore(final StoreParameters storeParameters); +} diff --git a/scm-core/src/main/java/sonia/scm/store/StoreParameters.java b/scm-core/src/main/java/sonia/scm/store/StoreParameters.java new file mode 100644 index 0000000000..b625004d42 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/store/StoreParameters.java @@ -0,0 +1,67 @@ +package sonia.scm.store; + +import sonia.scm.repository.Repository; + +/** + * The fields of the {@link StoreParameters} are used from the {@link StoreFactory} to create a store. + * + * @author Mohamed Karray + * @since 2.0.0 + */ +public class StoreParameters { + + private Class type; + private String name; + private Repository repository; + + public Class getType() { + return type; + } + + public String getName() { + return name; + } + + public Repository getRepository() { + return repository; + } + + public WithType withType(Class type){ + return new WithType(type); + } + + public class WithType { + + private WithType(Class type) { + StoreParameters.this.type = type; + } + + public WithTypeAndName withName(String name){ + return new WithTypeAndName(name); + } + + } + public class WithTypeAndName { + + private WithTypeAndName(String name) { + StoreParameters.this.name = name; + } + + public WithTypeNameAndRepository forRepository(Repository repository){ + return new WithTypeNameAndRepository(repository); + } + public StoreParameters build(){ + return StoreParameters.this; + } + } + + public class WithTypeNameAndRepository { + + private WithTypeNameAndRepository(Repository repository) { + StoreParameters.this.repository = repository; + } + public StoreParameters build(){ + return StoreParameters.this; + } + } +} diff --git a/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java b/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java index 577d732317..2b416cf53a 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java @@ -39,6 +39,7 @@ import com.google.inject.Singleton; import sonia.scm.group.Group; import sonia.scm.group.GroupDAO; +import sonia.scm.store.StoreParameters; import sonia.scm.xml.AbstractXmlDAO; import sonia.scm.store.ConfigurationStoreFactory; @@ -64,9 +65,11 @@ public class XmlGroupDAO extends AbstractXmlDAO * @param storeFactory */ @Inject - public XmlGroupDAO(ConfigurationStoreFactory storeFactory) - { - super(storeFactory.getStore(XmlGroupDatabase.class, STORE_NAME)); + public XmlGroupDAO(ConfigurationStoreFactory storeFactory) { + super(storeFactory.getStore(new StoreParameters() + .withType(XmlGroupDatabase.class) + .withName(STORE_NAME) + .build())); } //~--- methods -------------------------------------------------------------- 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 eadf277dd3..cdeb1adfa4 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 @@ -36,14 +36,18 @@ package sonia.scm.repository.xml; import com.google.inject.Inject; import com.google.inject.Singleton; +import sonia.scm.SCMContextProvider; import sonia.scm.repository.InitialRepositoryLocationResolver; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.PathBasedRepositoryDAO; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryPathNotFoundException; -import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.store.JAXBConfigurationStore; +import sonia.scm.store.StoreConstants; +import sonia.scm.util.IOUtil; import sonia.scm.xml.AbstractXmlDAO; +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; @@ -65,14 +69,10 @@ public class XmlRepositoryDAO //~--- constructors --------------------------------------------------------- - /** - * Constructs ... - * - * @param storeFactory - */ @Inject - public XmlRepositoryDAO(ConfigurationStoreFactory storeFactory, InitialRepositoryLocationResolver initialRepositoryLocationResolver) { - super(storeFactory.getStore(XmlRepositoryDatabase.class, STORE_NAME)); + public XmlRepositoryDAO(InitialRepositoryLocationResolver initialRepositoryLocationResolver, SCMContextProvider context) { + super(new JAXBConfigurationStore<>(XmlRepositoryDatabase.class, new File(context.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME + File.separator + STORE_NAME + StoreConstants.FILE_EXTENSION))); + IOUtil.mkdirs(new File(context.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME + File.separator + STORE_NAME + StoreConstants.FILE_EXTENSION)); this.initialRepositoryLocationResolver = initialRepositoryLocationResolver; } diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java index 5bfc4f34b9..f9d7f49e48 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java @@ -31,18 +31,23 @@ package sonia.scm.store; //~--- non-JDK imports -------------------------------------------------------- + import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import sonia.scm.SCMContextProvider; +import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.util.IOUtil; -//~--- JDK imports ------------------------------------------------------------ import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; + +//~--- JDK imports ------------------------------------------------------------ /** * Abstract store factory for file based stores. - * + * * @author Sebastian Sdorra */ public abstract class FileBasedStoreFactory { @@ -51,18 +56,14 @@ public abstract class FileBasedStoreFactory { * the logger for FileBasedStoreFactory */ private static final Logger LOG = LoggerFactory.getLogger(FileBasedStoreFactory.class); - - private static final String BASE_DIRECTORY = "var"; - - private final SCMContextProvider context; + private RepositoryLocationResolver repositoryLocationResolver; private final String dataDirectoryName; private File dataDirectory; - protected FileBasedStoreFactory(SCMContextProvider context, - String dataDirectoryName) { - this.context = context; + protected FileBasedStoreFactory(RepositoryLocationResolver repositoryLocationResolver, String dataDirectoryName) { + this.repositoryLocationResolver = repositoryLocationResolver; this.dataDirectoryName = dataDirectoryName; } @@ -76,9 +77,8 @@ public abstract class FileBasedStoreFactory { */ protected File getDirectory(String name) { if (dataDirectory == null) { - dataDirectory = new File(context.getBaseDirectory(), - BASE_DIRECTORY.concat(File.separator).concat(dataDirectoryName)); - LOG.debug("create data directory {}", dataDirectory); + dataDirectory = new File(repositoryLocationResolver.getGlobalStoreDirectory(), dataDirectoryName); + LOG.debug("get data directory {}", dataDirectory); } File storeDirectory = new File(dataDirectory, name); @@ -86,4 +86,25 @@ public abstract class FileBasedStoreFactory { return storeDirectory; } + /** + * Returns data directory for given name. + * + * @param name name of data directory + * + * @return data directory + */ + protected File getDirectory(String name, Repository repository) { + if (dataDirectory == null) { + try { + dataDirectory = new File(repositoryLocationResolver.getStoresDirectory(repository), dataDirectoryName); + } catch (IOException e) { + throw new InternalRepositoryException(repository, MessageFormat.format("Error on getting the store directory {0} of the repository {1}", dataDirectory.getAbsolutePath(), repository.getNamespaceAndName()), e); + } + LOG.debug("create data directory {}", dataDirectory); + } + File storeDirectory = new File(dataDirectory, name); + IOUtil.mkdirs(storeDirectory); + return storeDirectory; + } + } diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java index 8cc5b34ac2..4440cfc908 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java @@ -37,7 +37,7 @@ import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.SCMContextProvider; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.security.KeyGenerator; /** @@ -60,21 +60,21 @@ public class FileBlobStoreFactory extends FileBasedStoreFactory implements BlobS /** * Constructs a new instance. * - * @param context scm context + * @param repositoryLocationResolver * @param keyGenerator key generator */ @Inject - public FileBlobStoreFactory(SCMContextProvider context, - KeyGenerator keyGenerator) { - super(context, DIRECTORY_NAME); + public FileBlobStoreFactory(RepositoryLocationResolver repositoryLocationResolver, KeyGenerator keyGenerator) { + super(repositoryLocationResolver, DIRECTORY_NAME); this.keyGenerator = keyGenerator; } @Override - public BlobStore getBlobStore(String name) { - LOG.debug("create new blob with name {}", name); - - return new FileBlobStore(keyGenerator, getDirectory(name)); + public BlobStore getStore(StoreParameters storeParameters) { + if (storeParameters.getRepository() != null) { + return new FileBlobStore(keyGenerator, getDirectory(storeParameters.getName(), storeParameters.getRepository())); + } + return new FileBlobStore(keyGenerator, getDirectory(storeParameters.getName())); } } diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java index 261c36f8e4..e8f4028f50 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java @@ -42,6 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; +import sonia.scm.repository.Repository; import sonia.scm.security.KeyGenerator; import sonia.scm.util.IOUtil; @@ -91,18 +92,16 @@ public class JAXBConfigurationEntryStoreFactory * * @param type * @param name - * @param * * @return */ - @Override - public ConfigurationEntryStore getStore(Class type, String name) + private ConfigurationEntryStore getStore(Class type, String name) { logger.debug("create new configuration store for type {} with name {}", type, name); //J- - return new JAXBConfigurationEntryStore( + return new JAXBConfigurationEntryStore( new File(directory,name.concat(StoreConstants.FILE_EXTENSION)), keyGenerator, type @@ -117,4 +116,17 @@ public class JAXBConfigurationEntryStoreFactory /** Field description */ private KeyGenerator keyGenerator; + + @Override + public ConfigurationEntryStore getStore(StoreParameters storeParameters) { + if (storeParameters.getRepository() != null){ + return getStore(storeParameters.getType(),storeParameters.getName(),storeParameters.getRepository()); + } + return getStore(storeParameters.getType(),storeParameters.getName()); + } + + private ConfigurationEntryStore getStore(Class type, String name, Repository repository) { + return null; + } + } diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java index 4a87ea57f6..ac1477d7ea 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java @@ -61,7 +61,7 @@ public class JAXBConfigurationStore extends AbstractStore { private JAXBContext context; - JAXBConfigurationStore(Class type, File configFile) { + public JAXBConfigurationStore(Class type, File configFile) { this.type = type; try { diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java index 705b0c1177..8b6ad81756 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java @@ -32,17 +32,18 @@ package sonia.scm.store; import com.google.inject.Inject; import com.google.inject.Singleton; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import sonia.scm.SCMContextProvider; +import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.util.IOUtil; import java.io.File; +import java.io.IOException; /** - * JAXB implementation of {@link ConfigurationStoreFactory}. + * JAXB implementation of {@link StoreFactory}. * * @author Sebastian Sdorra */ @@ -54,33 +55,65 @@ public class JAXBConfigurationStoreFactory implements ConfigurationStoreFactory */ private static final Logger LOG = LoggerFactory.getLogger(JAXBConfigurationStoreFactory.class); - private final File configDirectory; + private RepositoryLocationResolver repositoryLocationResolver; /** * Constructs a new instance. * - * @param context scm context + * @param repositoryLocationResolver Resolver to get the repository Directory */ @Inject - public JAXBConfigurationStoreFactory(SCMContextProvider context) { - configDirectory = new File(context.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME); - IOUtil.mkdirs(configDirectory); + public JAXBConfigurationStoreFactory(RepositoryLocationResolver repositoryLocationResolver) { + this.repositoryLocationResolver = repositoryLocationResolver; } - @Override - public JAXBConfigurationStore getStore(Class type, String name) { - if (configDirectory == null) { - throw new IllegalStateException("store factory is not initialized"); - } + /** + * Get or create the global config directory. + * + * @return the global config directory. + */ + private File getGlobalConfigDirectory() { + File baseDirectory = repositoryLocationResolver.getInitialBaseDirectory(); + File configDirectory = new File(baseDirectory, StoreConstants.CONFIG_DIRECTORY_NAME); + return getOrCreateFile(configDirectory); + } + /** + * Get or create the repository specific config directory. + * + * @return the repository specific config directory. + */ + private File getRepositoryConfigDirectory(Repository repository) { + File baseDirectory = null; + try { + baseDirectory = repositoryLocationResolver.getConfigDirectory(repository); + } catch (IOException e) { + e.printStackTrace(); + } + File configDirectory = new File(baseDirectory, StoreConstants.CONFIG_DIRECTORY_NAME); + return getOrCreateFile(configDirectory); + } + + private File getOrCreateFile(File directory) { + if (!directory.exists()) { + IOUtil.mkdirs(directory); + } + return directory; + } + + private JAXBConfigurationStore getStore(Class type, String name, File configDirectory) { File configFile = new File(configDirectory, name.concat(StoreConstants.FILE_EXTENSION)); - - if (LOG.isDebugEnabled()) { - LOG.debug("create store for {} at {}", type.getName(), - configFile.getPath()); - } - + LOG.debug("create store for {} at {}", type.getName(), configFile.getPath()); return new JAXBConfigurationStore<>(type, configFile); } + @Override + public JAXBConfigurationStore getStore(StoreParameters storeParameters) { + try { + return getStore(storeParameters.getType(), storeParameters.getName(),repositoryLocationResolver.getRepositoryDirectory(storeParameters.getRepository())); + } catch (IOException e) { + + throw new InternalRepositoryException(storeParameters.getRepository(),"Error on getting the store of the repository"+ storeParameters.getRepository().getNamespaceAndName()); + } + } } diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java index 732b8c675b..f5199d8bd2 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java +++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java @@ -40,7 +40,7 @@ import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.SCMContextProvider; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.security.KeyGenerator; /** @@ -52,54 +52,23 @@ public class JAXBDataStoreFactory extends FileBasedStoreFactory implements DataStoreFactory { - /** Field description */ + private static final Logger logger = LoggerFactory.getLogger(JAXBDataStoreFactory.class); private static final String DIRECTORY_NAME = "data"; + private KeyGenerator keyGenerator; - /** - * the logger for JAXBDataStoreFactory - */ - private static final Logger logger = - LoggerFactory.getLogger(JAXBDataStoreFactory.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param context - * @param keyGenerator - */ @Inject - public JAXBDataStoreFactory(SCMContextProvider context, - KeyGenerator keyGenerator) - { - super(context, DIRECTORY_NAME); + public JAXBDataStoreFactory(RepositoryLocationResolver repositoryLocationResolver, KeyGenerator keyGenerator) { + super(repositoryLocationResolver, DIRECTORY_NAME); this.keyGenerator = keyGenerator; } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param type - * @param name - * @param - * - * @return - */ @Override - public DataStore getStore(Class type, String name) - { - logger.debug("create new store for type {} with name {}", type, name); - - return new JAXBDataStore<>(keyGenerator, type, getDirectory(name)); + @SuppressWarnings("unchecked") + public DataStore getStore(StoreParameters storeParameters) { + logger.debug("create new store for type {} with name {}", storeParameters.getType(), storeParameters.getName()); + if (storeParameters.getRepository() != null) { + return new JAXBDataStore(keyGenerator, storeParameters.getType(), getDirectory(storeParameters.getName(), storeParameters.getRepository())); + } + return new JAXBDataStore(keyGenerator, storeParameters.getType(), getDirectory(storeParameters.getName())); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private KeyGenerator keyGenerator; } diff --git a/scm-dao-xml/src/main/java/sonia/scm/user/xml/XmlUserDAO.java b/scm-dao-xml/src/main/java/sonia/scm/user/xml/XmlUserDAO.java index 1bfd877f44..5f84aeb3a8 100644 --- a/scm-dao-xml/src/main/java/sonia/scm/user/xml/XmlUserDAO.java +++ b/scm-dao-xml/src/main/java/sonia/scm/user/xml/XmlUserDAO.java @@ -37,6 +37,7 @@ package sonia.scm.user.xml; import com.google.inject.Inject; import com.google.inject.Singleton; +import sonia.scm.store.StoreParameters; import sonia.scm.user.User; import sonia.scm.user.UserDAO; import sonia.scm.xml.AbstractXmlDAO; @@ -65,7 +66,10 @@ public class XmlUserDAO extends AbstractXmlDAO @Inject public XmlUserDAO(ConfigurationStoreFactory storeFactory) { - super(storeFactory.getStore(XmlUserDatabase.class, STORE_NAME)); + super(storeFactory.getStore(new StoreParameters() + .withType(XmlUserDatabase.class) + .withName(STORE_NAME) + .build())); } //~--- methods -------------------------------------------------------------- diff --git a/scm-dao-xml/src/test/java/sonia/scm/store/FileBlobStoreTest.java b/scm-dao-xml/src/test/java/sonia/scm/store/FileBlobStoreTest.java index cae872538d..1df829588a 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/store/FileBlobStoreTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/store/FileBlobStoreTest.java @@ -52,6 +52,6 @@ public class FileBlobStoreTest extends BlobStoreTestBase @Override protected BlobStoreFactory createBlobStoreFactory() { - return new FileBlobStoreFactory(contextProvider, new UUIDKeyGenerator()); + return new FileBlobStoreFactory(repositoryLocationResolver, new UUIDKeyGenerator()); } } diff --git a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationEntryStoreTest.java b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationEntryStoreTest.java index d0f17fc313..f520ce88e8 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationEntryStoreTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationEntryStoreTest.java @@ -37,25 +37,22 @@ package sonia.scm.store; import com.google.common.io.Closeables; import com.google.common.io.Resources; - import org.junit.Test; - import sonia.scm.security.AssignedPermission; import sonia.scm.security.UUIDKeyGenerator; -import static org.junit.Assert.*; - -//~--- JDK imports ------------------------------------------------------------ - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; - import java.net.URL; - import java.util.UUID; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +//~--- JDK imports ------------------------------------------------------------ + /** * * @author Sebastian Sdorra @@ -132,13 +129,13 @@ public class JAXBConfigurationEntryStoreTest public void testStoreAndLoad() throws IOException { String name = UUID.randomUUID().toString(); - ConfigurationEntryStore store = - createPermissionStore(RESOURCE_FIXED, name); + ConfigurationEntryStore store = createPermissionStore(RESOURCE_FIXED, name); store.put("a45", new AssignedPermission("tuser4", "repository:create")); - store = - createConfigurationStoreFactory().getStore(AssignedPermission.class, - name); + store = createConfigurationStoreFactory().getStore(new StoreParameters() + .withType(AssignedPermission.class) + .withName(name) + .build()); AssignedPermission ap = store.get("a45"); @@ -154,10 +151,9 @@ public class JAXBConfigurationEntryStoreTest * @return */ @Override - protected ConfigurationEntryStoreFactory createConfigurationStoreFactory() + protected ConfigurationEntryStoreFactory createConfigurationStoreFactory() { - return new JAXBConfigurationEntryStoreFactory(new UUIDKeyGenerator(), - contextProvider); + return new JAXBConfigurationEntryStoreFactory(new UUIDKeyGenerator(), contextProvider); } /** @@ -225,8 +221,9 @@ public class JAXBConfigurationEntryStoreTest } copy(resource, name); - - return createConfigurationStoreFactory().getStore(AssignedPermission.class, - name); + return createConfigurationStoreFactory().getStore(new StoreParameters() + .withType(AssignedPermission.class) + .withName(name) + .build()); } } diff --git a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationStoreTest.java b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationStoreTest.java index 4151a6ca20..4f3b99efe0 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationStoreTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBConfigurationStoreTest.java @@ -34,7 +34,7 @@ package sonia.scm.store; /** * Unit tests for {@link JAXBConfigurationStore}. - * + * * @author Sebastian Sdorra */ public class JAXBConfigurationStoreTest extends StoreTestBase { @@ -42,6 +42,6 @@ public class JAXBConfigurationStoreTest extends StoreTestBase { @Override protected ConfigurationStoreFactory createStoreFactory() { - return new JAXBConfigurationStoreFactory(contextProvider); + return new JAXBConfigurationStoreFactory(repositoryLocationResolver); } } diff --git a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBDataStoreTest.java b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBDataStoreTest.java index 9834a48916..e050772e9e 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/store/JAXBDataStoreTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/store/JAXBDataStoreTest.java @@ -34,14 +34,14 @@ package sonia.scm.store; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.repository.Repository; import sonia.scm.security.UUIDKeyGenerator; /** * * @author Sebastian Sdorra */ -public class JAXBDataStoreTest extends DataStoreTestBase -{ +public class JAXBDataStoreTest extends DataStoreTestBase { /** * Method description @@ -52,6 +52,25 @@ public class JAXBDataStoreTest extends DataStoreTestBase @Override protected DataStoreFactory createDataStoreFactory() { - return new JAXBDataStoreFactory(contextProvider, new UUIDKeyGenerator()); + return new JAXBDataStoreFactory(repositoryLocationResolver, new UUIDKeyGenerator()); + } + + @Override + protected DataStore getDataStore(Class type, Repository repository) { + StoreParameters params = new StoreParameters() + .withType(type) + .withName("test") + .forRepository(repository) + .build(); + return createDataStoreFactory().getStore(params); + } + + @Override + protected DataStore getDataStore(Class type) { + StoreParameters params = new StoreParameters() + .withType(type) + .withName("test") + .build(); + return createDataStoreFactory().getStore(params); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/lfs/LfsBlobStoreFactory.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/lfs/LfsBlobStoreFactory.java index eebd6b8f2b..3e4ba67e0f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/lfs/LfsBlobStoreFactory.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/lfs/LfsBlobStoreFactory.java @@ -35,8 +35,10 @@ package sonia.scm.web.lfs; import com.google.inject.Inject; import com.google.inject.Singleton; import sonia.scm.repository.Repository; +import sonia.scm.store.Blob; import sonia.scm.store.BlobStore; import sonia.scm.store.BlobStoreFactory; +import sonia.scm.store.StoreParameters; /** * Creates {@link BlobStore} objects to store lfs objects. @@ -74,7 +76,13 @@ public class LfsBlobStoreFactory { * * @return blob store for the corresponding scm repository */ + @SuppressWarnings("unchecked") public BlobStore getLfsBlobStore(Repository repository) { - return blobStoreFactory.getBlobStore(repository.getId() + GIT_LFS_REPOSITORY_POSTFIX); + return blobStoreFactory.getStore(new StoreParameters() + .withType(Blob.class) + .withName(repository.getId() + GIT_LFS_REPOSITORY_POSTFIX) + .forRepository(repository) + .build() + ); } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryHandlerTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryHandlerTest.java index ace6756cad..3e2734f45e 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryHandlerTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryHandlerTest.java @@ -39,9 +39,12 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.io.DefaultFileSystem; import sonia.scm.schedule.Scheduler; +import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.store.StoreFactory; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import static org.junit.Assert.assertEquals; diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/lfs/LfsBlobStoreFactoryTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/lfs/LfsBlobStoreFactoryTest.java index 991e2655f7..8cc36a2ec4 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/lfs/LfsBlobStoreFactoryTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/lfs/LfsBlobStoreFactoryTest.java @@ -40,7 +40,8 @@ import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.Repository; import sonia.scm.store.BlobStoreFactory; -import static org.mockito.Matchers.matches; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -59,12 +60,17 @@ public class LfsBlobStoreFactoryTest { private LfsBlobStoreFactory lfsBlobStoreFactory; @Test - public void getBlobStore() throws Exception { - lfsBlobStoreFactory.getLfsBlobStore(new Repository("the-id", "GIT", "space", "the-name")); + public void getBlobStore() { + Repository repository = new Repository("the-id", "GIT", "space", "the-name"); + lfsBlobStoreFactory.getLfsBlobStore(repository); // just make sure the right parameter is passed, as properly validating the return value is nearly impossible with // the return value (and should not be part of this test) - verify(blobStoreFactory).getBlobStore(matches("the-id-git-lfs")); + verify(blobStoreFactory).getStore(argThat(blobStoreParameters -> { + assertThat(blobStoreParameters.getName()).isEqualTo("the-id-git-lfs"); + assertThat(blobStoreParameters.getRepository()).isEqualTo(repository); + return true; + })); // make sure there have been no further usages of the factory verifyNoMoreInteractions(blobStoreFactory); diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java index 408f7de24d..76a3266558 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java @@ -39,9 +39,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.io.DefaultFileSystem; +import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.store.StoreFactory; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import static org.junit.Assert.assertEquals; 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 35fd59f715..d13de30599 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 @@ -51,6 +51,7 @@ import sonia.scm.logging.SVNKitLogger; import sonia.scm.plugin.Extension; import sonia.scm.repository.spi.HookEventFacade; import sonia.scm.repository.spi.SvnRepositoryServiceProvider; +import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; import sonia.scm.util.Util; 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 3c644056ca..bfb2aac896 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 @@ -115,7 +115,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase { @Test public void getDirectory() { - when(factory.getStore(any(), any())).thenReturn(store); + when(factory.getStore(any())).thenReturn(store); SvnRepositoryHandler repositoryHandler = new SvnRepositoryHandler(factory, new DefaultFileSystem(), facade, repositoryLocationResolver); diff --git a/scm-test/src/main/java/sonia/scm/AbstractTestBase.java b/scm-test/src/main/java/sonia/scm/AbstractTestBase.java index 13cde0391e..f92c406c22 100644 --- a/scm-test/src/main/java/sonia/scm/AbstractTestBase.java +++ b/scm-test/src/main/java/sonia/scm/AbstractTestBase.java @@ -46,10 +46,15 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; +import sonia.scm.io.DefaultFileSystem; +import sonia.scm.repository.InitialRepositoryLocationResolver; +import sonia.scm.repository.RepositoryDAO; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.util.IOUtil; import sonia.scm.util.MockUtil; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; //~--- JDK imports ------------------------------------------------------------ @@ -66,10 +71,29 @@ import java.util.logging.Logger; public class AbstractTestBase { - /** Field description */ private static ThreadState subjectThreadState; - //~--- methods -------------------------------------------------------------- + protected SCMContextProvider contextProvider; + + private File tempDirectory; + + protected DefaultFileSystem fileSystem; + + protected RepositoryDAO repositoryDAO = mock(RepositoryDAO.class); + protected RepositoryLocationResolver repositoryLocationResolver; + + @Before + public void setUpTest() throws Exception + { + tempDirectory = new File(System.getProperty("java.io.tmpdir"), + UUID.randomUUID().toString()); + assertTrue(tempDirectory.mkdirs()); + contextProvider = MockUtil.getSCMContextProvider(tempDirectory); + fileSystem = new DefaultFileSystem(); + InitialRepositoryLocationResolver initialRepoLocationResolver = new InitialRepositoryLocationResolver(contextProvider,fileSystem); + repositoryLocationResolver = new RepositoryLocationResolver(repositoryDAO, initialRepoLocationResolver); + postSetUp(); + } /** * Method description @@ -165,25 +189,6 @@ public class AbstractTestBase } } - //~--- set methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @throws Exception - */ - @Before - public void setUpTest() throws Exception - { - tempDirectory = new File(System.getProperty("java.io.tmpdir"), - UUID.randomUUID().toString()); - assertTrue(tempDirectory.mkdirs()); - contextProvider = MockUtil.getSCMContextProvider(tempDirectory); - postSetUp(); - } - - //~--- methods -------------------------------------------------------------- /** * Clears Shiro's thread state, ensuring the thread remains clean for @@ -249,12 +254,4 @@ public class AbstractTestBase subjectThreadState = createThreadState(subject); subjectThreadState.bind(); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - protected SCMContextProvider contextProvider; - - /** Field description */ - private File tempDirectory; } diff --git a/scm-test/src/main/java/sonia/scm/ManagerTestBase.java b/scm-test/src/main/java/sonia/scm/ManagerTestBase.java index eda3182638..65f696067b 100644 --- a/scm-test/src/main/java/sonia/scm/ManagerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/ManagerTestBase.java @@ -37,10 +37,13 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; +import sonia.scm.repository.RepositoryLocationResolver; import sonia.scm.util.MockUtil; import java.io.IOException; +import static org.mockito.Mockito.mock; + /** * * @author Sebastian Sdorra @@ -54,12 +57,14 @@ public abstract class ManagerTestBase public TemporaryFolder tempFolder = new TemporaryFolder(); protected SCMContextProvider contextProvider; - + protected RepositoryLocationResolver locationResolver; + protected Manager manager; @Before public void setUp() throws IOException { contextProvider = MockUtil.getSCMContextProvider(tempFolder.newFolder()); + locationResolver = mock(RepositoryLocationResolver.class); manager = createManager(); manager.init(contextProvider); } diff --git a/scm-test/src/main/java/sonia/scm/store/BlobStoreTestBase.java b/scm-test/src/main/java/sonia/scm/store/BlobStoreTestBase.java index 48504feaf2..e30fa4de33 100644 --- a/scm-test/src/main/java/sonia/scm/store/BlobStoreTestBase.java +++ b/scm-test/src/main/java/sonia/scm/store/BlobStoreTestBase.java @@ -35,22 +35,24 @@ package sonia.scm.store; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.io.ByteStreams; - import org.junit.Before; import org.junit.Test; - import sonia.scm.AbstractTestBase; - -import static org.junit.Assert.*; - -//~--- JDK imports ------------------------------------------------------------ +import sonia.scm.repository.RepositoryTestData; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; - import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +//~--- JDK imports ------------------------------------------------------------ + /** * * @author Sebastian Sdorra @@ -58,12 +60,6 @@ import java.util.List; public abstract class BlobStoreTestBase extends AbstractTestBase { - /** - * Method description - * - * - * @return - */ protected abstract BlobStoreFactory createBlobStoreFactory(); /** @@ -73,7 +69,12 @@ public abstract class BlobStoreTestBase extends AbstractTestBase @Before public void createBlobStore() { - store = createBlobStoreFactory().getBlobStore("test"); + store = createBlobStoreFactory().getStore(new StoreParameters() + .withType(Blob.class) + .withName("test") + .forRepository(RepositoryTestData.createHeartOfGold()) + .build() + ); store.clear(); } diff --git a/scm-test/src/main/java/sonia/scm/store/ConfigurationEntryStoreTestBase.java b/scm-test/src/main/java/sonia/scm/store/ConfigurationEntryStoreTestBase.java index 8d3a63717a..55c92b2376 100644 --- a/scm-test/src/main/java/sonia/scm/store/ConfigurationEntryStoreTestBase.java +++ b/scm-test/src/main/java/sonia/scm/store/ConfigurationEntryStoreTestBase.java @@ -32,12 +32,13 @@ package sonia.scm.store; +import sonia.scm.repository.Repository; + /** * * @author Sebastian Sdorra */ -public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestBase -{ +public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestBase { /** * Method description @@ -48,17 +49,22 @@ public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestB protected abstract ConfigurationEntryStoreFactory createConfigurationStoreFactory(); //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ @Override - protected ConfigurationEntryStore getDataStore() - { - return createConfigurationStoreFactory().getStore(StoreObject.class, - "test"); + protected ConfigurationEntryStore getDataStore(Class type) { + StoreParameters params = new StoreParameters() + .withType(type) + .withName("test") + .build(); + return this.createConfigurationStoreFactory().getStore(params); + } + + @Override + protected ConfigurationEntryStore getDataStore(Class type, Repository repository) { + StoreParameters params = new StoreParameters() + .withType(type) + .withName("test") + .forRepository(repository) + .build(); + return this.createConfigurationStoreFactory().getStore(params); } } diff --git a/scm-test/src/main/java/sonia/scm/store/DataStoreTestBase.java b/scm-test/src/main/java/sonia/scm/store/DataStoreTestBase.java index 3129d3a339..839baaa616 100644 --- a/scm-test/src/main/java/sonia/scm/store/DataStoreTestBase.java +++ b/scm-test/src/main/java/sonia/scm/store/DataStoreTestBase.java @@ -33,6 +33,13 @@ package sonia.scm.store; +import org.junit.Test; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryTestData; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + /** * * @author Sebastian Sdorra @@ -48,17 +55,33 @@ public abstract class DataStoreTestBase extends KeyValueStoreTestBase */ protected abstract DataStoreFactory createDataStoreFactory(); + + protected StoreParameters getStoreParametersWithRepository(Repository repository) { + return new StoreParameters() + .withType(StoreObject.class) + .withName("test") + .forRepository(repository) + .build(); + } //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * - * @return - */ - @Override - protected DataStore getDataStore() + + + + @Test + // TODO + public void shouldStoreRepositorySpecificData() { - return createDataStoreFactory().getStore(StoreObject.class, "test"); + StoreFactory dataStoreFactory = createDataStoreFactory(); + StoreObject obj = new StoreObject("test-1"); + Repository repository = RepositoryTestData.createHeartOfGold(); + + DataStore store = dataStoreFactory.getStore(getStoreParametersWithRepository(repository)); + + String id = store.put(obj); + + assertNotNull(id); + + assertEquals(obj, store.get(id)); } } diff --git a/scm-test/src/main/java/sonia/scm/store/InMemoryConfigurationStoreFactory.java b/scm-test/src/main/java/sonia/scm/store/InMemoryConfigurationStoreFactory.java index d5e9474ff5..021b7bda02 100644 --- a/scm-test/src/main/java/sonia/scm/store/InMemoryConfigurationStoreFactory.java +++ b/scm-test/src/main/java/sonia/scm/store/InMemoryConfigurationStoreFactory.java @@ -43,8 +43,7 @@ package sonia.scm.store; public class InMemoryConfigurationStoreFactory implements ConfigurationStoreFactory { @Override - public ConfigurationStore getStore(Class type, String name) - { + public ConfigurationStore getStore(StoreParameters storeParameters) { return new InMemoryConfigurationStore<>(); } } diff --git a/scm-test/src/main/java/sonia/scm/store/KeyValueStoreTestBase.java b/scm-test/src/main/java/sonia/scm/store/KeyValueStoreTestBase.java index 0abad4f558..b1cdf8431e 100644 --- a/scm-test/src/main/java/sonia/scm/store/KeyValueStoreTestBase.java +++ b/scm-test/src/main/java/sonia/scm/store/KeyValueStoreTestBase.java @@ -38,6 +38,8 @@ import org.junit.Before; import org.junit.Test; import sonia.scm.AbstractTestBase; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryTestData; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -56,13 +58,19 @@ import java.util.Map; public abstract class KeyValueStoreTestBase extends AbstractTestBase { + private Repository repository = RepositoryTestData.createHeartOfGold(); + private DataStore store; + private DataStore repoStore; + /** * Method description * * * @return */ - protected abstract DataStore getDataStore(); + protected abstract DataStore getDataStore(Class type , Repository repository); + protected abstract DataStore getDataStore(Class type ); + //~--- methods -------------------------------------------------------------- @@ -73,8 +81,10 @@ public abstract class KeyValueStoreTestBase extends AbstractTestBase @Before public void before() { - store = getDataStore(); + store = getDataStore(StoreObject.class); + repoStore = getDataStore(StoreObject.class, repository); store.clear(); + repoStore.clear(); } /** @@ -215,8 +225,5 @@ public abstract class KeyValueStoreTestBase extends AbstractTestBase assertNull(store.get("2")); } - //~--- fields --------------------------------------------------------------- - /** Field description */ - private DataStore store; } diff --git a/scm-test/src/main/java/sonia/scm/store/StoreTestBase.java b/scm-test/src/main/java/sonia/scm/store/StoreTestBase.java index c39efa3ffe..fd9afaff08 100644 --- a/scm-test/src/main/java/sonia/scm/store/StoreTestBase.java +++ b/scm-test/src/main/java/sonia/scm/store/StoreTestBase.java @@ -35,10 +35,12 @@ package sonia.scm.store; //~--- non-JDK imports -------------------------------------------------------- import org.junit.Test; - import sonia.scm.AbstractTestBase; +import sonia.scm.repository.Repository; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; //~--- JDK imports ------------------------------------------------------------ @@ -58,6 +60,13 @@ public abstract class StoreTestBase extends AbstractTestBase */ protected abstract ConfigurationStoreFactory createStoreFactory(); + protected StoreParameters getStoreParameters() { + return new StoreParameters() + .withType(StoreObject.class) + .withName("test") + .build(); + } + /** * Method description * @@ -65,8 +74,7 @@ public abstract class StoreTestBase extends AbstractTestBase @Test public void testGet() { - ConfigurationStore store = createStoreFactory().getStore(StoreObject.class, - "test"); + ConfigurationStore store = createStoreFactory().getStore(getStoreParameters()); assertNotNull(store); @@ -82,8 +90,7 @@ public abstract class StoreTestBase extends AbstractTestBase @Test public void testSet() { - ConfigurationStore store = createStoreFactory().getStore(StoreObject.class, - "test"); + ConfigurationStore store = createStoreFactory().getStore(getStoreParameters()); assertNotNull(store); diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java index d958dcf41f..afbe3e00d3 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java +++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java @@ -55,6 +55,7 @@ import sonia.scm.event.ScmEventBus; import sonia.scm.group.GroupEvent; import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; +import sonia.scm.store.StoreParameters; import sonia.scm.user.UserEvent; import sonia.scm.util.ClassLoaders; @@ -108,9 +109,13 @@ public class DefaultSecuritySystem implements SecuritySystem * @param storeFactory */ @Inject + @SuppressWarnings("unchecked") public DefaultSecuritySystem(ConfigurationEntryStoreFactory storeFactory) { - store = storeFactory.getStore(AssignedPermission.class, NAME); + store = storeFactory.getStore(new StoreParameters() + .withType(AssignedPermission.class) + .withName(NAME) + .build()); readAvailablePermissions(); } diff --git a/scm-webapp/src/main/java/sonia/scm/security/SecureKeyResolver.java b/scm-webapp/src/main/java/sonia/scm/security/SecureKeyResolver.java index c7c594d5e3..31556afef4 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/SecureKeyResolver.java +++ b/scm-webapp/src/main/java/sonia/scm/security/SecureKeyResolver.java @@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; +import sonia.scm.store.StoreParameters; import static com.google.common.base.Preconditions.*; @@ -87,9 +88,13 @@ public class SecureKeyResolver extends SigningKeyResolverAdapter * @param storeFactory store factory */ @Inject + @SuppressWarnings("unchecked") public SecureKeyResolver(ConfigurationEntryStoreFactory storeFactory) { - this.store = storeFactory.getStore(SecureKey.class, STORE_NAME); + store = storeFactory.getStore(new StoreParameters() + .withType(SecureKey.class) + .withName(STORE_NAME) + .build()); } //~--- methods -------------------------------------------------------------- diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java index 2cab41bfbf..1dc93522a1 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java @@ -66,7 +66,7 @@ public class AutoCompleteResourceTest { ConfigurationStore storeConfig = mock(ConfigurationStore.class); xmlDB = mock(XmlDatabase.class); when(storeConfig.get()).thenReturn(xmlDB); - when(storeFactory.getStore(any(), any())).thenReturn(storeConfig); + when(storeFactory.getStore(any())).thenReturn(storeConfig); XmlUserDAO userDao = new XmlUserDAO(storeFactory); this.userDao = spy(userDao); XmlGroupDAO groupDAO = new XmlGroupDAO(storeFactory); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index ab7e3aafd9..3e2a77ff0f 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -422,10 +422,10 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase { private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) { DefaultFileSystem fileSystem = new DefaultFileSystem(); Set handlerSet = new HashSet<>(); - ConfigurationStoreFactory factory = new JAXBConfigurationStoreFactory(contextProvider); InitialRepositoryLocationResolver initialRepositoryLocationResolver = new InitialRepositoryLocationResolver(contextProvider, fileSystem); - XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(factory, initialRepositoryLocationResolver); + XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(initialRepositoryLocationResolver, contextProvider); RepositoryLocationResolver repositoryLocationResolver = new RepositoryLocationResolver(repositoryDAO, initialRepositoryLocationResolver); + ConfigurationStoreFactory factory = new JAXBConfigurationStoreFactory(repositoryLocationResolver); handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver)); handlerSet.add(new DummyRepositoryHandler(factory, repositoryLocationResolver) { @Override diff --git a/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java b/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java index 8d708c4677..81b237de2a 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/SecureKeyResolverTest.java @@ -36,20 +36,21 @@ package sonia.scm.security; //~--- non-JDK imports -------------------------------------------------------- import io.jsonwebtoken.Jwts; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; - import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; -import static org.junit.Assert.*; - -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * @@ -122,11 +123,13 @@ public class SecureKeyResolverTest @Before public void setUp() { - ConfigurationEntryStoreFactory factory = - mock(ConfigurationEntryStoreFactory.class); + ConfigurationEntryStoreFactory factory = mock(ConfigurationEntryStoreFactory.class); - when(factory.getStore(SecureKey.class, - SecureKeyResolver.STORE_NAME)).thenReturn(store); + when(factory.getStore(argThat(storeParameters -> { + assertThat(storeParameters.getName()).isEqualTo(SecureKeyResolver.STORE_NAME); + assertThat(storeParameters.getType()).isEqualTo(SecureKey.class); + return true; + }))).thenReturn(store); resolver = new SecureKeyResolver(factory); } diff --git a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java index 1614bf790a..ebfe47a343 100644 --- a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java @@ -182,6 +182,6 @@ public class DefaultUserManagerTest extends UserManagerTestBase //~--- methods -------------------------------------------------------------- private XmlUserDAO createXmlUserDAO() { - return new XmlUserDAO(new JAXBConfigurationStoreFactory(contextProvider)); + return new XmlUserDAO(new JAXBConfigurationStoreFactory(locationResolver)); } }