First steps to create a bootstrap module for data migration

This commit is contained in:
René Pfeuffer
2019-05-09 10:36:27 +02:00
parent f7c4ec06ce
commit d29fa32c8e
6 changed files with 176 additions and 35 deletions

View File

@@ -132,7 +132,7 @@ public class RepositoryPermission implements PermissionObject, Serializable
{
// Normally we do not have a log of repository permissions having the same size of verbs, but different content.
// Therefore we do not use the verbs themselves for the hash code but only the number of verbs.
return Objects.hashCode(name, verbs.size(), groupPermission);
return Objects.hashCode(name, verbs == null? -1: verbs.size(), groupPermission);
}

View File

@@ -184,6 +184,12 @@
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
<version>${guice.version}</version>
</dependency>
<!-- event bus -->
<dependency>

View File

@@ -0,0 +1,102 @@
package sonia.scm;
import com.google.inject.AbstractModule;
import com.google.inject.throwingproviders.ThrowingProviderBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.DefaultPluginLoader;
import sonia.scm.repository.RepositoryDAO;
import sonia.scm.repository.xml.XmlRepositoryDAO;
import sonia.scm.security.CipherUtil;
import sonia.scm.security.DefaultKeyGenerator;
import sonia.scm.security.KeyGenerator;
import sonia.scm.store.BlobStoreFactory;
import sonia.scm.store.ConfigurationEntryStoreFactory;
import sonia.scm.store.ConfigurationStoreFactory;
import sonia.scm.store.DataStoreFactory;
import sonia.scm.store.FileBlobStoreFactory;
import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
import sonia.scm.store.JAXBConfigurationStoreFactory;
import sonia.scm.store.JAXBDataStoreFactory;
import sonia.scm.util.ScmConfigurationUtil;
public class BootstrapModule extends AbstractModule {
private static final Logger LOG = LoggerFactory.getLogger(BootstrapModule.class);
private final ClassOverrides overrides;
private final DefaultPluginLoader pluginLoader;
public BootstrapModule(ClassOverrides overrides, DefaultPluginLoader pluginLoader) {
this.overrides = overrides;
this.pluginLoader = pluginLoader;
}
@Override
protected void configure() {
install(ThrowingProviderBinder.forModule(this));
ScmConfiguration config = getScmConfiguration();
CipherUtil cu = CipherUtil.getInstance();
SCMContextProvider context = SCMContext.getContext();
bind(SCMContextProvider.class).toInstance(context);
bind(KeyGenerator.class).to(DefaultKeyGenerator.class);
bind(RepositoryDAO.class, XmlRepositoryDAO.class);
bind(FileSystem.class, DefaultFileSystem.class);
// bind core
bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class);
bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class);
bind(DataStoreFactory.class, JAXBDataStoreFactory.class);
bind(BlobStoreFactory.class, FileBlobStoreFactory.class);
// bind(ScmConfiguration.class).toInstance(config);
// bind(PluginLoader.class).toInstance(pluginLoader);
// bind(PluginManager.class, DefaultPluginManager.class);
// note CipherUtil uses an other generator
// bind(KeyGenerator.class).to(DefaultKeyGenerator.class);
// bind(CipherHandler.class).toInstance(cu.getCipherHandler());
// bind(FileSystem.class, DefaultFileSystem.class);
}
private <T> void bind(Class<T> clazz, Class<? extends T> defaultImplementation) {
Class<? extends T> implementation = find(clazz, defaultImplementation);
LOG.debug("bind {} to {}", clazz, implementation);
bind(clazz).to(implementation);
}
private <T> Class<? extends T> find(Class<T> clazz, Class<? extends T> defaultImplementation) {
Class<? extends T> implementation = overrides.getOverride(clazz);
if (implementation != null) {
LOG.info("found override {} for {}", implementation, clazz);
} else {
implementation = defaultImplementation;
LOG.trace(
"no override available for {}, using default implementation {}",
clazz, implementation);
}
return implementation;
}
private ScmConfiguration getScmConfiguration() {
ScmConfiguration configuration = new ScmConfiguration();
ScmConfigurationUtil.getInstance().load(configuration);
return configuration;
}
}

View File

@@ -37,6 +37,7 @@ import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.assistedinject.Assisted;
import org.apache.shiro.guice.web.ShiroWebModule;
import org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener;
import org.slf4j.Logger;
@@ -55,6 +56,7 @@ import sonia.scm.upgrade.UpgradeManager;
import sonia.scm.user.UserManager;
import sonia.scm.util.IOUtil;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import java.util.Collections;
@@ -77,9 +79,12 @@ public class ScmContextListener extends GuiceResteasyBootstrapServletContextList
private final Set<PluginWrapper> plugins;
private Injector injector;
//~--- constructors ---------------------------------------------------------
public interface Factory {
ScmContextListener create(ClassLoader parent, Set<PluginWrapper> plugins);
}
public ScmContextListener(ClassLoader parent, Set<PluginWrapper> plugins)
@Inject
public ScmContextListener(@Assisted ClassLoader parent, @Assisted Set<PluginWrapper> plugins)
{
this.parent = parent;
this.plugins = plugins;

View File

@@ -208,9 +208,9 @@ public class ScmServletModule extends ServletModule
{
install(ThrowingProviderBinder.forModule(this));
SCMContextProvider context = SCMContext.getContext();
bind(SCMContextProvider.class).toInstance(context);
// SCMContextProvider context = SCMContext.getContext();
//
// bind(SCMContextProvider.class).toInstance(context);
ScmConfiguration config = getScmConfiguration();
CipherUtil cu = CipherUtil.getInstance();
@@ -230,10 +230,10 @@ public class ScmServletModule extends ServletModule
bind(ScmEventBus.class).toInstance(ScmEventBus.getInstance());
// bind core
bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class);
bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class);
bind(DataStoreFactory.class, JAXBDataStoreFactory.class);
bind(BlobStoreFactory.class, FileBlobStoreFactory.class);
// bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class);
// bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class);
// bind(DataStoreFactory.class, JAXBDataStoreFactory.class);
// bind(BlobStoreFactory.class, FileBlobStoreFactory.class);
bind(ScmConfiguration.class).toInstance(config);
bind(PluginLoader.class).toInstance(pluginLoader);
bind(PluginManager.class, DefaultPluginManager.class);
@@ -242,9 +242,9 @@ public class ScmServletModule extends ServletModule
bind(Scheduler.class).to(QuartzScheduler.class);
// note CipherUtil uses an other generator
bind(KeyGenerator.class).to(DefaultKeyGenerator.class);
// bind(KeyGenerator.class).to(DefaultKeyGenerator.class);
bind(CipherHandler.class).toInstance(cu.getCipherHandler());
bind(FileSystem.class, DefaultFileSystem.class);
// bind(FileSystem.class, DefaultFileSystem.class);
// bind health check stuff
bind(HealthCheckContextListener.class);
@@ -266,7 +266,7 @@ public class ScmServletModule extends ServletModule
// bind dao
bind(GroupDAO.class, XmlGroupDAO.class);
bind(UserDAO.class, XmlUserDAO.class);
bind(RepositoryDAO.class, XmlRepositoryDAO.class);
// bind(RepositoryDAO.class, XmlRepositoryDAO.class);
bindDecorated(RepositoryManager.class, DefaultRepositoryManager.class,
RepositoryManagerProvider.class);

View File

@@ -28,22 +28,25 @@
*/
package sonia.scm.boot;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.BootstrapModule;
import sonia.scm.ClassOverrides;
import sonia.scm.SCMContext;
import sonia.scm.ScmContextListener;
import sonia.scm.Stage;
import sonia.scm.event.ScmEventBus;
import sonia.scm.plugin.DefaultPluginLoader;
import sonia.scm.plugin.Plugin;
import sonia.scm.plugin.PluginException;
import sonia.scm.plugin.PluginLoadException;
@@ -53,29 +56,23 @@ import sonia.scm.plugin.SmpArchive;
import sonia.scm.util.ClassLoaders;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.xml.bind.DataBindingException;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
*
@@ -161,7 +158,38 @@ public class BootstrapContextListener implements ServletContextListener
Set<PluginWrapper> plugins = PluginsInternal.collectPlugins(cl,
pluginDirectory.toPath());
contextListener = new ScmContextListener(cl, plugins);
Module scmContextListenerModule = new AbstractModule() {
@Override
protected void configure() {
install(new FactoryModuleBuilder().build(ScmContextListener.Factory.class));
}
};
DefaultPluginLoader pluginLoader = new DefaultPluginLoader(context, cl, plugins);
Injector bootstrapInjector = Guice.createInjector(new BootstrapModule(
ClassOverrides.findOverrides(pluginLoader.getUberClassLoader()),
pluginLoader
),
scmContextListenerModule
);
contextListener = bootstrapInjector.getInstance(ScmContextListener.Factory.class).create(cl, plugins);
// Set<MigrationStep> steps = bootstrapInjector.getInstance(....);
// migrate
// contextListener = new ScmContextListener(cl, plugins);
}
catch (IOException ex)
{