001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Florent Guillaume 011 */ 012 013package org.nuxeo.ecm.core.storage.sql.ra; 014 015import java.util.Calendar; 016 017import javax.naming.Reference; 018import javax.resource.ResourceException; 019import javax.resource.cci.ConnectionSpec; 020import javax.resource.cci.RecordFactory; 021import javax.resource.cci.ResourceAdapterMetaData; 022import javax.resource.spi.ConnectionManager; 023 024import org.apache.commons.logging.LogFactory; 025import org.nuxeo.ecm.core.api.NuxeoException; 026import org.nuxeo.ecm.core.storage.sql.Repository; 027import org.nuxeo.ecm.core.storage.sql.Session; 028import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository; 029import org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession; 030import org.nuxeo.runtime.jtajca.NuxeoConnectionManagerConfiguration; 031import org.nuxeo.runtime.jtajca.NuxeoContainer; 032import org.nuxeo.runtime.jtajca.NuxeoContainer.ConnectionManagerWrapper; 033 034/** 035 * The connection factory delegates connection requests to the application server {@link ConnectionManager}. 036 * <p> 037 * An instance of this class is returned to the application when a JNDI lookup is done. This is the datasource 038 * equivalent of {@link SQLRepository}. 039 * 040 * @author Florent Guillaume 041 */ 042public class ConnectionFactoryImpl implements Repository, org.nuxeo.ecm.core.model.Repository { 043 044 private static final long serialVersionUID = 1L; 045 046 private final ManagedConnectionFactoryImpl managedConnectionFactory; 047 048 private final ConnectionManager connectionManager; 049 050 private final String name; 051 052 private Reference reference; 053 054 /** 055 * This is {@code true} if the connectionManager comes from an application server, or {@code false} if the 056 * {@link ConnectionFactoryImpl} was constructed by application code and passed our manual 057 * {@link ConnectionManagerImpl}. 058 */ 059 @SuppressWarnings("unused") 060 private final boolean managed; 061 062 public ConnectionFactoryImpl(ManagedConnectionFactoryImpl managedConnectionFactory, 063 ConnectionManager connectionManager) { 064 this.managedConnectionFactory = managedConnectionFactory; 065 this.connectionManager = connectionManager; 066 managed = !(connectionManager instanceof ConnectionManagerImpl); 067 name = managedConnectionFactory.getName(); 068 } 069 070 // NXP 3992 -- exposed this for clean shutdown on cluster 071 public ManagedConnectionFactoryImpl getManagedConnectionFactory() { 072 return managedConnectionFactory; 073 } 074 075 /* 076 * ----- javax.resource.cci.ConnectionFactory ----- 077 */ 078 079 /** 080 * Gets a new connection. 081 * 082 * @param connectionSpec the connection spec (unused) 083 * @return the connection 084 */ 085 @Override 086 public Session getConnection(ConnectionSpec connectionSpec) { 087 return getConnection(); 088 } 089 090 /** 091 * Gets a new connection. 092 * 093 * @return the connection 094 */ 095 @Override 096 public Session getConnection() { 097 try { 098 return (Session) connectionManager.allocateConnection(managedConnectionFactory, null); 099 } catch (ResourceException e) { 100 String msg = e.getMessage(); 101 if (msg != null && msg.startsWith("No ManagedConnections available")) { 102 String err = "Connection pool is fully used"; 103 if (connectionManager instanceof ConnectionManagerWrapper) { 104 ConnectionManagerWrapper cmw = (ConnectionManagerWrapper) connectionManager; 105 NuxeoConnectionManagerConfiguration config = cmw.getConfiguration(); 106 err = err + ", consider increasing " + "nuxeo.vcs.blocking-timeout-millis (currently " 107 + config.getBlockingTimeoutMillis() + ") or " + "nuxeo.vcs.max-pool-size (currently " 108 + config.getMaxPoolSize() + ")"; 109 } 110 throw new NuxeoException(err, e); 111 } 112 throw new NuxeoException(e); 113 } 114 } 115 116 @Override 117 public ResourceAdapterMetaData getMetaData() throws ResourceException { 118 // TODO Auto-generated method stub 119 throw new UnsupportedOperationException("Not implemented"); 120 } 121 122 @Override 123 public RecordFactory getRecordFactory() throws ResourceException { 124 throw new UnsupportedOperationException("Not implemented"); 125 } 126 127 /* 128 * ----- javax.naming.Referenceable ----- 129 */ 130 131 @Override 132 public Reference getReference() { 133 return reference; 134 } 135 136 @Override 137 public void setReference(Reference reference) { 138 this.reference = reference; 139 } 140 141 /* 142 * ----- Repository ----- 143 */ 144 145 @Override 146 public void close() { 147 throw new UnsupportedOperationException("Not implemented"); 148 } 149 150 /* 151 * ----- org.nuxeo.ecm.core.model.Repository ----- 152 */ 153 154 @Override 155 public String getName() { 156 return name; 157 } 158 159 @Override 160 public org.nuxeo.ecm.core.model.Session getSession() { 161 return new SQLSession(getConnection(), this); 162 } 163 164 @Override 165 public void shutdown() { 166 try { 167 NuxeoContainer.disposeConnectionManager(connectionManager); 168 } catch (RuntimeException e) { 169 LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot dispose connection manager of " + name); 170 } 171 try { 172 managedConnectionFactory.shutdown(); 173 } catch (NuxeoException e) { 174 LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot shutdown connection factory " + name); 175 } 176 } 177 178 /* 179 * ----- org.nuxeo.ecm.core.model.RepositoryManagement ----- 180 */ 181 182 @Override 183 public int getActiveSessionsCount() { 184 return managedConnectionFactory.getActiveSessionsCount(); 185 } 186 187 @Override 188 public long getCacheSize() { 189 return managedConnectionFactory.getCacheSize(); 190 } 191 192 @Override 193 public long getCachePristineSize() { 194 return managedConnectionFactory.getCachePristineSize(); 195 } 196 197 @Override 198 public long getCacheSelectionSize() { 199 return managedConnectionFactory.getCacheSelectionSize(); 200 } 201 202 @Override 203 public int clearCaches() { 204 return managedConnectionFactory.clearCaches(); 205 } 206 207 @Override 208 public void processClusterInvalidationsNext() { 209 managedConnectionFactory.processClusterInvalidationsNext(); 210 } 211 212 @Override 213 public void markReferencedBinaries() { 214 managedConnectionFactory.markReferencedBinaries(); 215 } 216 217 @Override 218 public int cleanupDeletedDocuments(int max, Calendar beforeTime) { 219 return managedConnectionFactory.cleanupDeletedDocuments(max, beforeTime); 220 } 221 222}