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