001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.connector.outbound; 019 020 import javax.resource.ResourceException; 021 import javax.resource.spi.ConnectionManager; 022 import javax.resource.spi.ConnectionRequestInfo; 023 import javax.resource.spi.LazyAssociatableConnectionManager; 024 import javax.resource.spi.ManagedConnectionFactory; 025 import javax.transaction.SystemException; 026 027 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport; 028 import org.apache.geronimo.transaction.manager.NamedXAResource; 029 import org.apache.geronimo.transaction.manager.RecoverableTransactionManager; 030 031 /** 032 * @version $Rev: 585309 $ $Date: 2007-10-17 02:54:22 +0200 (Wed, 17 Oct 2007) $ 033 */ 034 public abstract class AbstractConnectionManager implements ConnectionManagerContainer, ConnectionManager, LazyAssociatableConnectionManager, PoolingAttributes { 035 protected final Interceptors interceptors; 036 private final RecoverableTransactionManager transactionManager; 037 038 //default constructor for use as endpoint 039 public AbstractConnectionManager() { 040 interceptors = null; 041 transactionManager = null; 042 } 043 044 public AbstractConnectionManager(Interceptors interceptors, RecoverableTransactionManager transactionManager) { 045 this.interceptors = interceptors; 046 this.transactionManager = transactionManager; 047 } 048 049 public Object createConnectionFactory(ManagedConnectionFactory mcf) throws ResourceException { 050 return mcf.createConnectionFactory(this); 051 } 052 053 protected ConnectionManager getConnectionManager() { 054 return this; 055 } 056 057 public void doRecovery(ManagedConnectionFactory managedConnectionFactory) { 058 try { 059 if (!getIsRecoverable()) { 060 return; 061 } 062 ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, null); 063 064 ConnectionInfo recoveryConnectionInfo = new ConnectionInfo(mci); 065 getRecoveryStack().getConnection(recoveryConnectionInfo); 066 067 // For pooled resources, we may now have a new MCI (not the one constructed above). Make sure we use the correct MCI 068 NamedXAResource xaResource = (NamedXAResource) recoveryConnectionInfo.getManagedConnectionInfo().getXAResource(); 069 if (xaResource != null) { 070 transactionManager.recoverResourceManager(xaResource); 071 getRecoveryStack().returnConnection(recoveryConnectionInfo, ConnectionReturnAction.DESTROY); 072 } 073 } catch (ResourceException e) { 074 transactionManager.recoveryError((SystemException)new SystemException("Could not obtain recovery XAResource for managedConnectionFactory " + managedConnectionFactory).initCause(e)); 075 } 076 } 077 078 /** 079 * in: mcf != null, is a deployed mcf 080 * out: useable connection object. 081 */ 082 public Object allocateConnection(ManagedConnectionFactory managedConnectionFactory, 083 ConnectionRequestInfo connectionRequestInfo) 084 throws ResourceException { 085 ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, connectionRequestInfo); 086 ConnectionInfo ci = new ConnectionInfo(mci); 087 getStack().getConnection(ci); 088 Object connection = ci.getConnectionProxy(); 089 if (connection == null) { 090 connection = ci.getConnectionHandle(); 091 } else { 092 // connection proxy is used only once so we can be notified 093 // by the garbage collector when a connection is abandoned 094 ci.setConnectionProxy(null); 095 } 096 return connection; 097 } 098 099 /** 100 * in: non-null connection object, from non-null mcf. 101 * connection object is not associated with a managed connection 102 * out: supplied connection object is assiciated with a non-null ManagedConnection from mcf. 103 */ 104 public void associateConnection(Object connection, 105 ManagedConnectionFactory managedConnectionFactory, 106 ConnectionRequestInfo connectionRequestInfo) 107 throws ResourceException { 108 ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, connectionRequestInfo); 109 ConnectionInfo ci = new ConnectionInfo(mci); 110 ci.setConnectionHandle(connection); 111 getStack().getConnection(ci); 112 } 113 114 ConnectionInterceptor getConnectionInterceptor() { 115 return getStack(); 116 } 117 118 //statistics 119 120 public int getPartitionCount() { 121 return getPooling().getPartitionCount(); 122 } 123 124 public int getPartitionMaxSize() { 125 return getPooling().getPartitionMaxSize(); 126 } 127 128 public void setPartitionMaxSize(int maxSize) throws InterruptedException { 129 getPooling().setPartitionMaxSize(maxSize); 130 } 131 132 public int getPartitionMinSize() { 133 return getPooling().getPartitionMinSize(); 134 } 135 136 public void setPartitionMinSize(int minSize) { 137 getPooling().setPartitionMinSize(minSize); 138 } 139 140 public int getIdleConnectionCount() { 141 return getPooling().getIdleConnectionCount(); 142 } 143 144 public int getConnectionCount() { 145 return getPooling().getConnectionCount(); 146 } 147 148 public int getBlockingTimeoutMilliseconds() { 149 return getPooling().getBlockingTimeoutMilliseconds(); 150 } 151 152 public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) { 153 getPooling().setBlockingTimeoutMilliseconds(timeoutMilliseconds); 154 } 155 156 public int getIdleTimeoutMinutes() { 157 return getPooling().getIdleTimeoutMinutes(); 158 } 159 160 public void setIdleTimeoutMinutes(int idleTimeoutMinutes) { 161 getPooling().setIdleTimeoutMinutes(idleTimeoutMinutes); 162 } 163 164 private ConnectionInterceptor getStack() { 165 return interceptors.getStack(); 166 } 167 168 private ConnectionInterceptor getRecoveryStack() { 169 return interceptors.getRecoveryStack(); 170 } 171 172 private boolean getIsRecoverable() { 173 return interceptors.getRecoveryStack() != null; 174 } 175 176 //public for persistence of pooling attributes (max, min size, blocking/idle timeouts) 177 public PoolingSupport getPooling() { 178 return interceptors.getPoolingAttributes(); 179 } 180 181 public interface Interceptors { 182 ConnectionInterceptor getStack(); 183 184 ConnectionInterceptor getRecoveryStack(); 185 186 PoolingSupport getPoolingAttributes(); 187 } 188 189 public void doStart() throws Exception { 190 191 } 192 193 public void doStop() throws Exception { 194 interceptors.getStack().destroy(); 195 } 196 197 public void doFail() { 198 interceptors.getStack().destroy(); 199 } 200 }