/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.core.storage.sql.ra; import java.util.Calendar; import javax.naming.Reference; import javax.resource.ResourceException; import javax.resource.cci.ConnectionSpec; import javax.resource.cci.RecordFactory; import javax.resource.cci.ResourceAdapterMetaData; import javax.resource.spi.ConnectionManager; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.NuxeoException; import org.nuxeo.ecm.core.storage.sql.Repository; import org.nuxeo.ecm.core.storage.sql.Session; import org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession; import org.nuxeo.runtime.jtajca.NuxeoConnectionManagerConfiguration; import org.nuxeo.runtime.jtajca.NuxeoContainer; import org.nuxeo.runtime.jtajca.NuxeoContainer.ConnectionManagerWrapper; /** * The connection factory delegates connection requests to the application server {@link ConnectionManager}. * <p> * An instance of this class is returned to the application when a JNDI lookup is done. * * @author Florent Guillaume */ public class ConnectionFactoryImpl implements Repository, org.nuxeo.ecm.core.model.Repository { private static final long serialVersionUID = 1L; private final ManagedConnectionFactoryImpl managedConnectionFactory; private final ConnectionManager connectionManager; private final String name; private Reference reference; /** * This is {@code true} if the connectionManager comes from an application server, or {@code false} if the * {@link ConnectionFactoryImpl} was constructed by application code and passed our manual * {@link ConnectionManagerImpl}. */ @SuppressWarnings("unused") private final boolean managed; public ConnectionFactoryImpl(ManagedConnectionFactoryImpl managedConnectionFactory, ConnectionManager connectionManager) { this.managedConnectionFactory = managedConnectionFactory; this.connectionManager = connectionManager; managed = !(connectionManager instanceof ConnectionManagerImpl); name = managedConnectionFactory.getName(); } // NXP 3992 -- exposed this for clean shutdown on cluster public ManagedConnectionFactoryImpl getManagedConnectionFactory() { return managedConnectionFactory; } /* * ----- javax.resource.cci.ConnectionFactory ----- */ /** * Gets a new connection. * * @param connectionSpec the connection spec (unused) * @return the connection */ @Override public Session getConnection(ConnectionSpec connectionSpec) { return getConnection(); } /** * Gets a new connection. * * @return the connection */ @Override public Session getConnection() { try { return (Session) connectionManager.allocateConnection(managedConnectionFactory, null); } catch (ResourceException e) { String msg = e.getMessage(); if (msg != null && msg.startsWith("No ManagedConnections available")) { String err = "Connection pool is fully used"; if (connectionManager instanceof ConnectionManagerWrapper) { ConnectionManagerWrapper cmw = (ConnectionManagerWrapper) connectionManager; NuxeoConnectionManagerConfiguration config = cmw.getConfiguration(); err = err + ", consider increasing " + "nuxeo.vcs.blocking-timeout-millis (currently " + config.getBlockingTimeoutMillis() + ") or " + "nuxeo.vcs.max-pool-size (currently " + config.getMaxPoolSize() + ")"; } throw new NuxeoException(err, e); } throw new NuxeoException(e); } } @Override public ResourceAdapterMetaData getMetaData() throws ResourceException { // TODO Auto-generated method stub throw new UnsupportedOperationException("Not implemented"); } @Override public RecordFactory getRecordFactory() throws ResourceException { throw new UnsupportedOperationException("Not implemented"); } /* * ----- javax.naming.Referenceable ----- */ @Override public Reference getReference() { return reference; } @Override public void setReference(Reference reference) { this.reference = reference; } /* * ----- Repository ----- */ @Override public void close() { throw new UnsupportedOperationException("Not implemented"); } /* * ----- org.nuxeo.ecm.core.model.Repository ----- */ @Override public String getName() { return name; } @Override public org.nuxeo.ecm.core.model.Session getSession() { return new SQLSession(getConnection(), this); } @Override public void shutdown() { try { NuxeoContainer.disposeConnectionManager(connectionManager); } catch (RuntimeException e) { LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot dispose connection manager of " + name); } try { managedConnectionFactory.shutdown(); } catch (NuxeoException e) { LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot shutdown connection factory " + name); } } /* * ----- org.nuxeo.ecm.core.model.RepositoryManagement ----- */ @Override public int getActiveSessionsCount() { return managedConnectionFactory.getActiveSessionsCount(); } @Override public long getCacheSize() { return managedConnectionFactory.getCacheSize(); } @Override public long getCachePristineSize() { return managedConnectionFactory.getCachePristineSize(); } @Override public long getCacheSelectionSize() { return managedConnectionFactory.getCacheSelectionSize(); } @Override public int clearCaches() { return managedConnectionFactory.clearCaches(); } @Override public void processClusterInvalidationsNext() { managedConnectionFactory.processClusterInvalidationsNext(); } @Override public void markReferencedBinaries() { managedConnectionFactory.markReferencedBinaries(); } @Override public int cleanupDeletedDocuments(int max, Calendar beforeTime) { return managedConnectionFactory.cleanupDeletedDocuments(max, beforeTime); } }