diff --git a/mvn-build/core/pom.xml b/mvn-build/core/pom.xml index 55f8a90a..2ab77bbd 100644 --- a/mvn-build/core/pom.xml +++ b/mvn-build/core/pom.xml @@ -2,7 +2,7 @@ - + 4.0.0 org.springframework.ldap spring-ldap @@ -72,6 +72,12 @@ 1.0 provided + + com.sun + ldapbp + 1.0 + provided + org.springframework @@ -95,6 +101,12 @@ ${spring.version} provided + + org.springframework + spring-orm + ${spring.version} + provided + junit diff --git a/mvn-build/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndHibernateTransactionManager.java b/mvn-build/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndHibernateTransactionManager.java new file mode 100755 index 00000000..96bed5ee --- /dev/null +++ b/mvn-build/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndHibernateTransactionManager.java @@ -0,0 +1,203 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed 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.springframework.ldap.transaction.compensating.manager; + +import org.springframework.ldap.core.ContextSource; +import org.springframework.ldap.transaction.compensating.TempEntryRenamingStrategy; +import org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManagerDelegate; +import org.springframework.orm.hibernate3.HibernateTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionSuspensionNotSupportedException; +import org.springframework.transaction.support.DefaultTransactionStatus; +/** + * A Transaction Manager to manage LDAP and Hibernate 3 operations within the same + * transaction. Note that even though the same logical transaction is used, this + * is not a JTA XA transaction; no two-phase commit will be performed, + * and thus commit and rollback may yield unexpected results.
+ * This Transaction Manager is as good as it gets when you are using in LDAP in + * combination with a Hibernate 3 and unable to use XA transactions because LDAP + * is not transactional by design to begin with.
+ * + * Furthermore, this manager does not support nested transactions + * @author Hans Westerbeek + * @since 1.2.2 + */ +public class ContextSourceAndHibernateTransactionManager extends HibernateTransactionManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ContextSourceTransactionManagerDelegate ldapManagerDelegate = new ContextSourceTransactionManagerDelegate(); + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#isExistingTransaction(java.lang.Object) + */ + protected boolean isExistingTransaction(Object transaction) { + ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) transaction; + + return super.isExistingTransaction(actualTransactionObject + .getHibernateTransactionObject()); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doGetTransaction() + */ + protected Object doGetTransaction() throws TransactionException { + Object dataSourceTransactionObject = super.doGetTransaction(); + Object contextSourceTransactionObject = ldapManagerDelegate + .doGetTransaction(); + + return new ContextSourceAndHibernateTransactionObject( + contextSourceTransactionObject, dataSourceTransactionObject); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doBegin(java.lang.Object, + * org.springframework.transaction.TransactionDefinition) + */ + protected void doBegin(Object transaction, TransactionDefinition definition) + throws TransactionException { + ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) transaction; + + super.doBegin(actualTransactionObject.getHibernateTransactionObject(), + definition); + ldapManagerDelegate.doBegin(actualTransactionObject + .getLdapTransactionObject(), definition); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doCleanupAfterCompletion(java.lang.Object) + */ + protected void doCleanupAfterCompletion(Object transaction) { + ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) transaction; + + super.doCleanupAfterCompletion(actualTransactionObject + .getHibernateTransactionObject()); + ldapManagerDelegate.doCleanupAfterCompletion(actualTransactionObject + .getLdapTransactionObject()); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doCommit(org.springframework.transaction.support.DefaultTransactionStatus) + */ + protected void doCommit(DefaultTransactionStatus status) + throws TransactionException { + + ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) status + .getTransaction(); + + try { + super.doCommit(new DefaultTransactionStatus(actualTransactionObject + .getHibernateTransactionObject(), status + .isNewTransaction(), status.isNewSynchronization(), status + .isReadOnly(), status.isDebug(), status + .getSuspendedResources())); + } catch (TransactionException ex) { + if (isRollbackOnCommitFailure()) { + logger.debug("Failed to commit db resource, rethrowing", ex); + // If we are to rollback on commit failure, just rethrow the + // exception - this will cause a rollback to be performed on + // both resources. + throw ex; + } else { + logger + .warn("Failed to commit and resource is rollbackOnCommit not set -" + + " proceeding to commit ldap resource."); + } + } + ldapManagerDelegate.doCommit(new DefaultTransactionStatus( + actualTransactionObject.getLdapTransactionObject(), status + .isNewTransaction(), status.isNewSynchronization(), + status.isReadOnly(), status.isDebug(), status + .getSuspendedResources())); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doRollback(org.springframework.transaction.support.DefaultTransactionStatus) + */ + protected void doRollback(DefaultTransactionStatus status) + throws TransactionException { + ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) status + .getTransaction(); + + super.doRollback(new DefaultTransactionStatus(actualTransactionObject + .getHibernateTransactionObject(), status.isNewTransaction(), + status.isNewSynchronization(), status.isReadOnly(), status + .isDebug(), status.getSuspendedResources())); + ldapManagerDelegate.doRollback(new DefaultTransactionStatus( + actualTransactionObject.getLdapTransactionObject(), status + .isNewTransaction(), status.isNewSynchronization(), + status.isReadOnly(), status.isDebug(), status + .getSuspendedResources())); + } + + public ContextSource getContextSource() { + return ldapManagerDelegate.getContextSource(); + } + + public void setContextSource(ContextSource contextSource) { + ldapManagerDelegate.setContextSource(contextSource); + } + + protected void setRenamingStrategy( + TempEntryRenamingStrategy renamingStrategy) { + ldapManagerDelegate.setRenamingStrategy(renamingStrategy); + } + + private class ContextSourceAndHibernateTransactionObject { + private Object ldapTransactionObject; + + private Object hibernateTransactionObject; + + public ContextSourceAndHibernateTransactionObject( + Object ldapTransactionObject, Object hibernateTransactionObject) { + this.ldapTransactionObject = ldapTransactionObject; + this.hibernateTransactionObject = hibernateTransactionObject; + } + + public Object getHibernateTransactionObject() { + return hibernateTransactionObject; + } + + public Object getLdapTransactionObject() { + return ldapTransactionObject; + } + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doSuspend(java.lang.Object) + */ + protected Object doSuspend(Object transaction) throws TransactionException { + throw new TransactionSuspensionNotSupportedException( + "Transaction manager [" + getClass().getName() + + "] does not support transaction suspension"); + } + + /* + * @see org.springframework.orm.hibernate3.HibernateTransactionManager#doResume(java.lang.Object, + * java.lang.Object) + */ + protected void doResume(Object transaction, Object suspendedResources) + throws TransactionException { + throw new TransactionSuspensionNotSupportedException( + "Transaction manager [" + getClass().getName() + + "] does not support transaction suspension"); + } + +} diff --git a/mvn-build/integration-tests/pom.xml b/mvn-build/integration-tests/pom.xml index 301f89cb..7e72cdef 100644 --- a/mvn-build/integration-tests/pom.xml +++ b/mvn-build/integration-tests/pom.xml @@ -53,6 +53,24 @@ ${spring.version} test
+ + org.springframework + spring-orm + ${spring.version} + test + + + org.hibernate + hibernate + 3.2.6.ga + test + + + org.springframework + spring-orm + ${spring.version} + provided + aspectj aspectjrt diff --git a/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/DummyDaoLdapAndHibernateImpl.java b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/DummyDaoLdapAndHibernateImpl.java new file mode 100755 index 00000000..173588d5 --- /dev/null +++ b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/DummyDaoLdapAndHibernateImpl.java @@ -0,0 +1,107 @@ +package org.springframework.ldap.transaction.compensating.manager.hibernate; + +import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.transaction.compensating.manager.DummyException; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; +/** + * @author Hans Westerbeek + */ +public class DummyDaoLdapAndHibernateImpl extends HibernateDaoSupport implements OrgPersonDao { + + private LdapTemplate ldapTemplate; + + public void create(OrgPerson person) { + DistinguishedName dn = new DistinguishedName(); + dn.add("c", person.getCountry()); + dn.add("ou", person.getCompany()); + dn.add("cn", person.getFullname()); + + DirContextAdapter ctx = new DirContextAdapter(); + ctx.setAttributeValues("objectclass", new String[] { "top", "person" }); + ctx.setAttributeValue("cn", person.getFullname()); + ctx.setAttributeValue("sn", person.getLastname()); + ctx.setAttributeValue("description", person.getDescription()); + ldapTemplate.bind(dn, ctx, null); + this.getHibernateTemplate().saveOrUpdate(person); + + + } + + public void createWithException(OrgPerson person) { + this.create(person); + throw new DummyException("This method failed"); + + } + + public void modifyAttributes(String dn, String lastName, String description) { + DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn); + ctx.setAttributeValue("sn", lastName); + ctx.setAttributeValue("description", description); + + ldapTemplate.modifyAttributes(dn, ctx.getModificationItems()); + } + + public void modifyAttributesWithException(String dn, String lastName, + String description) { + modifyAttributes(dn, lastName, description); + throw new DummyException("This method failed."); + } + + public void unbind(OrgPerson person) { + String dn = prepareDn(person); + ldapTemplate.unbind(dn); + this.getHibernateTemplate().delete(person); + + } + + public void unbindWithException(OrgPerson person) { + this.unbind(person); + throw new DummyException("This method failed"); + } + + public void update(OrgPerson person) { + String dn = prepareDn(person); + DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn); + ctx.setAttributeValue("sn", person.getLastname()); + ctx.setAttributeValue("description", person.getDescription()); + ctx.update(); + + ldapTemplate.rebind(dn, ctx, null); + this.getHibernateTemplate().saveOrUpdate(person); + + } + + public void updateWithException(OrgPerson person) { + this.update(person); + throw new DummyException("This method failed"); + } + + public void updateAndRename(String dn, String newDn, String updatedDescription) { + + DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn); + ctx.setAttributeValue("description", updatedDescription); + ctx.update(); + + ldapTemplate.rebind(dn, ctx, null); + ldapTemplate.rename(dn, newDn); + + } + + public void updateAndRenameWithException(String dn, String newDn, String updatedDescription) { + this.updateAndRename(dn, newDn, updatedDescription); + throw new DummyException("This method failed"); + } + + + + public void setLdapTemplate(LdapTemplate ldapTemplate) { + this.ldapTemplate = ldapTemplate; + } + + private String prepareDn(OrgPerson person){ + return "cn=" + person.getFullname() + ",ou=" + person.getCompany() + ",c=" + person.getCountry(); + } + +} diff --git a/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPerson.java b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPerson.java new file mode 100755 index 00000000..f9bfa9a6 --- /dev/null +++ b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPerson.java @@ -0,0 +1,123 @@ +package org.springframework.ldap.transaction.compensating.manager.hibernate; + +/** + * Pojo for use with the ContextSourceAndHibernateTransactionManager integration tests + * @author Hans Westerbeek + * + */ +public class OrgPerson{ + + private Integer id; + + private String fullname; + + private String lastname; + + private String company; + + private String country; + + private String description; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getFullname() { + return fullname; + } + + public void setFullname(String fullname) { + this.fullname = fullname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((company == null) ? 0 : company.hashCode()); + result = prime * result + ((country == null) ? 0 : country.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((fullname == null) ? 0 : fullname.hashCode()); + result = prime * result + ((lastname == null) ? 0 : lastname.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final OrgPerson other = (OrgPerson) obj; + if (company == null) { + if (other.company != null) + return false; + } + else if (!company.equals(other.company)) + return false; + if (country == null) { + if (other.country != null) + return false; + } + else if (!country.equals(other.country)) + return false; + if (description == null) { + if (other.description != null) + return false; + } + else if (!description.equals(other.description)) + return false; + if (fullname == null) { + if (other.fullname != null) + return false; + } + else if (!fullname.equals(other.fullname)) + return false; + if (lastname == null) { + if (other.lastname != null) + return false; + } + else if (!lastname.equals(other.lastname)) + return false; + return true; + } + +} diff --git a/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPersonDao.java b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPersonDao.java new file mode 100755 index 00000000..fdd4ee55 --- /dev/null +++ b/mvn-build/integration-tests/src/main/java/org/springframework/ldap/transaction/compensating/manager/hibernate/OrgPersonDao.java @@ -0,0 +1,23 @@ +package org.springframework.ldap.transaction.compensating.manager.hibernate; + +public interface OrgPersonDao { + void createWithException(OrgPerson person); + + void create(OrgPerson person); + + void update(OrgPerson person); + + void updateWithException(OrgPerson person); + + void updateAndRename(String dn, String newDn, String updatedDescription); + + void updateAndRenameWithException(String dn, String newDn, String updatedDescription); + + void modifyAttributes(String dn, String lastName, String description); + + void modifyAttributesWithException(String dn, String lastName, String description); + + void unbind(OrgPerson person); + + void unbindWithException(OrgPerson person); +} diff --git a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java index 1c4ffe4b..8f63d8b2 100644 --- a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java +++ b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateNoBaseSuffixITest.java @@ -23,6 +23,7 @@ import static junit.framework.Assert.fail; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler; import org.springframework.test.context.ContextConfiguration; @@ -41,6 +42,11 @@ public class LdapTemplateNoBaseSuffixITest extends AbstractLdapTemplateIntegrati @Autowired private LdapTemplate tested; + @Override + protected DistinguishedName getRoot() { + return new DistinguishedName("dc=jayway,dc=se"); + } + /** * This method depends on a DirObjectFactory ({@link org.springframework.ldap.core.support.DefaultDirObjectFactory}) * being set in the ContextSource. diff --git a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/control/SupportedControlsITest.java b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/control/SupportedControlsITest.java index 326e9469..6a87fcc2 100644 --- a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/control/SupportedControlsITest.java +++ b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/control/SupportedControlsITest.java @@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.AbstractLdapTemplateIntegrationTest; import org.springframework.ldap.core.ContextMapper; import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.test.context.ContextConfiguration; @@ -41,6 +42,11 @@ public class SupportedControlsITest extends AbstractLdapTemplateIntegrationTest private static final String SUPPORTED_CONTROL = "supportedcontrol"; + @Override + protected DistinguishedName getRoot() { + return new DistinguishedName("dc=jayway,dc=se"); + } + @Test public void testExpectedControlsSupported() throws Exception { /** diff --git a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndDataSourceTransactionManagerIntegrationTest.java b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndDataSourceTransactionManagerIntegrationTest.java index c13c5cb1..1385fd84 100644 --- a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndDataSourceTransactionManagerIntegrationTest.java +++ b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/ContextSourceAndDataSourceTransactionManagerIntegrationTest.java @@ -39,6 +39,7 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.ldap.AbstractLdapTemplateIntegrationTest; import org.springframework.ldap.NameNotFoundException; import org.springframework.ldap.core.AttributesMapper; +import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -69,6 +70,7 @@ public class ContextSourceAndDataSourceTransactionManagerIntegrationTest extends TransactionSynchronizationManager.clearSynchronization(); } + jdbcTemplate.execute("drop table PERSON if exists"); 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" }); @@ -76,7 +78,7 @@ public class ContextSourceAndDataSourceTransactionManagerIntegrationTest extends @After public void cleanup() throws Exception { - jdbcTemplate.execute("drop table PERSON"); + jdbcTemplate.execute("drop table PERSON if exists"); } @Test diff --git a/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/hibernate/ContextSourceAndHibernateTransactionManagerIntegrationTest.java b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/hibernate/ContextSourceAndHibernateTransactionManagerIntegrationTest.java new file mode 100755 index 00000000..75bcc019 --- /dev/null +++ b/mvn-build/integration-tests/src/test/java/org/springframework/ldap/transaction/compensating/manager/hibernate/ContextSourceAndHibernateTransactionManagerIntegrationTest.java @@ -0,0 +1,372 @@ +/* + * Copyright 2005-2007 the original author or authors. + * + * Licensed 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.springframework.ldap.transaction.compensating.manager.hibernate; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import java.util.List; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.ldap.AbstractLdapTemplateIntegrationTest; +import org.springframework.ldap.NameNotFoundException; +import org.springframework.ldap.core.AttributesMapper; +import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.transaction.compensating.manager.ContextSourceAndHibernateTransactionManager; +import org.springframework.ldap.transaction.compensating.manager.DummyException; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +/** + * Integration tests for {@link ContextSourceAndHibernateTransactionManager}. + * + * @author Hans Westerbeek + */ +@ContextConfiguration(locations = { "/conf/ldapAndHibernateTransactionTestContext.xml" }) +public class ContextSourceAndHibernateTransactionManagerIntegrationTest extends AbstractLdapTemplateIntegrationTest { + + private static Log log = LogFactory.getLog(ContextSourceAndHibernateTransactionManagerIntegrationTest.class); + + @Autowired + @Qualifier("dummyDao") + private OrgPersonDao dummyDao; + + @Autowired + private LdapTemplate ldapTemplate; + + @Autowired + private HibernateTemplate hibernateTemplate; + + @Autowired + private SessionFactory sessionFactory; + + @Before + public void prepareTest() throws Exception { + if (TransactionSynchronizationManager.isSynchronizationActive()) { + TransactionSynchronizationManager.clearSynchronization(); + } + + OrgPerson person = new OrgPerson(); + person.setId(new Integer(1)); + person.setLastname("Person"); + person.setFullname("Some Person"); + person.setDescription("Sweden, Company1, Some Person"); + person.setCountry("Sweden"); + person.setCompany("Company1"); + // "Some Person", "Person", "Sweden, Company1, Some Person" + // avoid the transaction manager we have configured, do it manually + Session session = this.sessionFactory.openSession(); + Transaction tx = session.beginTransaction(); + session.saveOrUpdate(person); + tx.commit(); + session.close(); + + } + + @After + public void cleanup() throws Exception { + // probably the wrong idea, this will use the thing i am trying to + // test.. + + Session session = this.sessionFactory.openSession(); + Transaction tx = session.beginTransaction(); + Query query = session.createQuery("delete from OrgPerson"); + query.executeUpdate(); + tx.commit(); + session.close(); + } + + @Test + public void testCreateWithException() { + OrgPerson person = new OrgPerson(); + + person.setId(new Integer(2)); + person.setDescription("some description"); + person.setFullname("Some testperson"); + person.setLastname("testperson"); + person.setCountry("Sweden"); + person.setCompany("company1"); + + try { + dummyDao.createWithException(person); + fail("DummyException expected"); + } + catch (DummyException expected) { + assertTrue(true); + } + + log.debug("Verifying result"); + + // Verify that no entry was created in ldap or hibernate db + try { + ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden"); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + List result = hibernateTemplate.findByNamedParam("from OrgPerson person where person.lastname = :lastname", + "lastname", person.getLastname()); + assertTrue(result.size() == 0); + + } + + @Test + public void testCreate() { + OrgPerson person = new OrgPerson(); + + person.setId(new Integer(2)); + person.setDescription("some description"); + person.setFullname("Some testperson"); + person.setLastname("testperson"); + person.setCountry("Sweden"); + person.setCompany("company1"); + // dummyDao.create("Sweden", "company1", "some testperson", + // "testperson", "some description"); + + this.dummyDao.create(person); + person = null; + log.debug("Verifying result"); + Object ldapResult = ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden"); + OrgPerson fromDb = (OrgPerson) this.hibernateTemplate.get(OrgPerson.class, new Integer(2)); + assertNotNull(ldapResult); + assertNotNull(fromDb); + } + + @Test + public void testUpdateWithException() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + OrgPerson originalPerson = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + originalPerson.setLastname("fooo"); + try { + dummyDao.updateWithException(originalPerson); + fail("DummyException expected"); + } + catch (DummyException expected) { + assertTrue(true); + } + + log.debug("Verifying result"); + + Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertNotNull("Person", attributes.get("sn").get()); + assertEquals("Sweden, Company1, Some Person", attributes.get("description").get()); + return new Object(); + } + }); + + OrgPerson notUpdatedPerson = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + assertEquals("Person", notUpdatedPerson.getLastname()); + assertEquals("Sweden, Company1, Some Person", notUpdatedPerson.getDescription()); + + assertNotNull(ldapResult); + // no need to assert if notUpdatedPerson exists + } + + @Test + public void testUpdate() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + OrgPerson person = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + person.setLastname("Updated Person"); + person.setDescription("Updated description"); + + dummyDao.update(person); + + log.debug("Verifying result"); + Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertEquals("Updated Person", attributes.get("sn").get()); + assertEquals("Updated description", attributes.get("description").get()); + return new Object(); + } + }); + + OrgPerson updatedPerson = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + assertEquals("Updated Person", updatedPerson.getLastname()); + assertEquals("Updated description", updatedPerson.getDescription()); + assertNotNull(ldapResult); + } + + @Test + public void testUpdateAndRenameWithException() { + String dn = "cn=Some Person2,ou=company1,c=Sweden"; + String newDn = "cn=Some Person2,ou=company2,c=Sweden"; + OrgPerson person = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + person.setLastname("Updated Person"); + person.setDescription("Updated description"); + + try { + // Perform test + dummyDao.updateAndRenameWithException(dn, newDn, "Updated description"); + fail("DummyException expected"); + } + catch (DummyException expected) { + assertTrue(true); + } + + // Verify that entry was not moved. + try { + ldapTemplate.lookup(newDn); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + // Verify that original entry was not updated. + Object object = ldapTemplate.lookup(dn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertEquals("Sweden, Company1, Some Person2", attributes.get("description").get()); + return new Object(); + } + }); + assertNotNull(object); + } + + @Test + public void testUpdateAndRename() { + String dn = "cn=Some Person2,ou=company1,c=Sweden"; + String newDn = "cn=Some Person2,ou=company2,c=Sweden"; + // Perform test + dummyDao.updateAndRename(dn, newDn, "Updated description"); + + // Verify that entry was moved and updated. + Object object = ldapTemplate.lookup(newDn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertEquals("Updated description", attributes.get("description").get()); + return new Object(); + } + }); + + assertNotNull(object); + } + + @Test + public void testModifyAttributesWithException() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + try { + // Perform test + dummyDao.modifyAttributesWithException(dn, "Updated lastname", "Updated description"); + 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() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertEquals("Person", attributes.get("sn").get()); + assertEquals("Sweden, Company1, Some Person", attributes.get("description").get()); + return new Object(); + } + }); + + assertNotNull(result); + } + + @Test + public void testModifyAttributes() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + // Perform test + dummyDao.modifyAttributes(dn, "Updated lastname", "Updated description"); + + // Verify result - check that the operation was not rolled back + Object result = ldapTemplate.lookup(dn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + assertEquals("Updated lastname", attributes.get("sn").get()); + assertEquals("Updated description", attributes.get("description").get()); + return new Object(); + } + }); + + assertNotNull(result); + } + + @Test + public void testUnbindWithException() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + OrgPerson person = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + + try { + // Perform test + dummyDao.unbindWithException(person); + fail("DummyException expected"); + } + catch (DummyException expected) { + assertTrue(true); + } + + person = null; + // Verify result - check that the operation was properly rolled back + Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() { + public Object mapFromAttributes(Attributes attributes) throws NamingException { + // Just verify that the entry still exists. + return new Object(); + } + }); + + person = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); // will + // throw + // exception + // of + // person + // does + // not + // exist + + assertNotNull(ldapResult); + } + + @Test + public void testUnbind() { + String dn = "cn=Some Person,ou=company1,c=Sweden"; + // Perform test + OrgPerson person = (OrgPerson) this.hibernateTemplate.load(OrgPerson.class, new Integer(1)); + dummyDao.unbind(person); + + try { + // Verify result - check that the operation was not rolled back + ldapTemplate.lookup(dn); + fail("NameNotFoundException expected"); + } + catch (NameNotFoundException expected) { + assertTrue(true); + } + + person = (OrgPerson) this.hibernateTemplate.get(OrgPerson.class, new Integer(1)); + assertNull(person); + } +} diff --git a/mvn-build/integration-tests/src/test/resources/conf/OrgPerson.hbm.xml b/mvn-build/integration-tests/src/test/resources/conf/OrgPerson.hbm.xml new file mode 100755 index 00000000..6d619329 --- /dev/null +++ b/mvn-build/integration-tests/src/test/resources/conf/OrgPerson.hbm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mvn-build/integration-tests/src/test/resources/conf/ldapAndHibernateTransactionTestContext.xml b/mvn-build/integration-tests/src/test/resources/conf/ldapAndHibernateTransactionTestContext.xml new file mode 100755 index 00000000..a2d03bb4 --- /dev/null +++ b/mvn-build/integration-tests/src/test/resources/conf/ldapAndHibernateTransactionTestContext.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + conf/OrgPerson.hbm.xml + + + + + hibernate.dialect=org.hibernate.dialect.HSQLDialect + hibernate.hbm2ddl.auto=create + + + + + + + + + + + + + + + + + + + + PROPAGATION_REQUIRES_NEW + + + +