Start working on maintenance
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 6 Nov 2015 17:10:32 +0000 (17:10 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 6 Nov 2015 17:10:32 +0000 (17:10 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8548 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java
org.argeo.cms/src/org/argeo/cms/maintenance/DataMigration.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/maintenance/MaintenanceUi.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/maintenance/MigrationEntryPoint.java [new file with mode: 0644]

diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/RepositoryMigration.java
new file mode 100644 (file)
index 0000000..82f6fef
--- /dev/null
@@ -0,0 +1,69 @@
+package org.argeo.cms.internal.backup;
+
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.cms.maintenance.DataMigration;
+import org.argeo.jcr.JcrUtils;
+
+/** Migrate data between two workspaces, at JCR level. */
+public class RepositoryMigration implements PrivilegedExceptionAction<Boolean> {
+       private final Repository sourceRepository;
+       private final Repository targetRepository;
+       private final DataMigration dataMigration;
+
+       private Credentials sourceCredentials = null;
+       private Credentials targetCredentials = null;
+
+       public RepositoryMigration(Repository sourceRepository,
+                       Repository targetRepository, DataMigration dataMigration) {
+               this.sourceRepository = sourceRepository;
+               this.targetRepository = targetRepository;
+               this.dataMigration = dataMigration;
+       }
+
+       @Override
+       public Boolean run() throws Exception {
+               Map<String, String> wk = dataMigration.workspacesToMigrate();
+               if (wk == null)
+                       return migrate(sourceRepository, null, targetRepository, null);
+               else {
+                       for (String sourceWorkspace : wk.keySet()) {
+                               String targetWorkspace = wk.get(sourceWorkspace);
+                               boolean ok = migrate(sourceRepository, sourceWorkspace,
+                                               targetRepository, targetWorkspace);
+                               if (!ok)
+                                       return false;
+                       }
+                       return true;
+               }
+       }
+
+       protected final boolean migrate(Repository sourceRepository,
+                       String sourceWorkspace, Repository targetRepository,
+                       String targetWorkspace) throws RepositoryException {
+               Session source = null, target = null;
+               try {
+                       source = sourceRepository.login(sourceCredentials, sourceWorkspace);
+                       target = targetRepository.login(targetCredentials, targetWorkspace);
+                       return dataMigration.migrate(source, target);
+               } finally {
+                       JcrUtils.logoutQuietly(source);
+                       JcrUtils.logoutQuietly(target);
+               }
+       }
+
+       public void setSourceCredentials(Credentials sourceCredentials) {
+               this.sourceCredentials = sourceCredentials;
+       }
+
+       public void setTargetCredentials(Credentials targetCredentials) {
+               this.targetCredentials = targetCredentials;
+       }
+
+}
index d16ce555a01e962c2cd5f69e8913048d7c0bcc46..1f562b817cfeff0f1bcafeb3bfb222d96c537750 100644 (file)
@@ -41,6 +41,7 @@ import org.apache.jackrabbit.util.TransientFileFactory;
 import org.argeo.ArgeoException;
 import org.argeo.ArgeoLogger;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.maintenance.MaintenanceUi;
 import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
 import org.argeo.jcr.ArgeoJcrConstants;
 import org.argeo.jcr.ArgeoJcrUtils;
@@ -53,6 +54,7 @@ import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.startlevel.BundleStartLevel;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.log.LogReaderService;
@@ -113,6 +115,7 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener {
        private List<Locale> locales = null;
 
        public Kernel() {
+               // KernelUtils.logFrameworkProperties(log);
                nodeSecurity = new NodeSecurity();
        }
 
@@ -129,7 +132,6 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener {
 
        private void doInit() {
                long begin = System.currentTimeMillis();
-               ConfigurationAdmin conf = findConfigurationAdmin();
                // Use CMS bundle classloader
                ClassLoader currentContextCl = Thread.currentThread()
                                .getContextClassLoader();
@@ -149,35 +151,10 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener {
                        logger = new NodeLogger(logReaderService.getService());
                        logReaderService.close();
 
-                       // KernelUtils.logFrameworkProperties(log);
-
-                       // Initialise services
-                       initTransactionManager();
-                       if (repository == null)
-                               repository = new NodeRepository();
-                       if (repositoryFactory == null)
-                               repositoryFactory = new OsgiJackrabbitRepositoryFactory();
-                       userAdmin = new NodeUserAdmin(transactionManager, repository);
-
-                       // HTTP
-                       initWebServer(conf);
-                       ServiceReference<ExtendedHttpService> sr = bc
-                                       .getServiceReference(ExtendedHttpService.class);
-                       if (sr != null)
-                               addHttpService(sr);
-
-                       UserUi userUi = new UserUi();
-                       Hashtable<String, String> props = new Hashtable<String, String>();
-                       props.put("contextName", "user");
-                       bc.registerService(ApplicationConfiguration.class, userUi, props);
-
-                       // Kernel thread
-                       kernelThread = new KernelThread(this);
-                       kernelThread.setContextClassLoader(Kernel.class.getClassLoader());
-                       kernelThread.start();
-
-                       // Publish services to OSGi
-                       publish();
+                       if (isMaintenance())
+                               maintenanceInit();
+                       else
+                               normalInit();
                } catch (Exception e) {
                        log.error("Cannot initialize Argeo CMS", e);
                        throw new ArgeoException("Cannot initialize", e);
@@ -194,6 +171,63 @@ final class Kernel implements KernelHeader, KernelConstants, ServiceListener {
                directorsCut(initDuration);
        }
 
+       private void normalInit() {
+               ConfigurationAdmin conf = findConfigurationAdmin();
+               // Initialise services
+               initTransactionManager();
+               if (repository == null)
+                       repository = new NodeRepository();
+               if (repositoryFactory == null)
+                       repositoryFactory = new OsgiJackrabbitRepositoryFactory();
+               userAdmin = new NodeUserAdmin(transactionManager, repository);
+
+               // HTTP
+               initWebServer(conf);
+               ServiceReference<ExtendedHttpService> sr = bc
+                               .getServiceReference(ExtendedHttpService.class);
+               if (sr != null)
+                       addHttpService(sr);
+
+               // ADMIN UIs
+               UserUi userUi = new UserUi();
+               Hashtable<String, String> props = new Hashtable<String, String>();
+               props.put("contextName", "user");
+               bc.registerService(ApplicationConfiguration.class, userUi, props);
+
+               // Kernel thread
+               kernelThread = new KernelThread(this);
+               kernelThread.setContextClassLoader(Kernel.class.getClassLoader());
+               kernelThread.start();
+
+               // Publish services to OSGi
+               publish();
+       }
+
+       private boolean isMaintenance() {
+               String startLevel = KernelUtils.getFrameworkProp("osgi.startLevel");
+               if (startLevel == null)
+                       return false;
+               int bundleStartLevel = bc.getBundle().adapt(BundleStartLevel.class)
+                               .getStartLevel();
+               // int frameworkStartLevel =
+               // bc.getBundle(0).adapt(BundleStartLevel.class)
+               // .getStartLevel();
+               int frameworkStartLevel = Integer.parseInt(startLevel);
+               // int frameworkStartLevel = bc.getBundle(0)
+               // .adapt(FrameworkStartLevel.class).getStartLevel();
+               return bundleStartLevel == frameworkStartLevel;
+       }
+
+       private void maintenanceInit() {
+               log.info("## MAINTENANCE ##");
+               bc.addServiceListener(Kernel.this);
+               initWebServer(null);
+               MaintenanceUi maintenanceUi = new MaintenanceUi();
+               Hashtable<String, String> props = new Hashtable<String, String>();
+               props.put("contextName", "maintenance");
+               bc.registerService(ApplicationConfiguration.class, maintenanceUi, props);
+       }
+
        private void firstInit() {
                log.info("## FIRST INIT ##");
                String nodeInit = getFrameworkProp(NODE_INIT);
diff --git a/org.argeo.cms/src/org/argeo/cms/maintenance/DataMigration.java b/org.argeo.cms/src/org/argeo/cms/maintenance/DataMigration.java
new file mode 100644 (file)
index 0000000..3aa6120
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.cms.maintenance;
+
+import java.util.Map;
+
+import javax.jcr.Session;
+
+public interface DataMigration {
+       /** Migrate data between two workspaces, at JCR level. */
+       Boolean migrate(Session source, Session target);
+
+       /**
+        * Keys are the source workspaces and values the target workspaces. If null
+        * is returned, only the default workspace will be migrated, to the default
+        * workspace of the target repository.
+        */
+       Map<String, String> workspacesToMigrate();
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/maintenance/MaintenanceUi.java b/org.argeo.cms/src/org/argeo/cms/maintenance/MaintenanceUi.java
new file mode 100644 (file)
index 0000000..49556bc
--- /dev/null
@@ -0,0 +1,13 @@
+package org.argeo.cms.maintenance;
+
+import org.eclipse.rap.rwt.application.Application;
+import org.eclipse.rap.rwt.application.ApplicationConfiguration;
+
+public class MaintenanceUi implements ApplicationConfiguration {
+
+       @Override
+       public void configure(Application application) {
+               application.addEntryPoint("/migration", MigrationEntryPoint.class, null);
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/maintenance/MigrationEntryPoint.java b/org.argeo.cms/src/org/argeo/cms/maintenance/MigrationEntryPoint.java
new file mode 100644 (file)
index 0000000..e6bae8f
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.cms.maintenance;
+
+import org.eclipse.rap.rwt.application.AbstractEntryPoint;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+public class MigrationEntryPoint extends AbstractEntryPoint {
+
+       @Override
+       protected void createContents(Composite parent) {
+               new Label(parent, SWT.NONE).setText("Migration");
+       }
+
+       
+
+}