blob: ec431b78859116d5d13d84dd3dc789c58f3f5d48 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.geronimo.connector.outbound.connectiontracking;
import junit.framework.TestCase;
import org.apache.geronimo.connector.outbound.ConnectionInterceptor;
import org.apache.geronimo.connector.outbound.ConnectionTrackingInterceptor;
import org.apache.geronimo.connector.outbound.ConnectionInfo;
import org.apache.geronimo.connector.outbound.ConnectionReturnAction;
import org.apache.geronimo.connector.outbound.ManagedConnectionInfo;
import org.apache.geronimo.connector.outbound.GeronimoConnectionEventListener;
import javax.security.auth.Subject;
import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.ConnectionEventListener;
import javax.resource.spi.LocalTransaction;
import javax.resource.spi.ManagedConnectionMetaData;
import javax.transaction.xa.XAResource;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.lang.reflect.Proxy;
import java.io.PrintWriter;
/**
* @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
*/
public class ConnectionTrackingCoordinatorProxyTest extends TestCase implements ConnectionInterceptor {
private static final String name1 = "foo";
private ConnectionTrackingCoordinator connectionTrackingCoordinator;
private ConnectionTrackingInterceptor key1;
private Subject subject = null;
private Set<String> unshareableResources;
private Set<String> applicationManagedSecurityResources;
private ManagedConnectionInfo mci;
private ConnectionImpl connection;
protected void setUp() throws Exception {
super.setUp();
connectionTrackingCoordinator = new ConnectionTrackingCoordinator(true);
key1 = new ConnectionTrackingInterceptor(this, name1, connectionTrackingCoordinator);
unshareableResources = new HashSet<String>();
applicationManagedSecurityResources = new HashSet<String>();
mci = new ManagedConnectionInfo(null, null);
mci.setManagedConnection(new MockManagedConnection());
mci.setConnectionEventListener(new GeronimoConnectionEventListener(this, mci));
connection = new ConnectionImpl("ConnectionString");
}
protected void tearDown() throws Exception {
connectionTrackingCoordinator = null;
key1 = null;
super.tearDown();
}
public void testSimpleComponentContextLifecyle() throws Exception {
// enter component context
ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
ConnectorInstanceContext oldConnectorInstanceContext = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old instance context to be null", oldConnectorInstanceContext);
// simulate create connection
ConnectionInfo connectionInfo = createConnectionInfo();
connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);
// connection should be in component instance context
Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
assertNotNull("Expected one connections for key1", infos);
assertEquals("Expected one connection for key1", 1, infos.size());
assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());
// verify handle
Object handle = connectionInfo.getConnectionHandle();
assertNotNull("Expected a handle from ConnectionInfo", handle);
assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
ConnectionImpl connection = (ConnectionImpl) handle;
assertEquals("connection.getString()", "ConnectionString", connection.getString());
// verify proxy
Object proxy = connectionInfo.getConnectionProxy();
assertNotNull("Expected a proxy from ConnectionInfo", proxy);
assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
Connection connectionProxy = (Connection) proxy;
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
assertNotSame("Expected connection be proxied", connection, connectionProxy);
// exit component context
connectionTrackingCoordinator.exit(oldConnectorInstanceContext);
// connection should not be in context
connectionManagerMap = componentContext.getConnectionManagerMap();
infos = connectionManagerMap.get(key1);
assertEquals("Expected no connection set for key1", null, infos);
// enter again, and close the handle
oldConnectorInstanceContext = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old instance context to be null", oldConnectorInstanceContext);
connectionTrackingCoordinator.handleReleased(key1, connectionInfo, ConnectionReturnAction.DESTROY);
connectionTrackingCoordinator.exit(oldConnectorInstanceContext);
// use connection which will cause it to get a new handle if it is not closed
ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertTrue("Proxy should be connected", invocationHandler.isReleased());
assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
}
public void testReassociateConnection() throws Exception {
// enter component context
ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
ConnectorInstanceContext oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old component context to be null", oldConnectorInstanceContext1);
// simulate create connection
ConnectionInfo connectionInfo = createConnectionInfo();
connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);
// connection should be in component instance context
Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
assertNotNull("Expected one connections for key1", infos);
assertEquals("Expected one connection for key1", 1, infos.size());
assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());
// verify handle
Object handle = connectionInfo.getConnectionHandle();
assertNotNull("Expected a handle from ConnectionInfo", handle);
assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
ConnectionImpl connection = (ConnectionImpl) handle;
assertEquals("connection.getString()", "ConnectionString", connection.getString());
// verify proxy
Object proxy = connectionInfo.getConnectionProxy();
assertNotNull("Expected a proxy from ConnectionInfo", proxy);
assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
Connection connectionProxy = (Connection) proxy;
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
assertNotSame("Expected connection be proxied", connection, connectionProxy);
// exit outer component context
connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);
// proxy should be disconnected
ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
assertTrue("Proxy should be disconnected", invocationHandler.isReleased());
// enter again
oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old component context to be null", oldConnectorInstanceContext1);
// use connection to cause it to get a new handle
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
assertNotSame("Expected connection to not be original connection", connection, connectionProxy);
// destroy handle and exit context
connectionTrackingCoordinator.handleReleased(key1, connectionInfo, ConnectionReturnAction.DESTROY);
connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);
// connection should not be in context
connectionManagerMap = componentContext.getConnectionManagerMap();
infos = connectionManagerMap.get(key1);
assertNull("Expected no connection set for key1", infos);
// use connection which will cause it to get a new handle if it is not closed
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertTrue("Proxy should be connected", invocationHandler.isReleased());
assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
}
// some code calls the release method using a freshly constructed ContainerInfo without a proxy
// the ConnectionTrackingCoordinator must find the correct proxy and call releaseHandle or destroy
public void testReleaseNoProxy() throws Exception {
// enter component context
ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
ConnectorInstanceContext oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old component context to be null", oldConnectorInstanceContext1);
// simulate create connection
ConnectionInfo connectionInfo = createConnectionInfo();
connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);
// connection should be in component instance context
Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
assertNotNull("Expected one connections for key1", infos);
assertEquals("Expected one connection for key1", 1, infos.size());
assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());
// verify handle
Object handle = connectionInfo.getConnectionHandle();
assertNotNull("Expected a handle from ConnectionInfo", handle);
assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
ConnectionImpl connection = (ConnectionImpl) handle;
assertEquals("connection.getString()", "ConnectionString", connection.getString());
// verify proxy
Object proxy = connectionInfo.getConnectionProxy();
assertNotNull("Expected a proxy from ConnectionInfo", proxy);
assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
Connection connectionProxy = (Connection) proxy;
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
assertNotSame("Expected connection be proxied", connection, connectionProxy);
// simulate handle release due to a event listener, which won't hav the proxy
connectionTrackingCoordinator.handleReleased(key1, createConnectionInfo(), ConnectionReturnAction.RETURN_HANDLE);
// proxy should be disconnected
ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
assertTrue("Proxy should be disconnected", invocationHandler.isReleased());
// use connection which will cause it to get a new handle if it is not closed
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertTrue("Proxy should be connected", invocationHandler.isReleased());
assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
// exit outer component context
connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);
// proxy should be disconnected
assertTrue("Proxy should be disconnected", invocationHandler.isReleased());
// connection should not be in context
connectionManagerMap = componentContext.getConnectionManagerMap();
infos = connectionManagerMap.get(key1);
assertNull("Expected no connection set for key1", infos);
// enter again
oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
assertNull("Expected old component context to be null", oldConnectorInstanceContext1);
// exit context
connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);
// use connection which will cause it to get a new handle if it is not closed
assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
assertTrue("Proxy should be connected", invocationHandler.isReleased());
assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
}
public Subject mapSubject(Subject sourceSubject) {
return subject;
}
public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
}
public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
}
public void destroy() {
}
public void info(StringBuilder s) {
s.append(getClass().getName()).append("\n");
}
private ConnectionInfo createConnectionInfo() {
ConnectionInfo ci = new ConnectionInfo(mci);
ci.setConnectionHandle(connection);
mci.addConnectionHandle(ci);
return ci;
}
public static interface Connection {
String getString();
Connection getUnmanaged();
}
public static class ConnectionImpl implements Connection {
private final String string;
public ConnectionImpl(String string) {
this.string = string;
}
public String getString() {
return string;
}
public Connection getUnmanaged() {
return this;
}
}
public static class MockManagedConnection implements ManagedConnection {
public Object getConnection(Subject defaultSubject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
return null;
}
public void destroy() throws ResourceException {
}
public void cleanup() throws ResourceException {
}
public void associateConnection(Object object) throws ResourceException {
}
public void addConnectionEventListener(ConnectionEventListener connectionEventListener) {
}
public void removeConnectionEventListener(ConnectionEventListener connectionEventListener) {
}
public XAResource getXAResource() throws ResourceException {
return null;
}
public LocalTransaction getLocalTransaction() throws ResourceException {
return null;
}
public ManagedConnectionMetaData getMetaData() throws ResourceException {
return null;
}
public void setLogWriter(PrintWriter printWriter) throws ResourceException {
}
public PrintWriter getLogWriter() throws ResourceException {
return null;
}
public void dissociateConnections() throws ResourceException {
}
}
}