From 5ef1b4fb2deec11d15aa8943cb30bd2bb4e888ae Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 7 Jun 2011 12:14:30 +0000 Subject: [PATCH] Improve migration git-svn-id: https://svn.argeo.org/commons/trunk@4566 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../argeo/jackrabbit/JackrabbitContainer.java | 133 +++++++++++------- .../JackrabbitDataModelMigration.java | 61 +++++--- 2 files changed, 124 insertions(+), 70 deletions(-) diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java index e27a473b5..c897b6bea 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java @@ -35,6 +35,7 @@ import java.util.concurrent.Executor; import javax.jcr.Credentials; import javax.jcr.LoginException; import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -53,6 +54,7 @@ import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory; import org.argeo.ArgeoException; +import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.JcrUtils; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; @@ -68,16 +70,17 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { private Log log = LogFactory.getLog(JackrabbitContainer.class); private Resource configuration; - private String homeDirectory; + private File homeDirectory; private Resource variables; - /** cache home */ - private File home; private Boolean inMemory = false; private String uri = null; + // wrapped repository private Repository repository; + private RepositoryConfig repositoryConfig; + // CND private ResourceLoader resourceLoader; /** Node type definitions in CND format */ @@ -100,7 +103,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { return; } - repository = createJackrabbitRepository(); + createJackrabbitRepository(); // migrate if needed migrate(); @@ -111,8 +114,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } /** Actually creates a new repository. */ - protected JackrabbitRepository createJackrabbitRepository() { - JackrabbitRepository repository; + protected void createJackrabbitRepository() { try { // remote repository if (uri != null && !uri.trim().equals("")) { @@ -130,23 +132,24 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { // do not perform further initialization since we assume that // the // remote repository has been properly configured - return repository; + return; } // local repository - if (inMemory && getHome().exists()) { - FileUtils.deleteDirectory(getHome()); - log.warn("Deleted Jackrabbit home directory " + getHome()); + if (inMemory && getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); + log.warn("Deleted Jackrabbit home directory " + + getHomeDirectory()); } - RepositoryConfig config; Properties vars = getConfigurationProperties(); InputStream in = configuration.getInputStream(); try { vars.put( RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, - getHome().getCanonicalPath()); - config = RepositoryConfig.create(new InputSource(in), vars); + getHomeDirectory().getCanonicalPath()); + repositoryConfig = RepositoryConfig.create(new InputSource(in), + vars); } catch (Exception e) { throw new RuntimeException("Cannot read configuration", e); } finally { @@ -154,17 +157,15 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } if (inMemory) - repository = new TransientRepository(config); + repository = new TransientRepository(repositoryConfig); else - repository = RepositoryImpl.create(config); + repository = RepositoryImpl.create(repositoryConfig); log.info("Initialized Jackrabbit repository " + repository + " in " - + getHome() + " with config " + configuration); - - return repository; + + getHomeDirectory() + " with config " + configuration); } catch (Exception e) { throw new ArgeoException("Cannot create Jackrabbit repository " - + getHome(), e); + + getHomeDirectory(), e); } } @@ -192,35 +193,63 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { // restart repository if (restartAndClearCaches) { + JackrabbitDataModelMigration + .clearRepositoryCaches(repositoryConfig); ((JackrabbitRepository) repository).shutdown(); - JackrabbitDataModelMigration.clearRepositoryCaches(getHome()); - repository = createJackrabbitRepository(); + createJackrabbitRepository(); } - } - - /** Lazy init. */ - protected File getHome() { - if (home != null) - return home; + // set data model version try { - String osgiData = System.getProperty("osgi.instance.area"); - if (osgiData != null) - osgiData = osgiData.substring("file:".length()); - String path; - if (homeDirectory == null) - path = "./jackrabbit"; - else - path = homeDirectory; - if (path.startsWith(".") && osgiData != null) { - home = new File(osgiData + '/' + path).getCanonicalFile(); - } else - home = new File(path).getCanonicalFile(); - return home; - } catch (Exception e) { - throw new ArgeoException("Cannot define Jackrabbit home based on " - + homeDirectory, e); + session = login(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot login to migrated repository", e); } + + for (JackrabbitDataModelMigration dataModelMigration : new TreeSet( + dataModelMigrations)) { + try { + if (session.itemExists(dataModelMigration + .getDataModelNodePath())) { + Node dataModelNode = session.getNode(dataModelMigration + .getDataModelNodePath()); + dataModelNode.setProperty( + ArgeoNames.ARGEO_DATA_MODEL_VERSION, + dataModelMigration.getTargetVersion()); + session.save(); + } + } catch (Exception e) { + log.error("Cannot set model version", e); + } + } + JcrUtils.logoutQuietly(session); + + } + + /** Lazy init. */ + protected File getHomeDirectory() { + return homeDirectory; + // if (home != null) + // return home; + // + // try { + // String osgiData = System.getProperty("osgi.instance.area"); + // if (osgiData != null) + // osgiData = osgiData.substring("file:".length()); + // String path; + // if (homeDirectory == null) + // path = "./jackrabbit"; + // else + // path = homeDirectory; + // if (path.startsWith(".") && osgiData != null) { + // home = new File(osgiData + '/' + path).getCanonicalFile(); + // } else + // home = new File(path).getCanonicalFile(); + // return home; + // } catch (Exception e) { + // throw new ArgeoException("Cannot define Jackrabbit home based on " + // + homeDirectory, e); + // } } public void dispose() throws Exception { @@ -234,17 +263,18 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } if (inMemory) - if (getHome().exists()) { - FileUtils.deleteDirectory(getHome()); + if (getHomeDirectory().exists()) { + FileUtils.deleteDirectory(getHomeDirectory()); if (log.isDebugEnabled()) - log.debug("Deleted Jackrabbit home directory " + getHome()); + log.debug("Deleted Jackrabbit home directory " + + getHomeDirectory()); } if (uri != null && !uri.trim().equals("")) log.info("Destroyed Jackrabbit repository with uri " + uri); else log.info("Destroyed Jackrabbit repository " + repository + " in " - + getHome() + " with config " + configuration); + + getHomeDirectory() + " with config " + configuration); } /** @@ -278,6 +308,13 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } // override with system properties vars.putAll(System.getProperties()); + + if (log.isTraceEnabled()) { + log.trace("Jackrabbit config variables:"); + for (Object key : new TreeSet(vars.keySet())) + log.trace(key + "=" + vars.getProperty(key.toString())); + } + } catch (IOException e) { throw new ArgeoException("Cannot read configuration properties", e); } finally { @@ -423,7 +460,7 @@ public class JackrabbitContainer implements Repository, ResourceLoaderAware { } // BEANS METHODS - public void setHomeDirectory(String homeDirectory) { + public void setHomeDirectory(File homeDirectory) { this.homeDirectory = homeDirectory; } diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitDataModelMigration.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitDataModelMigration.java index 37d852907..fd8d44412 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitDataModelMigration.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitDataModelMigration.java @@ -1,6 +1,5 @@ package org.argeo.jackrabbit; -import java.io.File; import java.io.InputStreamReader; import java.io.Reader; @@ -11,6 +10,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.commons.cnd.CndImporter; +import org.apache.jackrabbit.core.config.RepositoryConfig; import org.argeo.ArgeoException; import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.JcrCallback; @@ -35,17 +35,17 @@ public class JackrabbitDataModelMigration implements * @return true if a migration was performed and the repository needs to be * restarted and its caches cleared. */ - public Boolean migrate(Session adminSession) { + public Boolean migrate(Session session) { long begin = System.currentTimeMillis(); Reader reader = null; try { // check if already migrated - if (!adminSession.itemExists(dataModelNodePath)) { + if (!session.itemExists(dataModelNodePath)) { log.warn("Node " + dataModelNodePath + " does not exist: nothing to migrate."); return false; } - Node dataModelNode = adminSession.getNode(dataModelNodePath); + Node dataModelNode = session.getNode(dataModelNodePath); if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) { String currentVersion = dataModelNode.getProperty( ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString(); @@ -57,30 +57,30 @@ public class JackrabbitDataModelMigration implements } // apply transitional CND - reader = new InputStreamReader(migrationCnd.getInputStream()); - CndImporter.registerNodeTypes(reader, adminSession, true); + if (migrationCnd != null) { + reader = new InputStreamReader(migrationCnd.getInputStream()); + CndImporter.registerNodeTypes(reader, session, true); + session.save(); + log.info("Registered migration node types from " + migrationCnd); + } // modify data - dataModification.execute(adminSession); - - // set data model version - dataModelNode.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION, - targetVersion); + dataModification.execute(session); // apply changes - adminSession.save(); + session.save(); long duration = System.currentTimeMillis() - begin; log.info("Migration of data model " + dataModelNodePath + " to " + targetVersion + " performed in " + duration + "ms"); return true; } catch (Exception e) { - JcrUtils.discardQuietly(adminSession); + JcrUtils.discardQuietly(session); throw new ArgeoException("Migration of data model " + dataModelNodePath + " to " + targetVersion + " failed.", e); } finally { - JcrUtils.logoutQuietly(adminSession); + JcrUtils.logoutQuietly(session); IOUtils.closeQuietly(reader); } } @@ -91,16 +91,25 @@ public class JackrabbitDataModelMigration implements } /** To be called on a stopped repository. */ - public static void clearRepositoryCaches(File home) { - File customNodeTypes = new File(home.getPath() - + "/repository/nodetypes/custom_nodetypes.xml"); - if (customNodeTypes.exists()) { - customNodeTypes.delete(); + public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) { + try { + String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml"; + repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath); if (log.isDebugEnabled()) - log.debug("Cleared " + customNodeTypes); - } else { - log.warn("File " + customNodeTypes + " not found."); + log.debug("Cleared " + customeNodeTypesPath); + } catch (Exception e) { + throw new ArgeoException("Cannot clear caches", e); } + + // File customNodeTypes = new File(home.getPath() + // + "/repository/nodetypes/custom_nodetypes.xml"); + // if (customNodeTypes.exists()) { + // customNodeTypes.delete(); + // if (log.isDebugEnabled()) + // log.debug("Cleared " + customNodeTypes); + // } else { + // log.warn("File " + customNodeTypes + " not found."); + // } } /* @@ -147,4 +156,12 @@ public class JackrabbitDataModelMigration implements this.dataModification = dataModification; } + public String getDataModelNodePath() { + return dataModelNodePath; + } + + public String getTargetVersion() { + return targetVersion; + } + } -- 2.30.2