diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java index 7da43afab34f0a334cd2000f5b1d39954bc67932..f6708fee6aa58e5a06d05587e0a251ae957ee9b0 100644 --- a/src/main/java/org/olat/basesecurity/AuthHelper.java +++ b/src/main/java/org/olat/basesecurity/AuthHelper.java @@ -253,7 +253,7 @@ public class AuthHelper { } else { //fxdiff FXOLAT-151: add eventually the identity to the security group if(!groupDao.hasRole(invitation.getBaseGroup(), identity, GroupRoles.invitee.name())) { - groupDao.addMembership(invitation.getBaseGroup(), identity, GroupRoles.invitee.name()); + groupDao.addMembershipTwoWay(invitation.getBaseGroup(), identity, GroupRoles.invitee.name()); DBFactory.getInstance().commit(); } diff --git a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java index 1b9c05e1026c4707c2c02248ba2cb115b4696bd6..a0c8a5624fdcee58cb6169a00b5b8e53252889bf 100644 --- a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java +++ b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java @@ -80,7 +80,11 @@ public class GroupDAO { return group; } - public GroupMembership addMembership(Group group, Identity identity, String role) { + /** + * Add a membership to the group, in the set of the group too which can be + * reloaded. + */ + public GroupMembership addMembershipTwoWay(Group group, Identity identity, String role) { GroupMembershipImpl membership = new GroupMembershipImpl(); membership.setCreationDate(new Date()); membership.setLastModified(new Date()); @@ -98,6 +102,19 @@ public class GroupDAO { return membership; } + /** + * Create a membership without updating the set in the group. + */ + public void addMembershipOneWay(Group group, Identity identity, String role) { + GroupMembershipImpl membership = new GroupMembershipImpl(); + membership.setCreationDate(new Date()); + membership.setLastModified(new Date()); + membership.setGroup(group); + membership.setIdentity(identity); + membership.setRole(role); + dbInstance.getCurrentEntityManager().persist(membership); + } + public int removeMemberships(Group group) { EntityManager em = dbInstance.getCurrentEntityManager(); List<GroupMembership> memberships = em.createNamedQuery("membershipsByGroup", GroupMembership.class) diff --git a/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java b/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java index 885616b5ab6bd0e990afbe5e618fe24b7a77c175..c9a0de90f03127399f296584cd542a9e0bce68f3 100644 --- a/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java +++ b/src/main/java/org/olat/basesecurity/model/GroupMembershipImpl.java @@ -59,6 +59,7 @@ import org.olat.core.id.Persistable; @NamedQuery(name="membershipsByGroupAndIdentity", query="select membership from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey"), @NamedQuery(name="membershipsByGroupIdentityAndRole", query="select membership from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey and membership.role=:role"), @NamedQuery(name="countMembersByGroup", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey"), + @NamedQuery(name="countMembersByGroupAndRole", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey and membership.role=:role"), @NamedQuery(name="membersByGroupAndRole", query="select distinct membership.identity from bgroupmember as membership where membership.group.key=:groupKey and membership.role=:role"), @NamedQuery(name="hasRoleByGroupIdentityAndRole", query="select count(membership.key) from bgroupmember as membership where membership.group.key=:groupKey and membership.identity.key=:identityKey and membership.role=:role") }) diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java index ad1ba63e55014a6554b6b821fdde907ef7e77c8c..47134e92332a49dfb844197e0968e1c5eff1b4a5 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java @@ -141,7 +141,7 @@ public class BusinessGroupDAO { Group group = groupDao.createGroup(); businessgroup.setBaseGroup(group); if (creator != null) { - groupDao.addMembership(group, creator, GroupRoles.coach.name()); + groupDao.addMembershipTwoWay(group, creator, GroupRoles.coach.name()); } EntityManager em = dbInstance.getCurrentEntityManager(); diff --git a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java index 5ca80d6859dedc04d5767ad2962da7150ce2eaf6..0693b16d4a5a0707b9933a448e6be64eb144d0d0 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java @@ -39,6 +39,8 @@ import org.olat.basesecurity.model.IdentityRefImpl; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.course.assessment.manager.AssessmentModeDAO; import org.olat.group.BusinessGroup; @@ -61,6 +63,8 @@ import org.springframework.stereotype.Service; */ @Service("businessGroupRelationDao") public class BusinessGroupRelationDAO { + + private static final OLog log = Tracing.createLoggerFor(BusinessGroupRelationDAO.class); @Autowired private DB dbInstance; @@ -75,9 +79,18 @@ public class BusinessGroupRelationDAO { repositoryEntryRelationDao.createRelation(((BusinessGroupImpl)group).getBaseGroup(), re); } - public void addRole(Identity identity, BusinessGroupRef businessGroup, String role) { - Group group = getGroup(businessGroup); - groupDao.addMembership(group, identity, role); + public void addRole(Identity identity, BusinessGroup businessGroup, String role) { + Group group = null; + try { + group = businessGroup.getBaseGroup(); + if(group == null) { + group = getGroup(businessGroup); + } + } catch(Exception e) { + log.warn("", e); + group = getGroup(businessGroup); + } + groupDao.addMembershipOneWay(group, identity, role); } public boolean removeRole(Identity identity, BusinessGroupRef businessGroup, String role) { @@ -195,6 +208,21 @@ public class BusinessGroupRelationDAO { return count == null ? 0 : count.intValue(); } + /** + * Count the number of participants. + * + * @param group + * @return + */ + public int countEnrollment(BusinessGroup group) { + Number count = dbInstance.getCurrentEntityManager() + .createNamedQuery("countMembersByGroupAndRole", Number.class) + .setParameter("groupKey", group.getBaseGroup().getKey()) + .setParameter("role", GroupRoles.participant.name()) + .getSingleResult(); + return count == null ? 0 : count.intValue(); + } + /** * Return the number of coaches with author rights. * @param group diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java index 5cef78b7fa898f45193f066841ff8a2a3ced3281..fd798171b2e4243aaabb09df9c681751ddba67c0 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java @@ -1385,11 +1385,11 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD reservationDao.deleteReservation(reservation); } } else if (reloadedGroup.getMaxParticipants() != null) { - int participantsCounter = businessGroupRelationDAO.countRoles(reloadedGroup, GroupRoles.participant.name()); + int participantsCounter = businessGroupRelationDAO.countEnrollment(reloadedGroup); int reservations = reservationDao.countReservations(reloadedGroup.getResource()); log.info("doEnroll - participantsCounter: " + participantsCounter + ", reservations: " + reservations + " maxParticipants: " + reloadedGroup.getMaxParticipants().intValue(), identity.getName()); - if (reservation == null && (participantsCounter + reservations) >= reloadedGroup.getMaxParticipants().intValue()) { + if ((participantsCounter + reservations) >= reloadedGroup.getMaxParticipants().intValue()) { // already full, show error and updated choose page again if (reloadedGroup.getWaitingListEnabled().booleanValue()) { addToWaitingList(ureqIdentity, identity, reloadedGroup, mailing, events); diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java index e39ce15e4e95ac1a45bb109f54f86d1e243052ff..4324f1ba8f8f957acc28d56dc5cd1804a5cbfb73 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java @@ -173,7 +173,7 @@ public class PortfolioServiceImpl implements PortfolioService { public Binder createNewBinder(String title, String summary, String imagePath, Identity owner) { BinderImpl portfolio = binderDao.createAndPersist(title, summary, imagePath, null); if(owner != null) { - groupDao.addMembership(portfolio.getBaseGroup(), owner, PortfolioRoles.owner.name()); + groupDao.addMembershipTwoWay(portfolio.getBaseGroup(), owner, PortfolioRoles.owner.name()); } return portfolio; } @@ -188,7 +188,7 @@ public class PortfolioServiceImpl implements PortfolioService { public void createAndPersistBinderTemplate(Identity owner, RepositoryEntry entry, Locale locale) { BinderImpl binder = binderDao.createAndPersist(entry.getDisplayname(), entry.getDescription(), null, entry); if(owner != null) { - groupDao.addMembership(binder.getBaseGroup(), owner, PortfolioRoles.owner.name()); + groupDao.addMembershipTwoWay(binder.getBaseGroup(), owner, PortfolioRoles.owner.name()); } //add section Translator pt = Util.createPackageTranslator(PortfolioHomeController.class, locale); @@ -564,7 +564,7 @@ public class PortfolioServiceImpl implements PortfolioService { public Binder assignBinder(Identity owner, BinderRef templateBinder, RepositoryEntry entry, String subIdent, Date deadline) { BinderImpl reloadedTemplate = (BinderImpl)binderDao.loadByKey(templateBinder.getKey()); BinderImpl binder = binderDao.createCopy(reloadedTemplate, entry, subIdent); - groupDao.addMembership(binder.getBaseGroup(), owner, PortfolioRoles.owner.name()); + groupDao.addMembershipTwoWay(binder.getBaseGroup(), owner, PortfolioRoles.owner.name()); return binder; } @@ -635,7 +635,7 @@ public class PortfolioServiceImpl implements PortfolioService { public void addAccessRights(PortfolioElement element, Identity identity, PortfolioRoles role) { Group baseGroup = element.getBaseGroup(); if(!groupDao.hasRole(baseGroup, identity, role.name())) { - groupDao.addMembership(baseGroup, identity, role.name()); + groupDao.addMembershipTwoWay(baseGroup, identity, role.name()); } } @@ -647,7 +647,7 @@ public class PortfolioServiceImpl implements PortfolioService { if(change.isAdd()) { if(!groupDao.hasRole(baseGroup, identity, change.getRole().name())) { Group group = getGroup(change.getElement()); - groupDao.addMembership(group, identity, change.getRole().name()); + groupDao.addMembershipOneWay(group, identity, change.getRole().name()); } } else { if(groupDao.hasRole(baseGroup, identity, change.getRole().name())) { @@ -839,7 +839,7 @@ public class PortfolioServiceImpl implements PortfolioService { ((SectionImpl)reloadedSection).setSectionStatus(SectionStatus.inProgress); } Page page = pageDao.createAndPersist(title, summary, imagePath, align, editable, reloadedSection, null); - groupDao.addMembership(page.getBaseGroup(), owner, PortfolioRoles.owner.name()); + groupDao.addMembershipTwoWay(page.getBaseGroup(), owner, PortfolioRoles.owner.name()); return page; } diff --git a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java index 61d160033d3df55ae53d835dc7805a7ec45fa09a..dd332c2435104114039a434737a0d328ecb5e583 100644 --- a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java @@ -225,7 +225,7 @@ public class EPPolicyManager { Group secGroup = groupDao.createGroup(); relation = createBaseRelation(map, secGroup, EPMapPolicy.Type.user.name(), policy.getFrom(), policy.getTo()); for(Identity identity:policy.getIdentities()) { - groupDao.addMembership(secGroup, identity, GroupRoles.participant.name()); + groupDao.addMembershipTwoWay(secGroup, identity, GroupRoles.participant.name()); } } else { EPStructureElementToGroupRelation currentPolicy = reusePolicyInSession(relation, map); @@ -248,7 +248,7 @@ public class EPPolicyManager { groupDao.removeMembership(secGroup, currentMember); } for(Identity newMember:newMembers) { - groupDao.addMembership(secGroup, newMember, GroupRoles.participant.name()); + groupDao.addMembershipTwoWay(secGroup, newMember, GroupRoles.participant.name()); } } return relation; diff --git a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java index c3102bf0e1b4e4c590ed70da457ce7520e087438..6c8067aed974e808bcc7c834e8655e6eca0f1987 100755 --- a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java @@ -1829,7 +1829,7 @@ public class EPStructureManager { Group group = repositoryEntyRelationDao.getDefaultGroup(entry); if(group == null) { group = groupDao.createGroup(); - groupDao.addMembership(group, identity, GroupRoles.owner.name()); + groupDao.addMembershipTwoWay(group, identity, GroupRoles.owner.name()); } EPStructureElementToGroupRelation relation = createBaseRelation(el, group); @@ -1885,7 +1885,7 @@ public class EPStructureManager { relation.setCreationDate(new Date()); relation.setGroup(ownerGroup); relation.setStructureElement(element); - groupDao.addMembership(ownerGroup, author, GroupRoles.owner.name()); + groupDao.addMembershipTwoWay(ownerGroup, author, GroupRoles.owner.name()); return relation; } diff --git a/src/main/java/org/olat/portfolio/manager/InvitationDAO.java b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java index c104acd26e25d091547806bdbc7e7ad23b90f794..b279768530d411721342b9f19e5fe71e6a9b0640 100644 --- a/src/main/java/org/olat/portfolio/manager/InvitationDAO.java +++ b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java @@ -110,7 +110,7 @@ public class InvitationDAO { User user = userManager.createUser(invitation.getFirstName(), invitation.getLastName(), invitation.getMail()); user.getPreferences().setLanguage(locale.toString()); Identity invitee = securityManager.createAndPersistIdentityAndUser(tempUsername, null, user, null, null); - groupDao.addMembership(invitation.getBaseGroup(), invitee, GroupRoles.invitee.name()); + groupDao.addMembershipTwoWay(invitation.getBaseGroup(), invitee, GroupRoles.invitee.name()); return invitee; } @@ -129,7 +129,7 @@ public class InvitationDAO { invitee = securityManager.createAndPersistIdentityAndUser(tempUsername, null, user, null, null, null); } // add invitee to the security group of that portfolio element - groupDao.addMembership(group, invitee, GroupRoles.invitee.name()); + groupDao.addMembershipTwoWay(group, invitee, GroupRoles.invitee.name()); return invitee; } diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java index 85e1eccab580d6e7697f1759cf4f600aa845d441..459a6519ba81662e0c57fa59f0c0b6d57ab7c793 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java @@ -168,7 +168,7 @@ public class RepositoryEntryRelationDAO { public void addRole(Identity identity, RepositoryEntryRef re, String role) { Group group = getDefaultGroup(re); - groupDao.addMembership(group, identity, role); + groupDao.addMembershipOneWay(group, identity, role); } public int removeRole(IdentityRef identity, RepositoryEntryRef re, String role) { diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java index 90f6e7600bf0a4483ae44ed859258d586e7a2a82..bfc6933b253efa78f889a1ea850f05fcb8c6276f 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java +++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java @@ -215,7 +215,7 @@ public class RepositoryServiceImpl implements RepositoryService { re.setGroups(rels); if(initialAuthor != null) { - groupDao.addMembership(group, initialAuthor, GroupRoles.owner.name()); + groupDao.addMembershipTwoWay(group, initialAuthor, GroupRoles.owner.name()); } dbInstance.getCurrentEntityManager().persist(re); diff --git a/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java b/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java index 7da1b5fa3b1506d5251577bce0534f35d528f050..5febf6910c3cff3ccf1f5c66fa1100ed458d3bc8 100644 --- a/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java +++ b/src/test/java/org/olat/basesecurity/manager/GroupDAOTest.java @@ -61,18 +61,26 @@ public class GroupDAOTest extends OlatTestCase { public void createGroupMembership() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); Group group = groupDao.createGroup(); - GroupMembership membership = groupDao.addMembership(group, id, "author"); + GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author"); dbInstance.commit(); Assert.assertNotNull(membership); } + @Test + public void createGroupMembership_oneWay() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); + Group group = groupDao.createGroup(); + groupDao.addMembershipOneWay(group, id, "author"); + dbInstance.commit(); + } + @Test public void createGroupMembership_v2() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); Group group = groupDao.createGroup(); - GroupMembership membership = groupDao.addMembership(group, id, "author"); + GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author"); dbInstance.commit(); Assert.assertNotNull(membership); @@ -86,11 +94,25 @@ public class GroupDAOTest extends OlatTestCase { Assert.assertEquals(1, members.size()); } + @Test + public void createGroupMembership_oneWay_v2() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); + Group group = groupDao.createGroup(); + groupDao.addMembershipOneWay(group, id, "author"); + dbInstance.commitAndCloseSession(); + + GroupImpl loadedGroup = (GroupImpl)groupDao.loadGroup(group.getKey()); + Assert.assertNotNull(loadedGroup); + Set<GroupMembership> members = loadedGroup.getMembers(); + Assert.assertNotNull(members); + Assert.assertEquals(1, members.size()); + } + @Test public void getMemberships() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); Group group = groupDao.createGroup(); - GroupMembership membership = groupDao.addMembership(group, id, "author"); + GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author"); dbInstance.commit(); Assert.assertNotNull(membership); @@ -101,13 +123,25 @@ public class GroupDAOTest extends OlatTestCase { Assert.assertNotNull(members); Assert.assertEquals(1, members.size()); } + + @Test + public void getMemberships_oneWay() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-1-"); + Group group = groupDao.createGroup(); + groupDao.addMembershipOneWay(group, id, "author"); + dbInstance.commitAndCloseSession(); + + List<GroupMembership> members = groupDao.getMemberships(group, "author"); + Assert.assertNotNull(members); + Assert.assertEquals(1, members.size()); + } @Test public void hasRole() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-2-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-2b-"); Group group = groupDao.createGroup(); - GroupMembership membership = groupDao.addMembership(group, id, "author"); + GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author"); dbInstance.commit(); Assert.assertNotNull(membership); @@ -126,7 +160,7 @@ public class GroupDAOTest extends OlatTestCase { public void getMembers() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-3-"); Group group = groupDao.createGroup(); - GroupMembership membership = groupDao.addMembership(group, id, "author"); + GroupMembership membership = groupDao.addMembershipTwoWay(group, id, "author"); dbInstance.commit(); Assert.assertNotNull(membership); @@ -143,9 +177,9 @@ public class GroupDAOTest extends OlatTestCase { Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-5-"); Identity id3 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-6-"); Group group = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot"); - GroupMembership membership3 = groupDao.addMembership(group, id3, "copilot"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot"); + GroupMembership membership3 = groupDao.addMembershipTwoWay(group, id3, "copilot"); dbInstance.commit(); Assert.assertNotNull(membership1); @@ -162,8 +196,8 @@ public class GroupDAOTest extends OlatTestCase { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-"); Group group = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot"); Assert.assertNotNull(membership1); Assert.assertNotNull(membership2); dbInstance.commitAndCloseSession(); @@ -189,9 +223,9 @@ public class GroupDAOTest extends OlatTestCase { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-"); Group group = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot"); - GroupMembership membership2alt = groupDao.addMembership(group, id2, "commander"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot"); + GroupMembership membership2alt = groupDao.addMembershipTwoWay(group, id2, "commander"); Assert.assertNotNull(membership1); Assert.assertNotNull(membership2); Assert.assertNotNull(membership2alt); @@ -226,8 +260,8 @@ public class GroupDAOTest extends OlatTestCase { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-7-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-8-"); Group group = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group, id2, "pilot"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "pilot"); Assert.assertNotNull(membership1); Assert.assertNotNull(membership2); dbInstance.commitAndCloseSession(); @@ -250,8 +284,8 @@ public class GroupDAOTest extends OlatTestCase { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-12-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-13-"); Group group = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group, id2, "copilot"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group, id2, "copilot"); Assert.assertNotNull(membership1); Assert.assertNotNull(membership2); dbInstance.commitAndCloseSession(); @@ -278,14 +312,14 @@ public class GroupDAOTest extends OlatTestCase { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-9-"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("bgrp-10-"); Group group1 = groupDao.createGroup(); - GroupMembership membership1 = groupDao.addMembership(group1, id1, "pilot"); - GroupMembership membership2 = groupDao.addMembership(group1, id2, "pilot"); + GroupMembership membership1 = groupDao.addMembershipTwoWay(group1, id1, "pilot"); + GroupMembership membership2 = groupDao.addMembershipTwoWay(group1, id2, "pilot"); Assert.assertNotNull(membership1); Assert.assertNotNull(membership2); dbInstance.commitAndCloseSession(); Group group2 = groupDao.createGroup(); - GroupMembership membership3 = groupDao.addMembership(group2, id1, "passanger"); - GroupMembership membership4 = groupDao.addMembership(group2, id2, "passanger"); + GroupMembership membership3 = groupDao.addMembershipTwoWay(group2, id1, "passanger"); + GroupMembership membership4 = groupDao.addMembershipTwoWay(group2, id2, "passanger"); Assert.assertNotNull(membership3); Assert.assertNotNull(membership4); dbInstance.commitAndCloseSession(); @@ -359,7 +393,7 @@ public class GroupDAOTest extends OlatTestCase { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-"); Group group = groupDao.createGroup(); String role = "hasGrant-role"; - groupDao.addMembership(group, id, role); + groupDao.addMembershipTwoWay(group, id, role); OLATResource resource = JunitTestHelper.createRandomResource(); groupDao.addGrant(group, role, "hasGrant-perm", resource); dbInstance.commitAndCloseSession(); @@ -373,7 +407,7 @@ public class GroupDAOTest extends OlatTestCase { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-"); Group group = groupDao.createGroup(); String role = "getPermissions-role"; - groupDao.addMembership(group, id, role); + groupDao.addMembershipTwoWay(group, id, role); OLATResource resource = JunitTestHelper.createRandomResource(); groupDao.addGrant(group, role, "getPermissions-perm", resource); dbInstance.commitAndCloseSession(); @@ -389,9 +423,9 @@ public class GroupDAOTest extends OlatTestCase { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("grant-1-"); Group group = groupDao.createGroup(); String role1 = "getPermissions-role-1"; - groupDao.addMembership(group, id, role1); + groupDao.addMembershipTwoWay(group, id, role1); String role2 = "getPermissions-role-2"; - groupDao.addMembership(group, id, role2); + groupDao.addMembershipTwoWay(group, id, role2); OLATResource resource = JunitTestHelper.createRandomResource(); groupDao.addGrant(group, role1, "getPermissions-perm-1", resource); groupDao.addGrant(group, role2, "getPermissions-perm-2", resource); @@ -408,8 +442,8 @@ public class GroupDAOTest extends OlatTestCase { public void addRemoveGrant() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("addremove-1-"); Group group = groupDao.createGroup(); - groupDao.addMembership(group, id, "addremove-1"); - groupDao.addMembership(group, id, "addremove-2"); + groupDao.addMembershipTwoWay(group, id, "addremove-1"); + groupDao.addMembershipTwoWay(group, id, "addremove-2"); OLATResource resource = JunitTestHelper.createRandomResource(); groupDao.addGrant(group, "addremove-1", "addremove-1-perm", resource); groupDao.addGrant(group, "addremove-2", "addremove-2-perm", resource); @@ -436,8 +470,8 @@ public class GroupDAOTest extends OlatTestCase { public void addRemoveGrants() { Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("addremove-1-"); Group group = groupDao.createGroup(); - groupDao.addMembership(group, id, "addremove-1"); - groupDao.addMembership(group, id, "addremove-2"); + groupDao.addMembershipTwoWay(group, id, "addremove-1"); + groupDao.addMembershipTwoWay(group, id, "addremove-2"); OLATResource resource = JunitTestHelper.createRandomResource(); groupDao.addGrant(group, "addremove-1", "addremove-1-perm", resource); groupDao.addGrant(group, "addremove-1", "addremove-11-perm", resource); diff --git a/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java b/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java index 0bc285744fa416f59ae1febdad118144687059ae..9e46d1b9a0a3eb4178c9a427a867ae757c91500d 100644 --- a/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java +++ b/src/test/java/org/olat/course/nodes/en/EnrollmentManagerConcurrentTest.java @@ -33,12 +33,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Random; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.GroupRoles; @@ -58,6 +60,11 @@ import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.ContextEntry; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.logging.activity.OlatResourceableType; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller; +import org.olat.core.util.SessionInfo; +import org.olat.core.util.UserSession; import org.olat.core.util.Util; import org.olat.course.CourseFactory; import org.olat.course.CourseModule; @@ -75,6 +82,7 @@ import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; +import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; /** @@ -249,23 +257,30 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win @Test public void testConcurrentEnrollmentWithWaitingList() { - List<Identity> ids = new ArrayList<Identity>(30); - for(int i=0; i<30; i++) { + int NUM_OF_USERS = 30; + List<Identity> ids = new ArrayList<Identity>(NUM_OF_USERS); + for(int i=0; i<NUM_OF_USERS; i++) { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("enroll-a-" + i + "-" + UUID.randomUUID().toString()); ids.add(id); } ENCourseNode enNode = new ENCourseNode(); - OLATResource resource = resourceManager.createOLATResourceInstance(CourseModule.class); - RepositoryEntry addedEntry = repositoryService.create("Ayanami", "-", "Enrollment test course 2", "A JUnit course", resource); + + Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("enroller"); + RepositoryEntry addedEntry = JunitTestHelper.deployBasicCourse(author); CourseEnvironment cenv = CourseFactory.createCourse(addedEntry, "Test-Enroll", "Test", "Test enrollment with concurrent users").getCourseEnvironment(); BusinessGroup group = businessGroupService.createBusinessGroup(id1, "Enrollment", "Enroll", new Integer(1), new Integer(10), true, false, null); Assert.assertNotNull(group); dbInstance.commitAndCloseSession(); final CountDownLatch doneSignal = new CountDownLatch(ids.size()); + EnrollThread[] threads = new EnrollThread[NUM_OF_USERS]; + int t = 0; for(Identity id:ids) { - EnrollThread thread = new EnrollThread(id, group, enNode, cenv, doneSignal); + threads[t++] = new EnrollThread(id, addedEntry, group, enNode, cenv, doneSignal); + } + + for(EnrollThread thread:threads) { thread.start(); } @@ -275,6 +290,8 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win } catch (InterruptedException e) { fail("" + e.getMessage()); } + + dbInstance.commitAndCloseSession(); List<Identity> enrolledIds = businessGroupService.getMembers(group, GroupRoles.participant.name()); Assert.assertNotNull(enrolledIds); @@ -284,17 +301,91 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win Assert.assertNotNull(waitingIds); Assert.assertEquals(ids.size() - 10, waitingIds.size()); } + + + @Test @Ignore + public void testConcurrentEnrollmentWithWaitingList_big() { + List<Identity> ids = new ArrayList<Identity>(100); + for(int i=0; i<100; i++) { + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("enroll-a-" + i + "-" + UUID.randomUUID().toString()); + ids.add(id); + } + + Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("enroller"); + RepositoryEntry addedEntry = JunitTestHelper.deployBasicCourse(author); + + ENCourseNode enNode1 = new ENCourseNode(); + ENCourseNode enNode2 = new ENCourseNode(); + ENCourseNode enNode3 = new ENCourseNode(); + ENCourseNode enNode4 = new ENCourseNode(); + ENCourseNode enNode5 = new ENCourseNode(); + + CourseEnvironment cenv = CourseFactory.loadCourse(addedEntry).getCourseEnvironment(); + BusinessGroup group1 = businessGroupService.createBusinessGroup(author, "Enrollment 1", "Enroll 1", new Integer(1), new Integer(8), true, true, addedEntry); + BusinessGroup group2 = businessGroupService.createBusinessGroup(author, "Enrollment 2", "Enroll 2", new Integer(1), new Integer(10), true, true, addedEntry); + BusinessGroup group3 = businessGroupService.createBusinessGroup(author, "Enrollment 3", "Enroll 3", new Integer(1), new Integer(4), true, true, addedEntry); + BusinessGroup group4 = businessGroupService.createBusinessGroup(author, "Enrollment 4", "Enroll 4", new Integer(1), new Integer(10), true, true, addedEntry); + BusinessGroup group5 = businessGroupService.createBusinessGroup(author, "Enrollment 5", "Enroll 5", new Integer(1), new Integer(9), true, true, addedEntry); + dbInstance.commitAndCloseSession(); + + EnrollThread[] threads = new EnrollThread[100]; + + final CountDownLatch doneSignal = new CountDownLatch(ids.size()); + int t = 0; + for(int i=0; i<30; i++) { + threads[t++] = new EnrollThread(ids.get(i), addedEntry, group1, enNode1, cenv, doneSignal); + } + for(int i=30; i<50; i++) { + threads[t++] = new EnrollThread(ids.get(i), addedEntry, group2, enNode2, cenv, doneSignal); + } + for(int i=50; i<70; i++) { + threads[t++] = new EnrollThread(ids.get(i), addedEntry, group3, enNode3, cenv, doneSignal); + } + for(int i=70; i<90; i++) { + threads[t++] = new EnrollThread(ids.get(i), addedEntry, group4, enNode4, cenv, doneSignal); + } + for(int i=90; i<100; i++) { + threads[t++] = new EnrollThread(ids.get(i), addedEntry, group5, enNode5, cenv, doneSignal); + } + + for(EnrollThread thread:threads) { + thread.start(); + } + + try { + boolean interrupt = doneSignal.await(360, TimeUnit.SECONDS); + assertTrue("Test takes too long (more than 10s)", interrupt); + } catch (InterruptedException e) { + fail("" + e.getMessage()); + } + + dbInstance.commitAndCloseSession(); + + List<Identity> enrolled_1_Ids = businessGroupService.getMembers(group1, GroupRoles.participant.name()); + Assert.assertEquals(8, enrolled_1_Ids.size()); + List<Identity> enrolled_2_Ids = businessGroupService.getMembers(group2, GroupRoles.participant.name()); + Assert.assertEquals(10, enrolled_2_Ids.size()); + List<Identity> enrolled_3_Ids = businessGroupService.getMembers(group3, GroupRoles.participant.name()); + Assert.assertEquals(4, enrolled_3_Ids.size()); + List<Identity> enrolled_4_Ids = businessGroupService.getMembers(group4, GroupRoles.participant.name()); + Assert.assertEquals(10, enrolled_4_Ids.size()); + List<Identity> enrolled_5_Ids = businessGroupService.getMembers(group5, GroupRoles.participant.name()); + Assert.assertEquals(9, enrolled_5_Ids.size()); + } private class EnrollThread extends Thread { private final ENCourseNode enNode; private final Identity identity; private final CourseEnvironment cenv; private final BusinessGroup group; + private final RepositoryEntry courseEntry; private final CountDownLatch doneSignal; - public EnrollThread(Identity identity, BusinessGroup group, ENCourseNode enNode, CourseEnvironment cenv, CountDownLatch doneSignal) { + public EnrollThread(Identity identity, RepositoryEntry courseEntry, BusinessGroup group, + ENCourseNode enNode, CourseEnvironment cenv, CountDownLatch doneSignal) { this.enNode = enNode; this.group = group; + this.courseEntry = courseEntry; this.identity = identity; this.cenv = cenv; this.doneSignal = doneSignal; @@ -303,19 +394,30 @@ public class EnrollmentManagerConcurrentTest extends OlatTestCase implements Win @Override public void run() { try { - sleep(10); + UserSession session = new UserSession(); + session.setIdentity(identity); + session.setSessionInfo(new SessionInfo(identity.getKey(), identity.getName())); + ThreadLocalUserActivityLoggerInstaller.initUserActivityLogger(session); + IdentityEnvironment ienv = new IdentityEnvironment(); ienv.setIdentity(identity); UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, cenv); CoursePropertyManager coursePropertyManager = userCourseEnv.getCourseEnvironment().getCoursePropertyManager(); CourseGroupManager courseGroupManager = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); + ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(courseEntry.getOlatResource(), OlatResourceableType.course)); + ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(enNode)); + ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(group)); + + sleep(Math.round(new Random().nextDouble() * 100l)); enrollmentManager.doEnroll(identity, JunitTestHelper.getUserRoles(), group, enNode, coursePropertyManager, EnrollmentManagerConcurrentTest.this /*WindowControl mock*/, testTranslator, new ArrayList<Long>()/*enrollableGroupNames*/, new ArrayList<Long>()/*enrollableAreaNames*/, courseGroupManager); - DBFactory.getInstance().commitAndCloseSession(); + DBFactory.getInstance().commit(); } catch (Exception e) { log.error("", e); } finally { + ThreadLocalUserActivityLoggerInstaller.resetUserActivityLogger(); + DBFactory.getInstance().commitAndCloseSession(); doneSignal.countDown(); } } diff --git a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java index 879d8c41cdf5ad7a174dd39f38d68d653b16d1e5..5a695ccd9bb4db274e2a51af87ec9cdc54ff4c37 100644 --- a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java +++ b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java @@ -93,7 +93,7 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase { dbInstance.commitAndCloseSession(); Group group = ((BusinessGroupImpl)businessGroup).getBaseGroup(); - groupDao.addMembership(group, coach, "coach"); + groupDao.addMembershipTwoWay(group, coach, "coach"); dbInstance.commitAndCloseSession(); List<String> roles = businessGroupRelationDao.getRoles(coach, businessGroup); @@ -582,6 +582,36 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase { Assert.assertEquals(1, numOfAuthors); } + @Test + public void countRoles() { + Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-" + UUID.randomUUID().toString()); + Identity test = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth"); + BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false); + businessGroupRelationDao.addRole(author, group, GroupRoles.coach.name()); + businessGroupRelationDao.addRole(test, group, GroupRoles.coach.name()); + dbInstance.commitAndCloseSession(); + + int numOfCoachs = businessGroupRelationDao.countRoles(group, GroupRoles.coach.name()); + Assert.assertEquals(2, numOfCoachs); + int numOfParticipants = businessGroupRelationDao.countRoles(group, GroupRoles.participant.name()); + Assert.assertEquals(0, numOfParticipants); + } + + @Test + public void countEnrollment() { + Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("auth-" + UUID.randomUUID().toString()); + Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth"); + Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("not-auth"); + BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false); + businessGroupRelationDao.addRole(author, group, GroupRoles.coach.name()); + businessGroupRelationDao.addRole(participant1, group, GroupRoles.participant.name()); + businessGroupRelationDao.addRole(participant2, group, GroupRoles.participant.name()); + dbInstance.commitAndCloseSession(); + + int numOfParticipants = businessGroupRelationDao.countEnrollment(group); + Assert.assertEquals(2, numOfParticipants); + } + @Test public void loadForUpdate() { BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false);