From commits-return-11511-apmail-jackrabbit-commits-archive=jackrabbit.apache.org@jackrabbit.apache.org Tue Jul 26 14:21:08 2011 Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 70A3F7E45 for ; Tue, 26 Jul 2011 14:21:08 +0000 (UTC) Received: (qmail 4978 invoked by uid 500); 26 Jul 2011 14:21:08 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 4926 invoked by uid 500); 26 Jul 2011 14:21:07 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 4919 invoked by uid 99); 26 Jul 2011 14:21:07 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jul 2011 14:21:07 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jul 2011 14:21:05 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 50407238885D; Tue, 26 Jul 2011 14:20:45 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1151110 - in /jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit: spi2dav/ spi2davex/ Date: Tue, 26 Jul 2011 14:20:44 -0000 To: commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110726142045.50407238885D@eris.apache.org> Author: angela Date: Tue Jul 26 14:20:43 2011 New Revision: 1151110 URL: http://svn.apache.org/viewvc?rev=1151110&view=rev Log: JCR-3026 - apply modified patch (original author: chad davis) Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?rev=1151110&r1=1151109&r2=1151110&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original) +++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Tue Jul 26 14:20:43 2011 @@ -33,6 +33,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.jcr.AccessDeniedException; import javax.jcr.Credentials; @@ -71,6 +73,7 @@ import org.apache.commons.httpclient.met import org.apache.commons.httpclient.methods.InputStreamRequestEntity; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.apache.jackrabbit.commons.webdav.EventUtil; import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants; import org.apache.jackrabbit.commons.webdav.JcrValueType; @@ -207,6 +210,17 @@ public class RepositoryServiceImpl imple private static final SubscriptionInfo S_INFO = new SubscriptionInfo(DefaultEventType.create(EventUtil.EVENT_ALL, ItemResourceConstants.NAMESPACE), true, INFINITE_TIMEOUT); + /** + * Key for the client map during repo creation (no sessionInfo present) + */ + private static final String CLIENT_KEY = "repoCreation"; + + /** + * Default value for the maximum number of connections per host such as + * configured with {@link HttpConnectionManagerParams#setDefaultMaxConnectionsPerHost(int)}. + */ + public static final int MAX_CONNECTIONS_DEFAULT = 20; + private final IdFactory idFactory; private final NameFactory nameFactory; private final PathFactory pathFactory; @@ -220,26 +234,69 @@ public class RepositoryServiceImpl imple private final URIResolverImpl uriResolver; private final HostConfiguration hostConfig; - private final Map clients = new HashMap(); + private final ConcurrentMap clients; private final HttpConnectionManager connectionManager; private final Map nodeTypeDefinitions = new HashMap(); private Map descriptors; + /** + * Same as {@link #RepositoryServiceImpl(String, IdFactory, NameFactory, PathFactory, QValueFactory, int, int)} + * using {@link ItemInfoCacheImpl#DEFAULT_CACHE_SIZE)} as size for the item + * cache and {@link #MAX_CONNECTIONS_DEFAULT} for the maximum number of + * connections on the client. + * + * @param uri The server uri. + * @param idFactory The id factory. + * @param nameFactory The name factory. + * @param pathFactory The path factory. + * @param qValueFactory The value factory. + * @throws RepositoryException If an error occurs. + */ public RepositoryServiceImpl(String uri, IdFactory idFactory, - NameFactory nameFactory, - PathFactory pathFactory, - QValueFactory qValueFactory) throws RepositoryException { - + NameFactory nameFactory, PathFactory pathFactory, + QValueFactory qValueFactory) throws RepositoryException { this(uri, idFactory, nameFactory, pathFactory, qValueFactory, ItemInfoCacheImpl.DEFAULT_CACHE_SIZE); } + /** + * Same as {@link #RepositoryServiceImpl(String, IdFactory, NameFactory, PathFactory, QValueFactory, int, int)} + * using {@link #MAX_CONNECTIONS_DEFAULT} for the maximum number of + * connections on the client. + * + * @param uri The server uri. + * @param idFactory The id factory. + * @param nameFactory The name factory. + * @param pathFactory The path factory. + * @param qValueFactory The value factory. + * @param itemInfoCacheSize The size of the item info cache. + * @throws RepositoryException If an error occurs. + */ + public RepositoryServiceImpl(String uri, IdFactory idFactory, + NameFactory nameFactory, PathFactory pathFactory, + QValueFactory qValueFactory, int itemInfoCacheSize) throws RepositoryException { + this(uri, idFactory, nameFactory, pathFactory, qValueFactory, itemInfoCacheSize, MAX_CONNECTIONS_DEFAULT); + } + + /** + * Creates a new instance of this repository service. + * + * @param uri The server uri. + * @param idFactory The id factory. + * @param nameFactory The name factory. + * @param pathFactory The path factory. + * @param qValueFactory The value factory. + * @param itemInfoCacheSize The size of the item info cache. + * @param maximumHttpConnections A int >0 defining the maximum number of + * connections per host to be configured on + * {@link HttpConnectionManagerParams#setDefaultMaxConnectionsPerHost(int)}. + * @throws RepositoryException If an error occurs. + */ public RepositoryServiceImpl(String uri, IdFactory idFactory, - NameFactory nameFactory, - PathFactory pathFactory, - QValueFactory qValueFactory, - int itemInfoCacheSize) throws RepositoryException { + NameFactory nameFactory, PathFactory pathFactory, + QValueFactory qValueFactory, int itemInfoCacheSize, + int maximumHttpConnections ) throws RepositoryException { if (uri == null || "".equals(uri)) { throw new RepositoryException("Invalid repository uri '" + uri + "'."); } @@ -272,7 +329,24 @@ public class RepositoryServiceImpl imple } catch (URIException e) { throw new RepositoryException(e); } + connectionManager = new MultiThreadedHttpConnectionManager(); + if (maximumHttpConnections > 0) { + HttpConnectionManagerParams connectionParams = connectionManager.getParams(); + connectionParams.setDefaultMaxConnectionsPerHost(maximumHttpConnections); + } + + // This configuration of the clients cache assumes that the level of + // concurrency on this map will be equal to the default number of maximum + // connections allowed on the httpClient level. + // TODO: review again + int concurrencyLevel = MAX_CONNECTIONS_DEFAULT; + int initialCapacity = MAX_CONNECTIONS_DEFAULT; + if (maximumHttpConnections > 0) { + concurrencyLevel = maximumHttpConnections; + initialCapacity = maximumHttpConnections; + } + clients = new ConcurrentHashMap(concurrencyLevel, .75f, initialCapacity); } private static void checkSessionInfo(SessionInfo sessionInfo) throws RepositoryException { @@ -365,8 +439,21 @@ public class RepositoryServiceImpl imple return resolver; } + /** + * Returns a key for the httpClient hash. The key is either the specified + * SessionInfo or a marker if the session info is null (used during + * repository instantiation). + * + * @param sessionInfo + * @return Key for the client map. + */ + private static Object getClientKey(SessionInfo sessionInfo) { + return (sessionInfo == null) ? CLIENT_KEY : sessionInfo; + } + protected HttpClient getClient(SessionInfo sessionInfo) throws RepositoryException { - HttpClient client = clients.get(sessionInfo); + Object clientKey = getClientKey(sessionInfo); + HttpClient client = clients.get(clientKey); if (client == null) { client = new HttpClient(connectionManager); client.setHostConfiguration(hostConfig); @@ -380,14 +467,14 @@ public class RepositoryServiceImpl imple client.getParams().setAuthenticationPreemptive(true); } client.getState().setCredentials(AuthScope.ANY, creds); - clients.put(sessionInfo, client); + clients.put(clientKey, client); log.debug("Created Client " + client + " for SessionInfo " + sessionInfo); } return client; } private void removeClient(SessionInfo sessionInfo) { - HttpClient cl = clients.remove(sessionInfo); + HttpClient cl = clients.remove(getClientKey(sessionInfo)); log.debug("Removed Client " + cl + " for SessionInfo " + sessionInfo); } Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java?rev=1151110&r1=1151109&r2=1151110&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java (original) +++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/Spi2davRepositoryServiceFactory.java Tue Jul 26 14:20:43 2011 @@ -77,6 +77,13 @@ public class Spi2davRepositoryServiceFac */ public static final String PARAM_ITEMINFO_CACHE_SIZE = "org.apache.jackrabbit.spi2dav.ItemInfoCacheSize"; + /** + * Optional configuration parameter: It's value defines the + * maximumConnectionsPerHost value on the HttpClient configuration and + * must be an int greater than zero. + */ + public static final String PARAM_MAX_CONNECTIONS = "org.apache.jackrabbit.spi2dav.MaxConnections"; + public RepositoryService createRepositoryService(Map parameters) throws RepositoryException { if (parameters == null) { throw new RepositoryException("Parameter " + PARAM_REPOSITORY_URI + " missing"); @@ -127,12 +134,26 @@ public class Spi2davRepositoryServiceFac if (param != null) { try { itemInfoCacheSize = Integer.parseInt(param.toString()); - } - catch (NumberFormatException e) { + } catch (NumberFormatException e) { // ignore, use default } } - return new RepositoryServiceImpl(uri, idFactory, nameFactory, pathFactory, vFactory, itemInfoCacheSize); - } + // max connections config + int maximumHttpConnections = 0; + param = parameters.get(PARAM_MAX_CONNECTIONS); + if (param != null) { + try { + maximumHttpConnections = Integer.parseInt(param.toString()); + } catch ( NumberFormatException e ) { + // using default + } + } + + if (maximumHttpConnections > 0) { + return new RepositoryServiceImpl(uri, idFactory, nameFactory, pathFactory, vFactory, itemInfoCacheSize, maximumHttpConnections); + } else { + return new RepositoryServiceImpl(uri, idFactory, nameFactory, pathFactory, vFactory, itemInfoCacheSize); + } + } } Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java?rev=1151110&r1=1151109&r2=1151110&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (original) +++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java Tue Jul 26 14:20:43 2011 @@ -111,15 +111,54 @@ public class RepositoryServiceImpl exten private final Map qvFactories = new HashMap(); + /** + * Same as {@link #RepositoryServiceImpl(String, String, BatchReadConfig, int, int))} + * using null workspace name, {@link ItemInfoCacheImpl#DEFAULT_CACHE_SIZE)} + * as size for the item cache and {@link #MAX_CONNECTIONS_DEFAULT} for the + * maximum number of connections on the client. + * + * @param jcrServerURI The server uri. + * @param batchReadConfig The batch read configuration. + * @throws RepositoryException If an exception occurs. + */ public RepositoryServiceImpl(String jcrServerURI, BatchReadConfig batchReadConfig) throws RepositoryException { this(jcrServerURI, null, batchReadConfig, ItemInfoCacheImpl.DEFAULT_CACHE_SIZE); } + /** + * Same as {@link #RepositoryServiceImpl(String, String, BatchReadConfig, int, int))} + * using {@link #MAX_CONNECTIONS_DEFAULT} for the maximum number of + * connections on the client. + * + * @param jcrServerURI The server uri. + * @param defaultWorkspaceName The default workspace name. + * @param batchReadConfig The batch read configuration. + * @param itemInfoCacheSize The size of the item info cache. + * @throws RepositoryException If an exception occurs. + */ + public RepositoryServiceImpl(String jcrServerURI, String defaultWorkspaceName, + BatchReadConfig batchReadConfig, int itemInfoCacheSize) throws RepositoryException { + this(jcrServerURI, defaultWorkspaceName, batchReadConfig, itemInfoCacheSize, MAX_CONNECTIONS_DEFAULT); + } + + /** + * Creates a new instance of this repository service. + * + * @param jcrServerURI The server uri. + * @param defaultWorkspaceName The default workspace name. + * @param batchReadConfig The batch read configuration. + * @param itemInfoCacheSize The size of the item info cache. + * @param maximumHttpConnections maximumHttpConnections A int >0 defining + * the maximum number of connections per host to be configured on + * {@link org.apache.commons.httpclient.params.HttpConnectionManagerParams#setDefaultMaxConnectionsPerHost(int)}. + * @throws RepositoryException If an exception occurs. + */ public RepositoryServiceImpl(String jcrServerURI, String defaultWorkspaceName, - BatchReadConfig batchReadConfig, int itemInfoCacheSize) throws RepositoryException { + BatchReadConfig batchReadConfig, int itemInfoCacheSize, + int maximumHttpConnections) throws RepositoryException { - super(jcrServerURI, IdFactoryImpl.getInstance(), NameFactoryImpl.getInstance(), PathFactoryImpl - .getInstance(), new QValueFactoryImpl(), itemInfoCacheSize); + super(jcrServerURI, IdFactoryImpl.getInstance(), NameFactoryImpl.getInstance(), + PathFactoryImpl.getInstance(), new QValueFactoryImpl(), itemInfoCacheSize, maximumHttpConnections); this.jcrServerURI = jcrServerURI.endsWith("/") ? jcrServerURI : jcrServerURI + "/"; this.defaultWorkspaceName = defaultWorkspaceName; @@ -198,20 +237,20 @@ public class RepositoryServiceImpl exten return sb.toString(); } - /** + /** * @see RepositoryService#getQValueFactory() */ public QValueFactoryImpl getQValueFactory(SessionInfo sessionInfo) throws RepositoryException { - QValueFactoryImpl qv; - if (qvFactories.containsKey(sessionInfo)) { - qv = qvFactories.get(sessionInfo); - } else { - ValueLoader loader = new ValueLoader(getClient(sessionInfo)); - qv = new QValueFactoryImpl(getNamePathResolver(sessionInfo), loader); - qvFactories.put(sessionInfo, qv); - } - return qv; - } + QValueFactoryImpl qv; + if (qvFactories.containsKey(sessionInfo)) { + qv = qvFactories.get(sessionInfo); + } else { + ValueLoader loader = new ValueLoader(getClient(sessionInfo)); + qv = new QValueFactoryImpl(getNamePathResolver(sessionInfo), loader); + qvFactories.put(sessionInfo, qv); + } + return qv; + } //--------------------------------------------------< RepositoryService >--- Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java?rev=1151110&r1=1151109&r2=1151110&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java (original) +++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/Spi2davexRepositoryServiceFactory.java Tue Jul 26 14:20:43 2011 @@ -59,41 +59,64 @@ public class Spi2davexRepositoryServiceF */ public static final String PARAM_ITEMINFO_CACHE_SIZE = "org.apache.jackrabbit.spi2davex.ItemInfoCacheSize"; + /** + * Optional configuration parameter: It's value defines the + * maximumConnectionsPerHost value on the HttpClient configuration and + * must be an int greater than zero. + */ + public static final String PARAM_MAX_CONNECTIONS = "org.apache.jackrabbit.spi2davex.MaxConnections"; + public RepositoryService createRepositoryService(Map parameters) throws RepositoryException { + // retrieve the repository uri String uri; - if (parameters == null) { uri = System.getProperty(PARAM_REPOSITORY_URI); - } - else { - uri = parameters.get(PARAM_REPOSITORY_URI) == null - ? null - : parameters.get(PARAM_REPOSITORY_URI).toString(); + } else { + Object repoUri = parameters.get(PARAM_REPOSITORY_URI); + uri = (repoUri == null) ? null : repoUri.toString(); } if (uri == null) { uri = DEFAULT_REPOSITORY_URI; } + // load other optional configuration parameters BatchReadConfig brc = null; + int itemInfoCacheSize = ItemInfoCacheImpl.DEFAULT_CACHE_SIZE; + int maximumHttpConnections = 0; + if (parameters != null) { + // batchRead config Object param = parameters.get(PARAM_BATCHREAD_CONFIG); if (param != null && param instanceof BatchReadConfig) { brc = (BatchReadConfig) param; } - } - int itemInfoCacheSize = ItemInfoCacheImpl.DEFAULT_CACHE_SIZE; - Object param = parameters.get(PARAM_ITEMINFO_CACHE_SIZE); - if (param != null) { - try { - itemInfoCacheSize = Integer.parseInt(param.toString()); + // itemCache size config + param = parameters.get(PARAM_ITEMINFO_CACHE_SIZE); + if (param != null) { + try { + itemInfoCacheSize = Integer.parseInt(param.toString()); + } catch (NumberFormatException e) { + // ignore, use default + } } - catch (NumberFormatException e) { - // ignore, use default + + // max connections config + param = parameters.get(PARAM_MAX_CONNECTIONS); + if (param != null) { + try { + maximumHttpConnections = Integer.parseInt(param.toString()); + } catch ( NumberFormatException e ) { + // using default + } } } - return new RepositoryServiceImpl(uri, null, brc, itemInfoCacheSize); + if (maximumHttpConnections > 0) { + return new RepositoryServiceImpl(uri, null, brc, itemInfoCacheSize, maximumHttpConnections); + } else { + return new RepositoryServiceImpl(uri, null, brc, itemInfoCacheSize); + } } }