From dfc028b3661b79e31986890a46b09a4bd3e857b2 Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Thu, 17 Nov 2011 08:38:15 +0000 Subject: [PATCH] CSPACE-4526: Adding missing classes to the repo. --- .../client/java/NuxeoClientEmbedded.java | 462 ++++++++++++++++++ .../client/java/NuxeoConnectorEmbedded.java | 316 ++++++++++++ .../client/java/NuxeoConnectorRemote.java | 263 ++++++++++ 3 files changed, 1041 insertions(+) create mode 100644 services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java create mode 100644 services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java create mode 100644 services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorRemote.java diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java new file mode 100644 index 000000000..821ded217 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoClientEmbedded.java @@ -0,0 +1,462 @@ +/* + * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public License + * (LGPL) version 2.1 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Contributors: + * bstefanescu, jcarsique + * + * $Id$ + */ + +package org.collectionspace.services.nuxeo.client.java; + +import java.security.Principal; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import javax.security.auth.Subject; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.LoginException; +import javax.security.auth.login.LoginContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jboss.remoting.InvokerLocator; +import org.nuxeo.common.collections.ListenerList; +import org.nuxeo.ecm.core.api.ClientException; +import org.nuxeo.ecm.core.api.local.ClientLoginModule; +import org.nuxeo.ecm.core.api.local.LoginStack; +import org.nuxeo.ecm.core.api.repository.Repository; +import org.nuxeo.ecm.core.api.repository.RepositoryInstance; +import org.nuxeo.ecm.core.api.repository.RepositoryInstanceHandler; +import org.nuxeo.ecm.core.api.repository.RepositoryManager; +import org.nuxeo.ecm.core.client.ConnectionListener; +import org.nuxeo.ecm.core.client.DefaultLoginHandler; +import org.nuxeo.ecm.core.client.LoginHandler; +import org.nuxeo.ecm.core.schema.SchemaManager; +import org.nuxeo.ecm.core.schema.SchemaManagerImpl; +import org.nuxeo.ecm.core.schema.TypeProvider; +import org.nuxeo.runtime.api.Framework; +import org.nuxeo.runtime.api.ServiceDescriptor; +import org.nuxeo.runtime.api.ServiceManager; +import org.nuxeo.runtime.api.login.LoginComponent; +import org.nuxeo.runtime.api.login.LoginService; +import org.nuxeo.runtime.api.login.SecurityDomain; +import org.nuxeo.runtime.config.AutoConfigurationService; +import org.nuxeo.runtime.remoting.RemotingService; +import org.nuxeo.runtime.services.streaming.StreamingService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Bogdan Stefanescu + * + */ +public final class NuxeoClientEmbedded { + + private Logger logger = LoggerFactory.getLogger(NuxeoClientEmbedded.class); + + private LoginHandler loginHandler; + + private LoginContext loginContext = null; + + private final List repositoryInstances; + + private final ListenerList connectionListeners; + + private InvokerLocator locator; + + private String serverName; + + private final AutoConfigurationService cfg; + + private RepositoryManager repositoryMgr; + + private boolean multiThreadedLogin = false; + + private static final NuxeoClientEmbedded instance = new NuxeoClientEmbedded(); + + private static final Log log = LogFactory.getLog(NuxeoClientEmbedded.class); + + /** + * Constructs a new NuxeoClient. NOTE: Using {@link #getInstance()} instead + * of this constructor is recommended. + */ + public NuxeoClientEmbedded() { + connectionListeners = new ListenerList(); + cfg = new AutoConfigurationService(); + loginHandler = loginHandler == null ? new DefaultLoginHandler() + : loginHandler; + repositoryInstances = new Vector(); + } + + public static NuxeoClientEmbedded getInstance() { + return instance; + } + + public void setMultiThreadedLogin(boolean useMultiThreadedLogin) { + multiThreadedLogin = useMultiThreadedLogin; + } + + public boolean getMultiThreadedLogin() { + return multiThreadedLogin; + } + + public synchronized void connect(String locator) throws Exception { + if (this.locator != null) { + throw new IllegalStateException("Client is already connected"); + } + doConnect(AutoConfigurationService.createLocator(locator)); + } + + public synchronized void connect(InvokerLocator locator) throws Exception { + if (this.locator != null) { + throw new IllegalStateException("Client is already connected"); + } + doConnect(locator); + } + + public synchronized void connect(String host, int port) throws Exception { + if (locator != null) { + throw new IllegalStateException("Client is already connected"); + } + doConnect(AutoConfigurationService.createLocator(host, port)); + } + + public synchronized void forceConnect(InvokerLocator locator) + throws Exception { + if (this.locator != null) { + disconnect(); + } + doConnect(locator); + } + + public synchronized void forceConnect(String locator) throws Exception { + if (this.locator != null) { + disconnect(); + } + doConnect(AutoConfigurationService.createLocator(locator)); + } + + public synchronized void forceConnect(String host, int port) + throws Exception { + if (locator != null) { + disconnect(); + } + doConnect(AutoConfigurationService.createLocator(host, port)); + } + + public synchronized void tryConnect(String host, int port) throws Exception { + if (locator != null) { + return; // do nothing + } + doConnect(AutoConfigurationService.createLocator(host, port)); + } + + public synchronized void tryConnect(String url) throws Exception { + if (locator != null) { + return; // do nothing + } + doConnect(AutoConfigurationService.createLocator(url)); + } + + public synchronized void tryConnect(InvokerLocator locator) + throws Exception { + if (this.locator != null) { + return; // do nothing + } + doConnect(locator); + } + + private void doConnect(InvokerLocator locator) throws Exception { + this.locator = locator; + try { + cfg.load(locator); + // FIXME TODO workaround to work with nxruntime core 1.3.3 + // -------------- + String newPort = Framework.getProperty("org.nuxeo.runtime.1.3.3.streaming.port"); + if (newPort != null) { + StreamingService streamingService = (StreamingService) Framework.getRuntime().getComponent( + StreamingService.NAME); + // streaming config + String oldLocator = streamingService.getServerLocator(); + int p = oldLocator.lastIndexOf(':'); + if (p > -1) { + String withoutPort = oldLocator.substring(0, p); + String serverLocator = withoutPort + ":" + newPort; + streamingService.stopManager(); + streamingService.setServerLocator(serverLocator); + streamingService.setServer(false); + streamingService.startManager(); + } + } + // FIXME TODO workaround for remote services + // ------------------------------- + schemaRemotingWorkaround(locator.getHost()); + // workaround for client login configuration - we need to make it + // not multi threaded + // TODO put an option for this in NuxeoClient + if (!multiThreadedLogin) { + LoginService ls = Framework.getService(LoginService.class); + SecurityDomain sysDomain = ls.getSecurityDomain(LoginComponent.SYSTEM_LOGIN); + SecurityDomain clientDomain = ls.getSecurityDomain(LoginComponent.CLIENT_LOGIN); + adaptClientSecurityDomain(sysDomain); + adaptClientSecurityDomain(clientDomain); + } + // ---------------- + login(); + } catch (Exception e) { + this.locator = null; + throw e; + } + fireConnected(this); + } + + public static void adaptClientSecurityDomain(SecurityDomain sd) { + AppConfigurationEntry[] entries = sd.getAppConfigurationEntries(); + if (entries != null) { + for (int i = 0; i < entries.length; i++) { + AppConfigurationEntry entry = entries[i]; + if ("org.jboss.security.ClientLoginModule".equals(entry.getLoginModuleName())) { + Map opts = entry.getOptions(); + Map newOpts = new HashMap( + opts); + newOpts.put("multi-threaded", "false"); + entries[i] = new AppConfigurationEntry( + entry.getLoginModuleName(), entry.getControlFlag(), + entry.getOptions()); + } + } + } + } + + /** + * Workaround for being able to load schemas from remote + * TODO integrate this in core + */ + private static void schemaRemotingWorkaround(String host) throws Exception { + ServiceManager serviceManager = Framework.getLocalService(ServiceManager.class); + ServiceDescriptor sd = new ServiceDescriptor(TypeProvider.class, "core"); + sd.setLocator("%TypeProviderBean"); + serviceManager.registerService(sd); + TypeProvider typeProvider = Framework.getService(TypeProvider.class); + SchemaManager schemaMgr = Framework.getLocalService(SchemaManager.class); + ((SchemaManagerImpl) schemaMgr).importTypes(typeProvider); + } + + public synchronized void disconnect() throws Exception { + if (locator == null) { + throw new IllegalStateException("Client is not connected"); + } + doDisconnect(); + } + + public synchronized void tryDisconnect() throws Exception { + if (locator == null) { + return; // do nothing + } + doDisconnect(); + } + + private void doDisconnect() throws Exception { + locator = null; + serverName = null; + // close repository sessions if any + Iterator it = repositoryInstances.iterator(); + while (it.hasNext()) { + RepositoryInstance repo = it.next(); + try { + repo.close(); + } catch (Exception e) { + log.debug("Error while trying to close " + repo, e); + } + it.remove(); + } + // logout + logout(); + repositoryMgr = null; + fireDisconnected(this); + } + + public synchronized void reconnect() throws Exception { + if (locator == null) { + throw new IllegalStateException("Client is not connected"); + } + InvokerLocator locator = this.locator; + disconnect(); + connect(locator); + } + + public AutoConfigurationService getConfigurationService() { + return cfg; + } + + public synchronized String getServerName() { + if (locator == null) { + throw new IllegalStateException("Client is not connected"); + } + if (serverName == null) { + if (cfg == null) { // compatibility + serverName = RemotingService.ping(locator.getHost(), + locator.getPort()); + } else { + serverName = cfg.getServerConfiguration().getProductInfo(); + } + } + return serverName; + } + + public synchronized boolean isConnected() { + return true; + } + + public String getServerHost() { + if (locator == null) { + throw new IllegalStateException("Client is not connected"); + } + return locator.getHost(); + } + + public int getServerPort() { + if (locator == null) { + throw new IllegalStateException("Client is not connected"); + } + return locator.getPort(); + } + + public InvokerLocator getLocator() { + return locator; + } + + public synchronized LoginHandler getLoginHandler() { + return loginHandler; + } + + public synchronized void setLoginHandler(LoginHandler loginHandler) { + this.loginHandler = loginHandler; + } + + public synchronized void login() throws LoginException { + // + // Login as the Nuxeo system/admin user + this.login(null); + } + + public synchronized void login(String user) throws LoginException { + loginContext = Framework.loginAs(user); + if (logger.isDebugEnabled() == true) { + Subject subject = loginContext.getSubject(); + Set principals = subject.getPrincipals(); + logger.debug("Nuxeo login performed with principals: "); + for (Principal principal : principals) { + logger.debug("[" + principal.getName() + "]"); + } + } + } + + public synchronized void logout() throws LoginException { + if (loginContext != null) { + loginContext.logout(); + loginContext = null; + } + } + + public RepositoryManager getRepositoryManager() throws Exception { + if (repositoryMgr == null) { + repositoryMgr = Framework.getService(RepositoryManager.class); + } + return repositoryMgr; + } + + /** + * Gets the repositories available on the connected server. + * + * @return the repositories + */ + public Repository[] getRepositories() throws Exception { + Collection repos = getRepositoryManager().getRepositories(); + return repos.toArray(new Repository[repos.size()]); + } + + public Repository getDefaultRepository() throws Exception { + return getRepositoryManager().getDefaultRepository(); + } + + public Repository getRepository(String name) throws Exception { + return getRepositoryManager().getRepository(name); + } + + public RepositoryInstance openRepository() throws Exception { + return openRepository(null); + } + + public RepositoryInstance openRepository(String name) throws Exception { + Repository repository = null; + if (name != null) { + repository = getRepositoryManager().getRepository(name); + } else { + repository = getRepositoryManager().getDefaultRepository(); + } + RepositoryInstance repo = newRepositoryInstance(repository); + repositoryInstances.add(repo); + + return repo; + } + + public void releaseRepository(RepositoryInstance repo) throws Exception { + try { + repo.close(); + } finally { + repositoryInstances.remove(repo); + } + } + + public RepositoryInstance[] getRepositoryInstances() { + return repositoryInstances.toArray(new RepositoryInstance[repositoryInstances.size()]); + } + + public static RepositoryInstance newRepositoryInstance(Repository repository) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = NuxeoClientEmbedded.class.getClassLoader(); + } + return new RepositoryInstanceHandler(repository).getProxy(); + } + + public void addConnectionListener(ConnectionListener listener) { + connectionListeners.add(listener); + } + + public void removeConnectionListener(ConnectionListener listener) { + connectionListeners.remove(listener); + } + + private void fireDisconnected(NuxeoClientEmbedded client) { + Object[] listeners = connectionListeners.getListeners(); + for (Object listener : listeners) { +// ((ConnectionListener) listener).disconnected(client); + } + } + + private void fireConnected(NuxeoClientEmbedded client) { + Object[] listeners = connectionListeners.getListeners(); + for (Object listener : listeners) { +// ((ConnectionListener) listener).connected(client); + } + } + +} diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java new file mode 100644 index 000000000..af7c65aa2 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java @@ -0,0 +1,316 @@ +package org.collectionspace.services.nuxeo.client.java; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +//import org.collectionspace.services.common.RepositoryClientConfigType; +import org.collectionspace.services.common.RepositoryClientConfigType; +import org.collectionspace.services.nuxeo.util.NuxeoUtils; +import org.nuxeo.ecm.core.api.CoreInstance; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.DocumentModelList; +import org.nuxeo.ecm.core.api.repository.Repository; +import org.nuxeo.ecm.core.api.repository.RepositoryInstance; +import org.nuxeo.ecm.core.api.repository.RepositoryManager; +import org.nuxeo.ecm.core.client.DefaultLoginHandler; +import org.nuxeo.ecm.core.client.NuxeoApp; +//import org.nuxeo.ecm.core.client.NuxeoClient; +import org.nuxeo.osgi.application.FrameworkBootstrap; +import org.nuxeo.runtime.api.Framework; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NuxeoConnectorEmbedded { + /* + 127.0.0.1 + 62474 + */ + private Logger logger = LoggerFactory.getLogger(NuxeoConnectorEmbedded.class); + + public final static String NUXEO_CLIENT_DIR = "nuxeo-client"; + public final static String NUXEO_SERVER_DIR = "nuxeo-server"; + + private static final String HOST = "127.0.0.1"; + private static final int PORT = 62474; + + private final static String CSPACE_JEESERVER_HOME = "CSPACE_CONTAINER"; + private final static String CSPACE_NUXEO_HOME = "CSPACE_NUXEO_HOME"; + + private static final String NUXEO_CLIENT_USERNAME = "NUXEO_CLIENT_USERNAME"; + private static final String NUXEO_CLIENT_PASSWORD = "NUXEO_CLIENT_PASSWORD"; + + private static final NuxeoConnectorEmbedded self = new NuxeoConnectorEmbedded(); + private NuxeoClientEmbedded client; + private ServletContext servletContext = null; + private volatile boolean initialized = false; // use volatile for lazy + // initialization in + // singleton + private RepositoryClientConfigType repositoryClientConfig; + public FrameworkBootstrap fb; + + private NuxeoConnectorEmbedded() { + } + + public final static NuxeoConnectorEmbedded getInstance() { + return self; + } + + private String getClientUserName() { + String username = System.getenv(NUXEO_CLIENT_USERNAME); + if (username == null) { + username = "Administrator"; + } + return username; + } + + private String getClientPassword() { + String password = System.getenv(NUXEO_CLIENT_PASSWORD); + if (password == null) { + password = "Administrator"; + } + return password; + } + + private String getServerRootPath() { + String result = null; + + String prop = System.getenv(CSPACE_JEESERVER_HOME); + if (prop == null || prop.isEmpty()) { + logger.error("The following CollectionSpace services' environment variable needs to be set: " + CSPACE_JEESERVER_HOME); + } + + return result; + } + + private String getNuxeoServerPath(String serverRootPath) throws IOException { + String result = null; + // + // Look for the CSPACE_NUXEO_HOME environment variable that might contain the fully qualified path of the + // Nuxeo EP configuration directory. + // + String prop = System.getenv(CSPACE_NUXEO_HOME); + if (prop != null && !prop.isEmpty()) { + result = prop; + } else { + // + // Could not find the 'CSPACE_NUXEO_HOME' environment variable, so using the default location instead. + // + result = serverRootPath + "/" + NUXEO_SERVER_DIR; + } + + return result; + } + + private File getNuxeoServerDir(String serverRootPath) throws IOException { + File result = null; + String errMsg = null; + + String path = getNuxeoServerPath(serverRootPath); + if (path != null) { + File temp = new File(path); + if (temp.exists() == true) { + result = temp; + } else { + errMsg = "The Nuxeo EP configuration directory is missing or inaccessible at: '" + path + "'."; + } + } + + if (result == null) { + if (errMsg == null) { + path = path != null ? path : ""; + errMsg = "Unknown error trying to find Nuxeo configuration: '" + + CSPACE_NUXEO_HOME + "' = " + + path; + } + throw new IOException(errMsg); + } + + return result; + } + + // + // Start/boot the Nuxeo EP server instance + // + private void startNuxeoEP(String serverRootPath) throws Exception { + File nuxeoHomeDir = getNuxeoServerDir(serverRootPath); + + if (logger.isInfoEnabled() == true) { + logger.info("Starting Nuxeo EP server from configuration at: " + + nuxeoHomeDir.getCanonicalPath()); + } + + fb = new FrameworkBootstrap(NuxeoConnectorEmbedded.class.getClassLoader(), + nuxeoHomeDir); + fb.initialize(); + fb.start(); + } + + /** + * release releases resources occupied by Nuxeo remoting client runtime + * + * @throws java.lang.Exception + */ + public void release() throws Exception { + if (initialized == true) { + try { + client.tryDisconnect(); + } catch (Exception e) { + logger.error("Failed to disconnect Nuxeo connection.", e); + throw e; + } + } + } + + public void initialize(String serverRootPath, + RepositoryClientConfigType repositoryClientConfig, + ServletContext servletContext) throws Exception { + if (initialized == false) { + synchronized (this) { + if (initialized == false) { + this.servletContext = servletContext; + this.repositoryClientConfig = repositoryClientConfig; + startNuxeoEP(serverRootPath); + client = new NuxeoClientEmbedded(); + initialized = true; + } + } + } + } + + /** + * releaseRepositorySession releases given repository session + * + * @param repoSession + * @throws java.lang.Exception + */ + public void releaseRepositorySession(RepositoryInstance repoSession) + throws Exception { + if (repoSession != null) { + getClient().releaseRepository(repoSession); + + if (logger.isDebugEnabled()) { + logger.debug("releaseRepositorySession() released repository session"); + } + } + } + + /** + * getRepositorySession get session to default repository + * + * @return RepositoryInstance + * @throws java.lang.Exception + */ + public RepositoryInstance getRepositorySession() throws Exception { + RepositoryInstance repoSession = getClient().openRepository(); + if (logger.isDebugEnabled()) { + logger.debug("getRepositorySession() opened repository session"); + } + return repoSession; + + // Repository repository = + // Framework.getService(RepositoryManager.class).getDefaultRepository(); + // session = repository.open(); + + } + + /** + * getClient get Nuxeo client for accessing Nuxeo services remotely using + * Nuxeo Java (EJB) Remote APIS + * + * @return NuxeoClient + * @throws java.lang.Exception + */ + public NuxeoClientEmbedded getClient() throws Exception { + if (initialized == true) { + if (client.isConnected()) { + client.login(); + return client; + } else { + client.forceConnect(this.HOST, + this.PORT); + if (logger.isDebugEnabled()) { + logger.debug("getClient(): connection successful port=" + + this.PORT); + } + return client; + } + } + String msg = "NuxeoConnector is not initialized!"; + logger.error(msg); + throw new IllegalStateException(msg); + } + + /** + * retrieveWorkspaceIds retrieves all workspace ids from default repository + * + * @param tenantDomain + * domain representing tenant + * @return + * @throws java.lang.Exception + */ + public Hashtable retrieveWorkspaceIds(String tenantDomain) + throws Exception { + RepositoryInstance repoSession = null; + Hashtable workspaceIds = new Hashtable(); + try { + repoSession = getRepositorySession(); + DocumentModel rootDoc = repoSession.getRootDocument(); + DocumentModelList rootChildrenList = repoSession + .getChildren(rootDoc.getRef()); + Iterator diter = rootChildrenList.iterator(); + while (diter.hasNext()) { + DocumentModel domain = diter.next(); + String domainPath = "/" + tenantDomain; + if (!domain.getPathAsString().equalsIgnoreCase(domainPath)) { + continue; + } + if (logger.isDebugEnabled()) { + logger.debug("domain=" + domain.toString()); + } + DocumentModelList domainChildrenList = repoSession + .getChildren(domain.getRef()); + Iterator witer = domainChildrenList.iterator(); + while (witer.hasNext()) { + DocumentModel childNode = witer.next(); + if (NuxeoUtils.Workspaces.equalsIgnoreCase(childNode.getName())) { + DocumentModelList workspaceList = repoSession + .getChildren(childNode.getRef()); + Iterator wsiter = workspaceList + .iterator(); + while (wsiter.hasNext()) { + DocumentModel workspace = wsiter.next(); + if (logger.isDebugEnabled()) { + logger.debug("workspace name=" + + workspace.getName() + " id=" + + workspace.getId()); + } + workspaceIds.put(workspace.getName().toLowerCase(), + workspace.getId()); + } + } + } + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("retrieveWorkspaceIds() caught exception ", e); + } + throw e; + } finally { + if (repoSession != null) { + releaseRepositorySession(repoSession); + } + } + return workspaceIds; + } + + @Deprecated + private void loadBundles() throws Exception { + } + +} diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorRemote.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorRemote.java new file mode 100644 index 000000000..2949e2131 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorRemote.java @@ -0,0 +1,263 @@ +package org.collectionspace.services.nuxeo.client.java; + +import java.io.File; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; + +import org.collectionspace.services.common.RepositoryClientConfigType; +import org.nuxeo.ecm.core.api.CoreInstance; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.DocumentModelList; +import org.nuxeo.ecm.core.api.repository.Repository; +import org.nuxeo.ecm.core.api.repository.RepositoryInstance; +import org.nuxeo.ecm.core.api.repository.RepositoryManager; +import org.nuxeo.ecm.core.client.DefaultLoginHandler; +import org.nuxeo.ecm.core.client.NuxeoApp; +import org.nuxeo.ecm.core.client.NuxeoClient; +import org.nuxeo.osgi.application.FrameworkBootstrap; +import org.nuxeo.runtime.api.Framework; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NuxeoConnectorRemote { + public FrameworkBootstrap fb; + public final static String NUXEO_CLIENT_DIR = "nuxeo-client"; + private Logger logger = LoggerFactory.getLogger(NuxeoConnectorRemote.class); + private static final NuxeoConnectorRemote self = new NuxeoConnectorRemote(); + private static final String NUXEO_CLIENT_USERNAME = "NUXEO_CLIENT_USERNAME"; + private static final String NUXEO_CLIENT_PASSWORD = "NUXEO_CLIENT_PASSWORD"; + private NuxeoClient client; + private volatile boolean initialized = false; // use volatile for lazy + // initialization in + // singleton + private RepositoryClientConfigType repositoryClientConfig; + + private NuxeoConnectorRemote() { + } + + public final static NuxeoConnectorRemote getInstance() { + return self; + } + + private String getClientUserName( + RepositoryClientConfigType repositoryClientConfig) { + String username = System.getenv(NUXEO_CLIENT_USERNAME); + if (username == null) { + username = repositoryClientConfig.getUser(); + } + return username; + } + + private String getClientPassword( + RepositoryClientConfigType repositoryClientConfig) { + String password = System.getenv(NUXEO_CLIENT_PASSWORD); + if (password == null) { + password = repositoryClientConfig.getPassword(); + } + return password; + } + + private void startNuxeoEP() throws Exception { + String nuxeoHome = "nuxeo-client/"; + String serverRootDir = System.getProperty("jboss.server.home.dir"); + if (serverRootDir == null) { + serverRootDir = "."; // assume server is started from server root, + // e.g. server/cspace + } + File nuxeoHomeDir = new File(serverRootDir + File.separator + nuxeoHome); + logger.info("Loading Nuxeo configuration from: " + + nuxeoHomeDir.getAbsolutePath()); + if (nuxeoHomeDir.exists() == false) { + String msg = "Library bundles requried to deploy Nuxeo client not found: " + + " directory named nuxeo-client with bundles does not exist in " + + serverRootDir; + logger.error(msg); + throw new IllegalStateException(msg); + } + fb = new FrameworkBootstrap(NuxeoConnectorRemote.class.getClassLoader(), + nuxeoHomeDir); + fb.initialize(); + fb.start(); + } + + /** + * release releases resources occupied by Nuxeo remoting client runtime + * + * @throws java.lang.Exception + */ + public void release() throws Exception { + if (initialized == true) { + try { + client.tryDisconnect(); + } catch (Exception e) { + logger.error("Failed to disconnect Nuxeo connection.", e); + throw e; + } + } + } + + public void initialize(RepositoryClientConfigType repositoryClientConfig) + throws Exception { + if (initialized == false) { + synchronized (this) { + if (initialized == false) { + try { + this.repositoryClientConfig = repositoryClientConfig; + startNuxeoEP(); + // client = NuxeoClient.getInstance(); + client = new NuxeoClient(); + String username = getClientUserName(repositoryClientConfig); + String password = getClientPassword(repositoryClientConfig); + DefaultLoginHandler loginHandler = new DefaultLoginHandler( + username, password); + client.setLoginHandler(loginHandler); + client.tryConnect(repositoryClientConfig.getHost(), + repositoryClientConfig.getPort()); + if (logger.isDebugEnabled()) { + logger.debug("initialize(): connection successful port=" + + repositoryClientConfig.getPort()); + } + initialized = true; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception while initializing", + e); + } + } + } + } + } + } + + /** + * releaseRepositorySession releases given repository session + * + * @param repoSession + * @throws java.lang.Exception + */ + public void releaseRepositorySession(RepositoryInstance repoSession) + throws Exception { + if (repoSession != null) { + getClient().releaseRepository(repoSession); + + if (logger.isDebugEnabled()) { + logger.debug("releaseRepositorySession() released repository session"); + } + } + } + + /** + * getRepositorySession get session to default repository + * + * @return RepositoryInstance + * @throws java.lang.Exception + */ + public RepositoryInstance getRepositorySession() throws Exception { + RepositoryInstance repoSession = getClient().openRepository(); + if (logger.isDebugEnabled()) { + logger.debug("getRepositorySession() opened repository session"); + } + return repoSession; + + // Repository repository = + // Framework.getService(RepositoryManager.class).getDefaultRepository(); + // session = repository.open(); + + } + + /** + * getClient get Nuxeo client for accessing Nuxeo services remotely using + * Nuxeo Java (EJB) Remote APIS + * + * @return NuxeoClient + * @throws java.lang.Exception + */ + public NuxeoClient getClient() throws Exception { + if (initialized == true) { + if (client.isConnected()) { + client.login(); + return client; + } else { + client.forceConnect(repositoryClientConfig.getHost(), + repositoryClientConfig.getPort()); + if (logger.isDebugEnabled()) { + logger.debug("getClient(): connection successful port=" + + repositoryClientConfig.getPort()); + } + return client; + } + } + String msg = "NuxeoConnector is not initialized!"; + logger.error(msg); + throw new IllegalStateException(msg); + } + + /** + * retrieveWorkspaceIds retrieves all workspace ids from default repository + * + * @param tenantDomain + * domain representing tenant + * @return + * @throws java.lang.Exception + */ + public Hashtable retrieveWorkspaceIds(String tenantDomain) + throws Exception { + RepositoryInstance repoSession = null; + Hashtable workspaceIds = new Hashtable(); + try { + repoSession = getRepositorySession(); + DocumentModel rootDoc = repoSession.getRootDocument(); + DocumentModelList rootChildrenList = repoSession + .getChildren(rootDoc.getRef()); + Iterator diter = rootChildrenList.iterator(); + while (diter.hasNext()) { + DocumentModel domain = diter.next(); + String domainPath = "/" + tenantDomain; + if (!domain.getPathAsString().equalsIgnoreCase(domainPath)) { + continue; + } + if (logger.isDebugEnabled()) { + logger.debug("domain=" + domain.toString()); + } + DocumentModelList domainChildrenList = repoSession + .getChildren(domain.getRef()); + Iterator witer = domainChildrenList.iterator(); + while (witer.hasNext()) { + DocumentModel childNode = witer.next(); + if ("Workspaces".equalsIgnoreCase(childNode.getName())) { + DocumentModelList workspaceList = repoSession + .getChildren(childNode.getRef()); + Iterator wsiter = workspaceList + .iterator(); + while (wsiter.hasNext()) { + DocumentModel workspace = wsiter.next(); + if (logger.isDebugEnabled()) { + logger.debug("workspace name=" + + workspace.getName() + " id=" + + workspace.getId()); + } + workspaceIds.put(workspace.getName().toLowerCase(), + workspace.getId()); + } + } + } + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("retrieveWorkspaceIds() caught exception ", e); + } + throw e; + } finally { + if (repoSession != null) { + releaseRepositorySession(repoSession); + } + } + return workspaceIds; + } + + @Deprecated + private void loadBundles() throws Exception { + } + +} -- 2.47.3