Start dealing properly with remote node
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 9 Apr 2018 07:09:23 +0000 (09:09 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 9 Apr 2018 07:09:23 +0000 (09:09 +0200)
org.argeo.cms/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java
org.argeo.cms/src/org/argeo/cms/internal/jcr/repository-memory.xml
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsFsProvider.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeRepositoryFactory.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/RepositoryServiceFactory.java

index 622600d3ce6ba6fe5f34198247ed850eb349e30c..d5f3a20cd5b6a0c8650d8c0dc999d5cd05fefb52 100644 (file)
@@ -101,7 +101,14 @@ public class RepositoryBuilder {
                        }
                } else {
                        try {
-                               homePath = Paths.get(new URI(homeUri)).toAbsolutePath();
+                               URI uri = new URI(homeUri);
+                               String host = uri.getHost();
+                               if (host == null || host.trim().equals("")) {
+                                       homePath = Paths.get(uri).toAbsolutePath();
+                               } else {
+                                       // TODO remote at this stage?
+                                       throw new IllegalArgumentException("Cannot manage repository path for host " + host);
+                               }
                        } catch (URISyntaxException e) {
                                throw new CmsException("Invalid repository home URI", e);
                        }
index 738ed5bbd601e3a9edcb0cc6af28afb42b24e97a..3630a149d614f99f16ab4b569a000aadb4be881b 100644 (file)
                        <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
                        <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
                </SearchIndex>
+               <WorkspaceSecurity>
+                       <AccessControlProvider
+                               class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
+               </WorkspaceSecurity>
        </Workspace>
 
        <!-- Versioning -->
index 917b15a9a94c9baef9290d8d7b11c153eb08b003..7134517f398e7c27ece82b48b295cad45ea32b1a 100644 (file)
@@ -21,6 +21,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryContext;
+import org.apache.jackrabbit.core.RepositoryImpl;
 import org.argeo.cms.CmsException;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.node.DataModelNamespace;
@@ -211,11 +212,11 @@ public class CmsDeployment implements NodeDeployment {
                prepareDataModel(NodeConstants.NODE, KernelUtils.openAdminSession(deployedNodeRepository));
        }
 
-       private void prepareHomeRepository(Repository deployedRepository) {
+       private void prepareHomeRepository(RepositoryImpl deployedRepository) {
                Hashtable<String, String> regProps = new Hashtable<String, String>();
                regProps.put(NodeConstants.CN, NodeConstants.HOME);
                // regProps.put(LEGACY_JCR_REPOSITORY_ALIAS, NodeConstants.HOME);
-               homeRepository = new HomeRepository(deployedRepository);
+               homeRepository = new HomeRepository(deployedRepository, false);
                // register
                bc.registerService(Repository.class, homeRepository, regProps);
 
index f42646ec5907a6aa3a934448ae2b3a32fb9626c6..614ff6c497ebda2ce6dd0554c4dd11f8cd64ad71 100644 (file)
@@ -10,11 +10,13 @@ import java.util.Map;
 
 import javax.jcr.Node;
 import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider;
+import org.argeo.jcr.JcrUtils;
 import org.argeo.jcr.fs.JcrFileSystem;
 import org.argeo.jcr.fs.JcrFsException;
 import org.argeo.node.NodeConstants;
@@ -42,12 +44,23 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider {
                        throw new FileSystemAlreadyExistsException("CMS file system already exists for user " + username);
 
                try {
-                       Repository repository = bc.getService(
-                                       bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.HOME + ")").iterator().next());
-                       Session session = repository.login();
-                       JcrFileSystem fileSystem = new JcrFileSystem(this, session);
-                       fileSystems.put(username, fileSystem);
-                       return fileSystem;
+                       String host = uri.getHost();
+                       if (host != null && !host.trim().equals("")) {
+                               URI repoUri = new URI("http", uri.getUserInfo(), uri.getHost(), uri.getPort(), "/jcr/node", null, null);
+                               RepositoryFactory repositoryFactory = bc.getService(bc.getServiceReference(RepositoryFactory.class));
+                               Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory, repoUri.toString());
+                               Session session = repository.login("main");
+                               JcrFileSystem fileSystem = new JcrFileSystem(this, session);
+                               fileSystems.put(username, fileSystem);
+                               return fileSystem;
+                       } else {
+                               Repository repository = bc.getService(
+                                               bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.HOME + ")").iterator().next());
+                               Session session = repository.login();
+                               JcrFileSystem fileSystem = new JcrFileSystem(this, session);
+                               fileSystems.put(username, fileSystem);
+                               return fileSystem;
+                       }
                } catch (Exception e) {
                        throw new CmsException("Cannot open file system " + uri + " for user " + username, e);
                }
index 9ab66ffb8f3314b8b727ef70afb3b89ac00e1d72..b4f65bef73a1dea2bd458d4936cf16d0be40fe0a 100644 (file)
@@ -39,36 +39,41 @@ class HomeRepository extends JcrRepositoryWrapper implements KernelConstants {
 
        private SimpleDateFormat usersDatePath = new SimpleDateFormat("YYYY/MM");
 
-       public HomeRepository(Repository repository) {
+       private final boolean remote;
+
+       public HomeRepository(Repository repository, boolean remote) {
                super(repository);
+               this.remote = remote;
                putDescriptor(NodeConstants.CN, NodeConstants.HOME);
-               LoginContext lc;
-               try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
-                       lc.login();
-               } catch (javax.security.auth.login.LoginException e1) {
-                       throw new CmsException("Cannot login as systrem", e1);
-               }
-               Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
-
-                       @Override
-                       public Void run() {
-                               try {
-                                       Session adminSession = getRepository().login();
-                                       initJcr(adminSession);
-                               } catch (RepositoryException e) {
-                                       throw new CmsException("Cannot init JCR home", e);
-                               }
-                               return null;
+               if (!remote) {
+                       LoginContext lc;
+                       try {
+                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
+                               lc.login();
+                       } catch (javax.security.auth.login.LoginException e1) {
+                               throw new CmsException("Cannot login as systrem", e1);
                        }
+                       Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
+
+                               @Override
+                               public Void run() {
+                                       try {
+                                               Session adminSession = getRepository().login();
+                                               initJcr(adminSession);
+                                       } catch (RepositoryException e) {
+                                               throw new CmsException("Cannot init JCR home", e);
+                                       }
+                                       return null;
+                               }
 
-               });
+                       });
+               }
        }
 
        @Override
        protected void processNewSession(Session session) {
                String username = session.getUserID();
-               if (username == null)
+               if (username == null || username.toString().equals(""))
                        return;
                if (session.getUserID().equals(NodeConstants.ROLE_ANONYMOUS))
                        return;
@@ -98,7 +103,7 @@ class HomeRepository extends JcrRepositoryWrapper implements KernelConstants {
                        JcrUtils.addPrivilege(adminSession, groupsBasePath, NodeConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
                        adminSession.save();
                } catch (RepositoryException e) {
-                       throw new CmsException("Cannot initialize node user admin", e);
+                       throw new CmsException("Cannot initialize home repository", e);
                } finally {
                        JcrUtils.logoutQuietly(adminSession);
                }
index f8bce9cf689e967620f4be3e894954a2af7d25c0..f221d0cdbf7dee2d08f9d57ae12bf0e837dbad67 100644 (file)
@@ -41,4 +41,5 @@ public interface KernelConstants {
        // avoid dependencies
        String CONTEXT_NAME_PROP = "contextName";
        String JACKRABBIT_REPOSITORY_URI = "org.apache.jackrabbit.repository.uri";
+       String JACKRABBIT_REMOTE_DEFAULT_WORKSPACE = "org.apache.jackrabbit.spi2davex.WorkspaceNameDefault";
 }
index 116cf98ab825010478619b31a78a5857ff0ef9f3..f7d6df811a6e798dbc95908a6ff9fd78bdc434a3 100644 (file)
@@ -52,6 +52,7 @@ import org.argeo.node.ArgeoLogListener;
 import org.argeo.node.ArgeoLogger;
 import org.argeo.node.NodeConstants;
 import org.argeo.osgi.useradmin.UserAdminConf;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.cm.ConfigurationAdmin;
@@ -191,6 +192,10 @@ class NodeLogger implements ArgeoLogger, LogListener {
        private String msg(LogEntry status) {
                StringBuilder sb = new StringBuilder();
                sb.append(status.getMessage());
+               Bundle bundle = status.getBundle();
+               if (bundle != null) {
+                       sb.append(" '" + bundle.getSymbolicName() + "'");
+               }
                ServiceReference<?> sr = status.getServiceReference();
                if (sr != null) {
                        sb.append(' ');
index 2e3e78f0da5b49380d55f453978f3f6ae78bbd48..f83eb9476f6005c725d95817782d4b8ac9911681 100644 (file)
@@ -28,6 +28,7 @@ import javax.jcr.RepositoryFactory;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
+import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.jcr.ArgeoJcrException;
 import org.argeo.node.NodeConstants;
 import org.osgi.framework.BundleContext;
@@ -84,15 +85,16 @@ class NodeRepositoryFactory implements RepositoryFactory {
                // check if remote
                Repository repository;
                String uri = null;
-               if (parameters.containsKey(NodeConstants.LABELED_URI))
+               if (parameters.containsKey(RepoConf.labeledUri.name()))
                        uri = parameters.get(NodeConstants.LABELED_URI).toString();
                else if (parameters.containsKey(KernelConstants.JACKRABBIT_REPOSITORY_URI))
                        uri = parameters.get(KernelConstants.JACKRABBIT_REPOSITORY_URI).toString();
 
                if (uri != null) {
-                       if (uri.startsWith("http"))// http, https
-                               repository = createRemoteRepository(uri);
-                       else if (uri.startsWith("file"))// http, https
+                       if (uri.startsWith("http")) {// http, https
+                               Object defaultWorkspace = parameters.get(RepoConf.defaultWorkspace.name());
+                               repository = createRemoteRepository(uri, defaultWorkspace != null ? defaultWorkspace.toString() : null);
+                       } else if (uri.startsWith("file"))// http, https
                                repository = createFileRepository(uri, parameters);
                        else if (uri.startsWith("vm")) {
                                // log.warn("URI " + uri + " should have been managed by generic
@@ -120,9 +122,11 @@ class NodeRepositoryFactory implements RepositoryFactory {
                return repository;
        }
 
-       protected Repository createRemoteRepository(String uri) throws RepositoryException {
+       protected Repository createRemoteRepository(String uri, String defaultWorkspace) throws RepositoryException {
                Map<String, String> params = new HashMap<String, String>();
                params.put(KernelConstants.JACKRABBIT_REPOSITORY_URI, uri);
+               if (defaultWorkspace != null)
+                       params.put(KernelConstants.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, defaultWorkspace);
                Repository repository = new Jcr2davRepositoryFactory().getRepository(params);
                if (repository == null)
                        throw new ArgeoJcrException("Remote Davex repository " + uri + " not found");
@@ -190,8 +194,7 @@ class NodeRepositoryFactory implements RepositoryFactory {
        }
 
        /**
-        * Called after the repository has been initialised. Does nothing by
-        * default.
+        * Called after the repository has been initialised. Does nothing by default.
         */
        @SuppressWarnings("rawtypes")
        protected void postInitialization(Repository repository, Map parameters) {
@@ -199,7 +202,7 @@ class NodeRepositoryFactory implements RepositoryFactory {
        }
 
        public void setFileRepositoryConfiguration(Resource fileRepositoryConfiguration) {
-//             this.fileRepositoryConfiguration = fileRepositoryConfiguration;
+               // this.fileRepositoryConfiguration = fileRepositoryConfiguration;
        }
 
 }
index b718043d99c6bfbf160a323d249cffeeacae7485..97a3e8d5ae12b8e353af65776c0604220c4ea743 100644 (file)
@@ -1,13 +1,18 @@
 package org.argeo.cms.internal.kernel;
 
+import java.net.URI;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.core.RepositoryContext;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.cms.internal.jcr.RepositoryBuilder;
 import org.argeo.node.NodeConstants;
 import org.argeo.util.LangUtils;
@@ -43,19 +48,59 @@ class RepositoryServiceFactory implements ManagedServiceFactory {
                }
 
                try {
-                       RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
-                       RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
-                       repositories.put(pid, repositoryContext);
-                       Dictionary<String, Object> props = LangUtils.dico(Constants.SERVICE_PID, pid);
-                       // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
-                       // properties.get(RepoConf.labeledUri.name()));
-                       Object cn = properties.get(NodeConstants.CN);
-                       if (cn != null) {
-                               props.put(NodeConstants.CN, cn);
-//                             props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
-                               pidToCn.put(pid, cn);
+                       Object labeledUri = properties.get(RepoConf.labeledUri.name());
+                       if (labeledUri == null) {
+                               RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
+                               RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
+                               repositories.put(pid, repositoryContext);
+                               Dictionary<String, Object> props = LangUtils.dico(Constants.SERVICE_PID, pid);
+                               // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
+                               // properties.get(RepoConf.labeledUri.name()));
+                               Object cn = properties.get(NodeConstants.CN);
+                               if (cn != null) {
+                                       props.put(NodeConstants.CN, cn);
+                                       // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
+                                       pidToCn.put(pid, cn);
+                               }
+                               bc.registerService(RepositoryContext.class, repositoryContext, props);
+                       } else {
+                               try {
+                                       Object cn = properties.get(NodeConstants.CN);
+                                       Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
+                                       if (defaultWorkspace == null)
+                                               defaultWorkspace = RepoConf.defaultWorkspace.getDefault();
+                                       URI uri = new URI(labeledUri.toString());
+                                       RepositoryFactory repositoryFactory = bc
+                                                       .getService(bc.getServiceReference(RepositoryFactory.class));
+                                       Map<String, String> parameters = new HashMap<String, String>();
+                                       parameters.put(RepoConf.labeledUri.name(), uri.toString());
+                                       parameters.put(RepoConf.defaultWorkspace.name(), defaultWorkspace.toString());
+                                       Repository repository = repositoryFactory.getRepository(parameters);
+                                       // Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory,
+                                       // uri.toString());
+                                       Dictionary<String, Object> props = LangUtils.dico(Constants.SERVICE_PID, pid);
+                                       props.put(RepoConf.labeledUri.name(),
+                                                       new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
+                                                                       .toString());
+                                       if (cn != null) {
+                                               props.put(NodeConstants.CN, cn);
+                                               // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
+                                               pidToCn.put(pid, cn);
+                                       }
+                                       bc.registerService(Repository.class, repository, props);
+
+                                       // home
+                                       // TODO make a sperate home configurable
+                                       if (cn.equals(NodeConstants.NODE)) {
+                                               Dictionary<String, Object> homeProps = LangUtils.dico(NodeConstants.CN, NodeConstants.HOME);
+                                               HomeRepository homeRepository = new HomeRepository(repository, true);
+                                               bc.registerService(Repository.class, homeRepository, homeProps);
+                                       }
+                               } catch (Exception e) {
+                                       // TODO Auto-generated catch block
+                                       e.printStackTrace();
+                               }
                        }
-                       bc.registerService(RepositoryContext.class, repositoryContext, props);
                } catch (Exception e) {
                        throw new CmsException("Cannot create Jackrabbit repository " + pid, e);
                }