Introduced ContextSourceTransactionManagerDelegate and ContextSourceAndDataSourceTransactionManager.
This commit is contained in:
@@ -49,5 +49,7 @@
|
||||
<classpathentry kind="lib" path="lib/test/backport-util-concurrent.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-ldap.jar" sourcepath="lib/source/spring-ldap-src.zip"/>
|
||||
<classpathentry kind="lib" path="lib/test/shared-asn1-codec.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/hsqldb.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/dbunit.jar"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
||||
211
sandbox/ivy.xml
211
sandbox/ivy.xml
@@ -1,105 +1,134 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ivy-module version="1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<ivy-module version="1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd">
|
||||
|
||||
<info organisation="org.springframework" module="spring-ldap-sandbox" />
|
||||
<info organisation="org.springframework"
|
||||
module="spring-ldap-sandbox" />
|
||||
|
||||
<configurations>
|
||||
<conf name="default" extends="global" />
|
||||
<conf name="global" visibility="private" />
|
||||
<conf name="buildtime" visibility="private" />
|
||||
<conf name="test" visibility="private" />
|
||||
<conf name="source" visibility="public" />
|
||||
</configurations>
|
||||
<configurations>
|
||||
<conf name="default" extends="global" />
|
||||
<conf name="global" visibility="private" />
|
||||
<conf name="buildtime" visibility="private" />
|
||||
<conf name="test" visibility="private" />
|
||||
<conf name="source" visibility="public" />
|
||||
</configurations>
|
||||
|
||||
<publications>
|
||||
<artifact name="spring-ldap-sandbox" type="jar" conf="default" />
|
||||
<artifact name="spring-ldap-sandbox-src" type="zip" conf="source" />
|
||||
<artifact name="spring-ldap-sandbox-src" type="zip"
|
||||
conf="source" />
|
||||
</publications>
|
||||
|
||||
<dependencies defaultconf="global->default">
|
||||
<!-- global (core) dependencies -->
|
||||
<dependency org="commons-logging" name="commons-logging" rev="1.0.4" />
|
||||
<dependency org="commons-lang" name="commons-lang" rev="2.1" />
|
||||
<dependency org="commons-collections" name="commons-collections" rev="3.1" />
|
||||
<dependency org="org.springframework" name="spring-ldap" rev="latest.integration"
|
||||
conf="global->default;source->source"/>
|
||||
<dependency org="org.springframework" name="spring-beans" rev="2.0.2"/>
|
||||
<dependency org="org.springframework" name="spring-core" rev="2.0.2"/>
|
||||
<dependency org="org.springframework" name="spring-context" rev="2.0.2"/>
|
||||
<dependency org="org.springframework" name="spring-dao" rev="2.0.2"/>
|
||||
<dependency org="org.springframework" name="spring-src" rev="2.0.2" conf="source->source">
|
||||
<artifact name="spring-src" type="zip"/>
|
||||
</dependency>
|
||||
<dependency org="com.sun" name="ldapbp" rev="1.0" />
|
||||
|
||||
<!-- build time only dependencies -->
|
||||
<dependency org="org.acegisecurity" name="acegi-security" rev="1.0.1"
|
||||
conf="buildtime->default" />
|
||||
<!-- kind of nasty, acegi needs some 1.2.7 stuff, so we override with newer! -->
|
||||
<dependency org="org.springframework" name="spring-jdbc" rev="2.0.2"
|
||||
conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-remoting" rev="2.0.2"
|
||||
conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-support" rev="2.0.2"
|
||||
conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-jpa" rev="2.0.2"
|
||||
conf="buildtime->default" />
|
||||
<dependencies defaultconf="global->default">
|
||||
<!-- global (core) dependencies -->
|
||||
<dependency org="commons-logging" name="commons-logging"
|
||||
rev="1.0.4" />
|
||||
<dependency org="commons-lang" name="commons-lang" rev="2.1" />
|
||||
<dependency org="commons-collections" name="commons-collections"
|
||||
rev="3.1" />
|
||||
<dependency org="org.springframework" name="spring-ldap"
|
||||
rev="latest.integration" conf="global->default;source->source" />
|
||||
<dependency org="org.springframework" name="spring-beans"
|
||||
rev="2.0.2" />
|
||||
<dependency org="org.springframework" name="spring-core"
|
||||
rev="2.0.2" />
|
||||
<dependency org="org.springframework" name="spring-context"
|
||||
rev="2.0.2" />
|
||||
<dependency org="org.springframework" name="spring-dao"
|
||||
rev="2.0.2" />
|
||||
<dependency org="org.springframework" name="spring-src"
|
||||
rev="2.0.2" conf="source->source">
|
||||
<artifact name="spring-src" type="zip" />
|
||||
</dependency>
|
||||
<dependency org="com.sun" name="ldapbp" rev="1.0" />
|
||||
|
||||
<!-- test time only dependencies -->
|
||||
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12" conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-mock" rev="2.0.2"
|
||||
conf="test->default"/>
|
||||
<dependency org="gsbase" name="gsbase" rev="2.0.1" conf="test->default"/>
|
||||
<dependency org="junit" name="junit" rev="3.8.1" conf="test->default"/>
|
||||
<dependency org="junit-addons" name="junit-addons" rev="1.4" conf="test->default"/>
|
||||
<dependency org="easymock" name="easymock" rev="1.2_Java1.3" conf="test->default"/>
|
||||
<dependency org="ehcache" name="ehcache" rev="1.1" conf="test->default" />
|
||||
<dependency org="net.sf.ehcache" name="ehcache-constructs" rev="0.6" conf="test->default" />
|
||||
<dependency org="jexcelapi" name="jxl" rev="2.5.9" conf="test->default" />
|
||||
<dependency org="org.ddsteps" name="DDSteps" rev="1.1" conf="test->default" />
|
||||
<dependency org="cglib" name="cglib-nodep" rev="2.1_3" conf="test->default"/>
|
||||
<dependency org="org.springframework" name="spring-aop" rev="2.0.2" conf="test->default"/>
|
||||
<dependency org="aopalliance" name="aopalliance" rev="1.0" conf="test->default" />
|
||||
|
||||
<!-- Test dependencies for Apache Directory Server -->
|
||||
<dependency org="org.apache.directory.server" name="apacheds-core" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-core-shared" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-server-jndi" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-server-main" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-protocol-shared" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-protocol-changepw" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-protocol-kerberos" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-kerberos-shared" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.server" name="apacheds-protocol-ldap" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<!-- build time only dependencies -->
|
||||
<dependency org="org.acegisecurity" name="acegi-security"
|
||||
rev="1.0.1" conf="buildtime->default" />
|
||||
<!-- kind of nasty, acegi needs some 1.2.7 stuff, so we override with newer! -->
|
||||
<dependency org="org.springframework" name="spring-jdbc"
|
||||
rev="2.0.2" conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-remoting"
|
||||
rev="2.0.2" conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-support"
|
||||
rev="2.0.2" conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-jpa"
|
||||
rev="2.0.2" conf="buildtime->default" />
|
||||
|
||||
<dependency org="org.apache.directory.shared" name="shared-asn1" rev="0.9.5.3"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.shared" name="shared-asn1-codec" rev="0.9.5.3"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.directory.shared" name="shared-ldap" rev="0.9.5.3"
|
||||
conf="test->default"/>
|
||||
<!-- test time only dependencies -->
|
||||
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12"
|
||||
conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-mock"
|
||||
rev="2.0.2" conf="test->default" />
|
||||
<dependency org="gsbase" name="gsbase" rev="2.0.1"
|
||||
conf="test->default" />
|
||||
<dependency org="junit" name="junit" rev="3.8.1"
|
||||
conf="test->default" />
|
||||
<dependency org="junit-addons" name="junit-addons" rev="1.4"
|
||||
conf="test->default" />
|
||||
<dependency org="easymock" name="easymock" rev="1.2_Java1.3"
|
||||
conf="test->default" />
|
||||
<dependency org="ehcache" name="ehcache" rev="1.1"
|
||||
conf="test->default" />
|
||||
<dependency org="net.sf.ehcache" name="ehcache-constructs"
|
||||
rev="0.6" conf="test->default" />
|
||||
<dependency org="jexcelapi" name="jxl" rev="2.5.9"
|
||||
conf="test->default" />
|
||||
<dependency org="org.ddsteps" name="DDSteps" rev="1.1"
|
||||
conf="test->default" />
|
||||
<dependency org="cglib" name="cglib-nodep" rev="2.1_3"
|
||||
conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-aop"
|
||||
rev="2.0.2" conf="test->default" />
|
||||
<dependency org="aopalliance" name="aopalliance" rev="1.0"
|
||||
conf="test->default" />
|
||||
<dependency org="hsqldb" name="hsqldb" rev="1.8.0.7"
|
||||
conf="test->default" />
|
||||
<dependency org="org.dbunit" name="dbunit" rev="2.2"
|
||||
conf="test->default" />
|
||||
|
||||
<dependency org="log4j" name="log4j" rev="1.2.9" conf="test->default" />
|
||||
<dependency org="antlr" name="antlr" rev="2.7.2" conf="test->default" />
|
||||
<dependency org="jdbm" name="jdbm" rev="1.0" conf="test->default" />
|
||||
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.0"
|
||||
conf="test->default" />
|
||||
<dependency org="org.apache.mina" name="mina-core" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<dependency org="org.apache.mina" name="mina-filter-ssl" rev="1.0.0"
|
||||
conf="test->default"/>
|
||||
<!-- End test dependencies for Apache Directory Server -->
|
||||
<!-- Test dependencies for Apache Directory Server -->
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-core" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-core-shared" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-server-jndi" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-server-main" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-protocol-shared" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-protocol-changepw" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-protocol-kerberos" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-kerberos-shared" rev="1.0.0" conf="test->default" />
|
||||
<dependency org="org.apache.directory.server"
|
||||
name="apacheds-protocol-ldap" rev="1.0.0" conf="test->default" />
|
||||
|
||||
<dependency org="org.apache.directory.shared" name="shared-asn1"
|
||||
rev="0.9.5.3" conf="test->default" />
|
||||
<dependency org="org.apache.directory.shared"
|
||||
name="shared-asn1-codec" rev="0.9.5.3" conf="test->default" />
|
||||
<dependency org="org.apache.directory.shared" name="shared-ldap"
|
||||
rev="0.9.5.3" conf="test->default" />
|
||||
|
||||
<dependency org="log4j" name="log4j" rev="1.2.9"
|
||||
conf="test->default" />
|
||||
<dependency org="antlr" name="antlr" rev="2.7.2"
|
||||
conf="test->default" />
|
||||
<dependency org="jdbm" name="jdbm" rev="1.0"
|
||||
conf="test->default" />
|
||||
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.0"
|
||||
conf="test->default" />
|
||||
<dependency org="org.apache.mina" name="mina-core" rev="1.0.0"
|
||||
conf="test->default" />
|
||||
<dependency org="org.apache.mina" name="mina-filter-ssl"
|
||||
rev="1.0.0" conf="test->default" />
|
||||
<!-- End test dependencies for Apache Directory Server -->
|
||||
|
||||
</dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</ivy-module>
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
package org.springframework.ldap.transaction.core;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.ldap.LdapServerManager;
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.core.AttributesMapper;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
/**
|
||||
* Integration tests for {@link ContextSourceAndDataSourceTransactionManager}.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class ContextSourceAndDataSourceTransactionManagerIntegrationTest extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private static Log log = LogFactory
|
||||
.getLog(ContextSourceTransactionManagerIntegrationTest.class);
|
||||
.getLog(ContextSourceAndDataSourceTransactionManagerIntegrationTest.class);
|
||||
|
||||
public ContextSourceTransactionManagerIntegrationTest() {
|
||||
public ContextSourceAndDataSourceTransactionManagerIntegrationTest() {
|
||||
setAutowireMode(AbstractDependencyInjectionSpringContextTests.AUTOWIRE_BY_NAME);
|
||||
}
|
||||
|
||||
@@ -25,6 +37,8 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private LdapServerManager ldapServerManager;
|
||||
|
||||
public void setLdapServerManager(LdapServerManager ldapServerManager) {
|
||||
@@ -44,7 +58,19 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
ldapServerManager.cleanAndSetup("setup_data.ldif");
|
||||
jdbcTemplate
|
||||
.execute("create table PERSON(fullname VARCHAR, lastname VARCHAR, description VARCHAR)");
|
||||
jdbcTemplate.update("insert into PERSON values(?, ?, ?)", new Object[] {
|
||||
"Some Person", "Person", "Sweden, Company1, Some Person" });
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
jdbcTemplate.execute("drop table PERSON");
|
||||
}
|
||||
|
||||
public void testCreateWithException() {
|
||||
@@ -58,12 +84,27 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
|
||||
log.debug("Verifying result");
|
||||
|
||||
// Verify that no entry was created
|
||||
try {
|
||||
ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
|
||||
fail("NameNotFoundException expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname='some testperson'",
|
||||
new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
fail("EmptyResultDataAccessException expected");
|
||||
} catch (EmptyResultDataAccessException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreate() {
|
||||
@@ -71,13 +112,24 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
"some description");
|
||||
|
||||
log.debug("Verifying result");
|
||||
ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
|
||||
Object ldapResult = ldapTemplate
|
||||
.lookup("cn=some testperson, ou=company1, c=Sweden");
|
||||
Object dbResult = jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname='some testperson'",
|
||||
new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
assertNotNull(ldapResult);
|
||||
assertNotNull(dbResult);
|
||||
}
|
||||
|
||||
public void testUpdateWithException() {
|
||||
String dn = "cn=Some Person,ou=company1,c=Sweden";
|
||||
try {
|
||||
dummyDao.updateWithException(dn, "Updated Person",
|
||||
dummyDao.updateWithException(dn, "Some Person", "Updated Person",
|
||||
"Updated description");
|
||||
fail("DummyException expected");
|
||||
} catch (DummyException expected) {
|
||||
@@ -86,7 +138,7 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
|
||||
log.debug("Verifying result");
|
||||
|
||||
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attributes)
|
||||
throws NamingException {
|
||||
assertEquals("Person", attributes.get("sn").get());
|
||||
@@ -96,15 +148,29 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(result);
|
||||
Object jdbcResult = jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname=?",
|
||||
new Object[] { "Some Person" }, new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
assertEquals("Person", rs.getString("lastname"));
|
||||
assertEquals("Sweden, Company1, Some Person", rs
|
||||
.getString("description"));
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(ldapResult);
|
||||
assertNotNull(jdbcResult);
|
||||
}
|
||||
|
||||
public void testUpdate() {
|
||||
String dn = "cn=Some Person,ou=company1,c=Sweden";
|
||||
dummyDao.update(dn, "Updated Person", "Updated description");
|
||||
dummyDao.update(dn, "Some Person", "Updated Person",
|
||||
"Updated description");
|
||||
|
||||
log.debug("Verifying result");
|
||||
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attributes)
|
||||
throws NamingException {
|
||||
assertEquals("Updated Person", attributes.get("sn").get());
|
||||
@@ -114,7 +180,20 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(result);
|
||||
Object jdbcResult = jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname=?",
|
||||
new Object[] { "Some Person" }, new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
assertEquals("Updated Person", rs.getString("lastname"));
|
||||
assertEquals("Updated description", rs
|
||||
.getString("description"));
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(ldapResult);
|
||||
assertNotNull(jdbcResult);
|
||||
}
|
||||
|
||||
public void testUpdateAndRenameWithException() {
|
||||
@@ -217,31 +296,39 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
String dn = "cn=Some Person,ou=company1,c=Sweden";
|
||||
try {
|
||||
// Perform test
|
||||
dummyDao.unbindWithException(dn);
|
||||
dummyDao.unbindWithException(dn, "Some Person");
|
||||
fail("DummyException expected");
|
||||
} catch (DummyException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
// Verify result - check that the operation was properly rolled back
|
||||
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attributes)
|
||||
throws NamingException {
|
||||
assertEquals("Some Person", attributes.get("cn").get());
|
||||
assertEquals("Person", attributes.get("sn").get());
|
||||
assertEquals("Sweden, Company1, Some Person", attributes.get(
|
||||
"description").get());
|
||||
// Just verify that the entry still exists.
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(result);
|
||||
Object jdbcResult = jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname=?",
|
||||
new Object[] { "Some Person" }, new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
// Just verify that the entry still exists.
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
|
||||
assertNotNull(ldapResult);
|
||||
assertNotNull(jdbcResult);
|
||||
}
|
||||
|
||||
public void testUnbind() {
|
||||
String dn = "cn=Some Person,ou=company1,c=Sweden";
|
||||
// Perform test
|
||||
dummyDao.unbind(dn);
|
||||
dummyDao.unbind(dn, "Some Person");
|
||||
|
||||
try {
|
||||
// Verify result - check that the operation was not rolled back
|
||||
@@ -251,5 +338,22 @@ public class ContextSourceTransactionManagerIntegrationTest extends
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
jdbcTemplate.queryForObject(
|
||||
"select * from PERSON where fullname=?",
|
||||
new Object[] { "Some Person" }, new RowMapper() {
|
||||
public Object mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
fail("EmptyResultDataAccessException expected");
|
||||
} catch (EmptyResultDataAccessException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,10 @@ public interface DummyDao {
|
||||
void create(String country, String company, String fullname,
|
||||
String lastname, String description);
|
||||
|
||||
void update(String dn, String lastname, String description);
|
||||
void update(String dn, String fullname, String lastname, String description);
|
||||
|
||||
void updateWithException(String dn, String lastname, String description);
|
||||
void updateWithException(String dn, String fullname, String lastname,
|
||||
String description);
|
||||
|
||||
void updateAndRename(String dn, String newDn, String description);
|
||||
|
||||
@@ -21,8 +22,8 @@ public interface DummyDao {
|
||||
void modifyAttributesWithException(String dn, String lastName,
|
||||
String description);
|
||||
|
||||
void unbind(String dn);
|
||||
void unbind(String dn, String fullname);
|
||||
|
||||
void unbindWithException(String dn);
|
||||
void unbindWithException(String dn, String fullname);
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
|
||||
public class DummyDaoImpl implements DummyDao{
|
||||
public class LdapAndJdbcDummyDaoImpl implements DummyDao {
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@@ -21,13 +21,10 @@ public class DummyDaoImpl implements DummyDao{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#createWithException(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#createWithException(java.lang.String,
|
||||
* java.lang.String, java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#createWithException(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void createWithException(String country, String company,
|
||||
String fullname, String lastname, String description) {
|
||||
create(country, company, fullname, lastname, description);
|
||||
@@ -37,13 +34,10 @@ public class DummyDaoImpl implements DummyDao{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#create(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#create(java.lang.String,
|
||||
* java.lang.String, java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#create(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void create(String country, String company, String fullname,
|
||||
String lastname, String description) {
|
||||
DistinguishedName dn = new DistinguishedName();
|
||||
@@ -57,70 +51,63 @@ public class DummyDaoImpl implements DummyDao{
|
||||
ctx.setAttributeValue("sn", lastname);
|
||||
ctx.setAttributeValue("description", description);
|
||||
ldapTemplate.bind(dn, ctx, null);
|
||||
// jdbcTemplate.execute("insert into test values(1, 'kalle', 'pettersson', 123)");
|
||||
jdbcTemplate.update("insert into PERSON values(?, ?, ?)", new Object[] {
|
||||
fullname, lastname, description });
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#update(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#update(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#update(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void update(String dn, String lastname, String description) {
|
||||
public void update(String dn, String fullname, String lastname,
|
||||
String description) {
|
||||
DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
ctx.setAttributeValue("sn", lastname);
|
||||
ctx.setAttributeValue("description", description);
|
||||
ctx.update();
|
||||
|
||||
ldapTemplate.rebind(dn, ctx, null);
|
||||
jdbcTemplate
|
||||
.update(
|
||||
"update PERSON set lastname=?, description = ? where fullname = ?",
|
||||
new Object[] { lastname, description, fullname });
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#updateWithException(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#updateWithException(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateWithException(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void updateWithException(String dn, String lastname,
|
||||
String description) {
|
||||
update(dn, lastname, description);
|
||||
public void updateWithException(String dn, String fullname,
|
||||
String lastname, String description) {
|
||||
update(dn, fullname, lastname, description);
|
||||
throw new DummyException("This method failed.");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#updateAndRename(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#updateAndRename(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateAndRename(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void updateAndRename(String dn, String newDn, String description) {
|
||||
DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
ctx.setAttributeValue("description", description);
|
||||
ctx.update();
|
||||
|
||||
ldapTemplate.rebind(dn, ctx, null);
|
||||
|
||||
ldapTemplate.rename(dn, newDn);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#updateAndRenameWithException(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#updateAndRenameWithException(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateAndRenameWithException(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void updateAndRenameWithException(String dn, String newDn,
|
||||
String description) {
|
||||
updateAndRename(dn, newDn, description);
|
||||
@@ -130,12 +117,9 @@ public class DummyDaoImpl implements DummyDao{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#modifyAttributes(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#modifyAttributes(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#modifyAttributes(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void modifyAttributes(String dn, String lastName, String description) {
|
||||
DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
ctx.setAttributeValue("sn", lastName);
|
||||
@@ -147,12 +131,9 @@ public class DummyDaoImpl implements DummyDao{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#modifyAttributesWithException(java.lang.String,
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#modifyAttributesWithException(java.lang.String,
|
||||
* java.lang.String, java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#modifyAttributesWithException(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void modifyAttributesWithException(String dn, String lastName,
|
||||
String description) {
|
||||
modifyAttributes(dn, lastName, description);
|
||||
@@ -162,25 +143,21 @@ public class DummyDaoImpl implements DummyDao{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#unbind(java.lang.String)
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#unbind(java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#unbind(java.lang.String)
|
||||
*/
|
||||
public void unbind(String dn) {
|
||||
public void unbind(String dn, String fullname) {
|
||||
ldapTemplate.unbind(dn);
|
||||
jdbcTemplate.update("delete from PERSON where fullname=?",
|
||||
new Object[] { fullname });
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.transaction.DummyDao#unbindWithException(java.lang.String)
|
||||
* @see org.springframework.ldap.transaction.core.DummyDao#unbindWithException(java.lang.String)
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.ldap.support.transaction.TempDummyDao#unbindWithException(java.lang.String)
|
||||
*/
|
||||
public void unbindWithException(String dn) {
|
||||
unbind(dn);
|
||||
public void unbindWithException(String dn, String fullname) {
|
||||
unbind(dn, fullname);
|
||||
throw new DummyException("This operation failed.");
|
||||
}
|
||||
}
|
||||
@@ -15,19 +15,14 @@
|
||||
*/
|
||||
package org.springframework.ldap.transaction.core;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.ldap.transaction.CompensatingTransactionOperationExecutor;
|
||||
import org.springframework.ldap.transaction.CompensatingTransactionOperationRecorder;
|
||||
import org.springframework.ldap.transaction.DefaultCompensatingTransactionOperationManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* TransactionManager for managing LDAP transactions. Since transactions are not
|
||||
@@ -92,56 +87,27 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* {@link DefaultTempEntryRenamingStrategy}), specified in
|
||||
* {@link #setRenamingStrategy(TempEntryRenamingStrategy)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The actual work of this Transaction Manager is delegated to a
|
||||
* {@link ContextSourceTransactionManagerDelegate}. This is because the exact
|
||||
* same logic needs to be used if we want to wrap a JDBC and LDAP transaction in
|
||||
* the same logical transaction.
|
||||
* </p>
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
* @see ContextSourceAndDataSourceTransactionManager
|
||||
* @see ContextSourceTransactionManagerDelegate
|
||||
* @see DefaultCompensatingTransactionOperationManager
|
||||
* @see TempEntryRenamingStrategy
|
||||
* @see TransactionAwareContextSourceProxy
|
||||
*/
|
||||
public class ContextSourceTransactionManager extends
|
||||
AbstractPlatformTransactionManager {
|
||||
|
||||
private static final long serialVersionUID = -4308820955185446535L;
|
||||
private static final long serialVersionUID = 7138208218687237856L;
|
||||
|
||||
private static Log log = LogFactory
|
||||
.getLog(ContextSourceTransactionManager.class);
|
||||
|
||||
private ContextSource contextSource;
|
||||
|
||||
private TempEntryRenamingStrategy renamingStrategy = new DefaultTempEntryRenamingStrategy();
|
||||
|
||||
/**
|
||||
* Set the ContextSource to work on. Even though the actual ContextSource
|
||||
* sent to the LdapTemplate instance should be a
|
||||
* {@link TransactionAwareContextSourceProxy}, the one sent to this method
|
||||
* should be the target of that proxy. If it is not, the target will be
|
||||
* extracted and used instead.
|
||||
*
|
||||
* @param contextSource
|
||||
* the ContextSource to work on.
|
||||
*/
|
||||
public void setContextSource(ContextSource contextSource) {
|
||||
if (contextSource instanceof TransactionAwareContextSourceProxy) {
|
||||
TransactionAwareContextSourceProxy proxy = (TransactionAwareContextSourceProxy) contextSource;
|
||||
this.contextSource = proxy.getTarget();
|
||||
} else {
|
||||
this.contextSource = contextSource;
|
||||
}
|
||||
}
|
||||
|
||||
public ContextSource getContextSource() {
|
||||
return contextSource;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doGetTransaction()
|
||||
*/
|
||||
protected Object doGetTransaction() throws TransactionException {
|
||||
DirContextHolder contextHolder = (DirContextHolder) TransactionSynchronizationManager
|
||||
.getResource(this.contextSource);
|
||||
ContextSourceTransactionObject txObject = new ContextSourceTransactionObject(
|
||||
contextHolder);
|
||||
return txObject;
|
||||
}
|
||||
private ContextSourceTransactionManagerDelegate delegate = new ContextSourceTransactionManagerDelegate();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -151,17 +117,16 @@ public class ContextSourceTransactionManager extends
|
||||
*/
|
||||
protected void doBegin(Object transaction, TransactionDefinition definition)
|
||||
throws TransactionException {
|
||||
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) transaction;
|
||||
delegate.doBegin(transaction, definition);
|
||||
}
|
||||
|
||||
if (txObject.getContextHolder() == null) {
|
||||
DirContext newCtx = getContextSource().getReadOnlyContext();
|
||||
DirContextHolder contextHolder = new DirContextHolder(newCtx,
|
||||
renamingStrategy);
|
||||
|
||||
txObject.setContextHolder(contextHolder);
|
||||
TransactionSynchronizationManager.bindResource(getContextSource(),
|
||||
contextHolder);
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
|
||||
*/
|
||||
protected void doCleanupAfterCompletion(Object transaction) {
|
||||
delegate.doCleanupAfterCompletion(transaction);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -171,10 +136,16 @@ public class ContextSourceTransactionManager extends
|
||||
*/
|
||||
protected void doCommit(DefaultTransactionStatus status)
|
||||
throws TransactionException {
|
||||
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) status
|
||||
.getTransaction();
|
||||
txObject.getContextHolder().getTransactionDataManager().commit();
|
||||
delegate.doCommit(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doGetTransaction()
|
||||
*/
|
||||
protected Object doGetTransaction() throws TransactionException {
|
||||
return delegate.doGetTransaction();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -184,42 +155,38 @@ public class ContextSourceTransactionManager extends
|
||||
*/
|
||||
protected void doRollback(DefaultTransactionStatus status)
|
||||
throws TransactionException {
|
||||
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) status
|
||||
.getTransaction();
|
||||
txObject.getContextHolder().getTransactionDataManager().rollback();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
|
||||
*/
|
||||
protected void doCleanupAfterCompletion(Object transaction) {
|
||||
log.debug("Cleaning stored ContextHolder");
|
||||
TransactionSynchronizationManager.unbindResource(contextSource);
|
||||
|
||||
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) transaction;
|
||||
DirContext ctx = txObject.getContextHolder().getCtx();
|
||||
|
||||
try {
|
||||
log.debug("Closing target context");
|
||||
ctx.close();
|
||||
} catch (NamingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
txObject.getContextHolder().clear();
|
||||
delegate.doRollback(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link TempEntryRenamingStrategy} to be used when renaming
|
||||
* temporary entries in unbind and rebind operations. Default value is a
|
||||
* {@link DefaultTempEntryRenamingStrategy}.
|
||||
* Get the ContextSource.
|
||||
*
|
||||
* @return the contextSource.
|
||||
* @see ContextSourceTransactionManagerDelegate#getContextSource()
|
||||
*/
|
||||
public ContextSource getContextSource() {
|
||||
return delegate.getContextSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ContextSource.
|
||||
*
|
||||
* @param contextSource
|
||||
* the ContextSource.
|
||||
* @see ContextSourceTransactionManagerDelegate#setContextSource(ContextSource)
|
||||
*/
|
||||
public void setContextSource(ContextSource contextSource) {
|
||||
delegate.setContextSource(contextSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link TempEntryRenamingStrategy}.
|
||||
*
|
||||
* @param renamingStrategy
|
||||
* the {@link TempEntryRenamingStrategy} to use.
|
||||
* the Renaming Strategy.
|
||||
* @see ContextSourceTransactionManagerDelegate#setRenamingStrategy(TempEntryRenamingStrategy)
|
||||
*/
|
||||
public void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy) {
|
||||
this.renamingStrategy = renamingStrategy;
|
||||
delegate.setRenamingStrategy(renamingStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user