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: 550546 $ $Date: 2007-06-25 12:52:11 -0400 (Mon, 25 Jun 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 }
092 return connection;
093 }
094
095 /**
096 * in: non-null connection object, from non-null mcf.
097 * connection object is not associated with a managed connection
098 * out: supplied connection object is assiciated with a non-null ManagedConnection from mcf.
099 */
100 public void associateConnection(Object connection,
101 ManagedConnectionFactory managedConnectionFactory,
102 ConnectionRequestInfo connectionRequestInfo)
103 throws ResourceException {
104 ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, connectionRequestInfo);
105 ConnectionInfo ci = new ConnectionInfo(mci);
106 ci.setConnectionHandle(connection);
107 getStack().getConnection(ci);
108 }
109
110 ConnectionInterceptor getConnectionInterceptor() {
111 return getStack();
112 }
113
114 //statistics
115
116 public int getPartitionCount() {
117 return getPooling().getPartitionCount();
118 }
119
120 public int getPartitionMaxSize() {
121 return getPooling().getPartitionMaxSize();
122 }
123
124 public void setPartitionMaxSize(int maxSize) throws InterruptedException {
125 getPooling().setPartitionMaxSize(maxSize);
126 }
127
128 public int getPartitionMinSize() {
129 return getPooling().getPartitionMinSize();
130 }
131
132 public void setPartitionMinSize(int minSize) {
133 getPooling().setPartitionMinSize(minSize);
134 }
135
136 public int getIdleConnectionCount() {
137 return getPooling().getIdleConnectionCount();
138 }
139
140 public int getConnectionCount() {
141 return getPooling().getConnectionCount();
142 }
143
144 public int getBlockingTimeoutMilliseconds() {
145 return getPooling().getBlockingTimeoutMilliseconds();
146 }
147
148 public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
149 getPooling().setBlockingTimeoutMilliseconds(timeoutMilliseconds);
150 }
151
152 public int getIdleTimeoutMinutes() {
153 return getPooling().getIdleTimeoutMinutes();
154 }
155
156 public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
157 getPooling().setIdleTimeoutMinutes(idleTimeoutMinutes);
158 }
159
160 private ConnectionInterceptor getStack() {
161 return interceptors.getStack();
162 }
163
164 private ConnectionInterceptor getRecoveryStack() {
165 return interceptors.getRecoveryStack();
166 }
167
168 private boolean getIsRecoverable() {
169 return interceptors.getRecoveryStack() != null;
170 }
171
172 //public for persistence of pooling attributes (max, min size, blocking/idle timeouts)
173 public PoolingSupport getPooling() {
174 return interceptors.getPoolingAttributes();
175 }
176
177 public interface Interceptors {
178 ConnectionInterceptor getStack();
179
180 ConnectionInterceptor getRecoveryStack();
181
182 PoolingSupport getPoolingAttributes();
183 }
184
185 public void doStart() throws Exception {
186
187 }
188
189 public void doStop() throws Exception {
190 interceptors.getStack().destroy();
191 }
192
193 public void doFail() {
194 interceptors.getStack().destroy();
195 }
196 }