package fi.otavanopisto.muikku.plugins.schooldatapyramus;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.AccessTimeout;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Stateless;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import fi.otavanopisto.muikku.model.users.EnvironmentUser;
import fi.otavanopisto.muikku.model.users.RoleSchoolDataIdentifier;
import fi.otavanopisto.muikku.model.users.UserEntity;
import fi.otavanopisto.muikku.model.users.UserGroupEntity;
import fi.otavanopisto.muikku.model.users.UserGroupUserEntity;
import fi.otavanopisto.muikku.model.users.UserRoleType;
import fi.otavanopisto.muikku.model.users.UserSchoolDataIdentifier;
import fi.otavanopisto.muikku.model.workspace.WorkspaceEntity;
import fi.otavanopisto.muikku.model.workspace.WorkspaceRoleEntity;
import fi.otavanopisto.muikku.model.workspace.WorkspaceUserEntity;
import fi.otavanopisto.muikku.plugins.schooldatapyramus.entities.PyramusSchoolDataEntityFactory;
import fi.otavanopisto.muikku.plugins.schooldatapyramus.rest.PyramusClient;
import fi.otavanopisto.muikku.schooldata.SchoolDataIdentifier;
import fi.otavanopisto.muikku.schooldata.WorkspaceController;
import fi.otavanopisto.muikku.schooldata.WorkspaceEntityController;
import fi.otavanopisto.muikku.schooldata.entity.EnvironmentRole;
import fi.otavanopisto.muikku.schooldata.entity.WorkspaceRole;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataEnvironmentRoleDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataEnvironmentRoleRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupUpdatedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupUserDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupUserRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserGroupUserUpdatedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataUserUpdatedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceRoleDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceRoleRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceUpdatedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceUserDiscoveredEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceUserRemovedEvent;
import fi.otavanopisto.muikku.schooldata.events.SchoolDataWorkspaceUserUpdatedEvent;
import fi.otavanopisto.muikku.users.EnvironmentRoleEntityController;
import fi.otavanopisto.muikku.users.EnvironmentUserController;
import fi.otavanopisto.muikku.users.RoleSchoolDataIdentifierController;
import fi.otavanopisto.muikku.users.UserEmailEntityController;
import fi.otavanopisto.muikku.users.UserEntityController;
import fi.otavanopisto.muikku.users.UserGroupEntityController;
import fi.otavanopisto.muikku.users.UserSchoolDataIdentifierController;
import fi.otavanopisto.muikku.users.WorkspaceRoleEntityController;
import fi.otavanopisto.muikku.users.WorkspaceUserEntityController;
import fi.otavanopisto.pyramus.rest.model.ContactType;
import fi.otavanopisto.pyramus.rest.model.Course;
import fi.otavanopisto.pyramus.rest.model.CourseStaffMember;
import fi.otavanopisto.pyramus.rest.model.CourseStaffMemberRole;
import fi.otavanopisto.pyramus.rest.model.CourseStudent;
import fi.otavanopisto.pyramus.rest.model.Email;
import fi.otavanopisto.pyramus.rest.model.Person;
import fi.otavanopisto.pyramus.rest.model.StaffMember;
import fi.otavanopisto.pyramus.rest.model.Student;
import fi.otavanopisto.pyramus.rest.model.StudentGroup;
import fi.otavanopisto.pyramus.rest.model.StudentGroupStudent;
import fi.otavanopisto.pyramus.rest.model.StudentGroupUser;
import fi.otavanopisto.pyramus.rest.model.StudyProgramme;
import fi.otavanopisto.pyramus.rest.model.UserRole;
@Stateless
public class PyramusUpdater {
@Inject
private Logger logger;
@Inject
private WorkspaceController workspaceController;
@Inject
private WorkspaceEntityController workspaceEntityController;
@Inject
private WorkspaceUserEntityController workspaceUserEntityController;
@Inject
private UserEntityController userEntityController;
@Inject
private UserSchoolDataIdentifierController userSchoolDataIdentifierController;
@Inject
private PyramusSchoolDataEntityFactory entityFactory;
@Inject
private Instance<PyramusClient> pyramusClient;
@Inject
private PyramusIdentifierMapper identifierMapper;
@Inject
private EnvironmentRoleEntityController environmentRoleEntityController;
@Inject
private RoleSchoolDataIdentifierController roleSchoolDataIdentifierController;
@Inject
private WorkspaceRoleEntityController workspaceRoleEntityController;
@Inject
private UserGroupEntityController userGroupEntityController;
@Inject
private EnvironmentUserController environmentUserController;
@Inject
private UserEmailEntityController userEmailEntityController;
@Inject
private Event<SchoolDataUserUpdatedEvent> schoolDataUserUpdatedEvent;
@Inject
private Event<SchoolDataWorkspaceUserDiscoveredEvent> schoolDataWorkspaceUserDiscoveredEvent;
@Inject
private Event<SchoolDataWorkspaceUserUpdatedEvent> schoolDataWorkspaceUserUpdatedEvent;
@Inject
private Event<SchoolDataWorkspaceUserRemovedEvent> schoolDataWorkspaceUserRemovedEvent;
@Inject
private Event<SchoolDataWorkspaceDiscoveredEvent> schoolDataWorkspaceDiscoveredEvent;
@Inject
private Event<SchoolDataWorkspaceUpdatedEvent> schoolDataWorkspaceUpdatedEvent;
@Inject
private Event<SchoolDataWorkspaceRemovedEvent> schoolDataWorkspaceRemovedEvent;
@Inject
private Event<SchoolDataEnvironmentRoleDiscoveredEvent> schoolDataEnvironmentRoleDiscoveredEvent;
@Inject
private Event<SchoolDataEnvironmentRoleRemovedEvent> schoolDataEnvironmentRoleRemovedEvent;
@Inject
private Event<SchoolDataWorkspaceRoleDiscoveredEvent> schoolDataWorkspaceRoleDiscoveredEvent;
@Inject
private Event<SchoolDataWorkspaceRoleRemovedEvent> schoolDataWorkspaceRoleRemovedEvent;
@Inject
private Event<SchoolDataUserGroupDiscoveredEvent> schoolDataUserGroupDiscoveredEvent;
@Inject
private Event<SchoolDataUserGroupUpdatedEvent> schoolDataUserGroupUpdatedEvent;
@Inject
private Event<SchoolDataUserGroupRemovedEvent> schoolDataUserGroupRemovedEvent;
@Inject
private Event<SchoolDataUserGroupUserDiscoveredEvent> schoolDataUserGroupUserDiscoveredEvent;
@Inject
private Event<SchoolDataUserGroupUserUpdatedEvent> schoolDataUserGroupUserUpdatedEvent;
@Inject
private Event<SchoolDataUserGroupUserRemovedEvent> schoolDataUserGroupUserRemovedEvent;
public int updateStudyProgrammes() {
StudyProgramme[] studyProgrammes = pyramusClient.get().get("/students/studyProgrammes", StudyProgramme[].class);
if (studyProgrammes == null || studyProgrammes.length == 0)
return -1;
for (StudyProgramme studyProgramme : studyProgrammes) {
updateStudyProgramme(studyProgramme.getId());
}
return studyProgrammes.length;
}
public void updateStudyProgramme(Long pyramusId) {
StudyProgramme studentGroup = pyramusClient.get().get(String.format("/students/studyProgrammes/%d", pyramusId), StudyProgramme.class);
String identifier = identifierMapper.getStudyProgrammeIdentifier(pyramusId);
UserGroupEntity userGroupEntity = userGroupEntityController.findUserGroupEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier, true);
if (studentGroup == null) {
if (userGroupEntity != null)
fireUserGroupRemoved(identifier);
} else {
if (userGroupEntity == null) {
fireUserGroupDiscovered(identifier);
} else {
fireUserGroupUpdated(identifier);
}
}
}
public int updateStudyProgrammeMembers(int offset, int maxStudents) {
Student[] students = pyramusClient.get().get("/students/students?filterArchived=false&firstResult=" + offset + "&maxResults=" + maxStudents, Student[].class);
if (students == null || students.length == 0) {
return -1;
}
for (Student student : students) {
updateStudyProgrammeMember(student);
}
return students.length;
}
public void updateStudyProgrammeMember(Student student) {
if (student.getStudyProgrammeId() != null) {
String studyProgrammeIdentifier = identifierMapper.getStudyProgrammeIdentifier(student.getStudyProgrammeId());
String studyProgrammeStudentIdentifier = identifierMapper.getStudyProgrammeStudentIdentifier(student.getId());
UserGroupUserEntity userGroupUserEntity = userGroupEntityController.findUserGroupUserEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, studyProgrammeStudentIdentifier);
boolean isActive = (!student.getArchived()) && (student.getStudyEndDate() == null);
if (isActive) {
if (userGroupUserEntity == null) {
String userEntityIdentifier = identifierMapper.getStudentIdentifier(student.getId());
fireUserGroupUserDiscovered(studyProgrammeStudentIdentifier, studyProgrammeIdentifier, userEntityIdentifier);
} else
fireUserGroupUserUpdated(studyProgrammeStudentIdentifier, studyProgrammeIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
} else {
if (userGroupUserEntity != null)
fireUserGroupUserRemoved(studyProgrammeStudentIdentifier, studyProgrammeIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
}
}
}
public int updateStudentGroups(int offset, int batchSize) {
StudentGroup[] userGroups = pyramusClient.get().get("/students/studentGroups?firstResult=" + offset + "&maxResults=" + batchSize, StudentGroup[].class);
if (userGroups == null || userGroups.length == 0)
return -1;
for (StudentGroup userGroup : userGroups) {
updateStudentGroup(userGroup.getId());
}
return userGroups.length;
}
public void updateStudentGroup(Long pyramusId) {
StudentGroup studentGroup = pyramusClient.get().get(String.format("/students/studentGroups/%d", pyramusId), StudentGroup.class);
String identifier = identifierMapper.getStudentGroupIdentifier(pyramusId);
UserGroupEntity userGroupEntity = userGroupEntityController.findUserGroupEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier, true);
if (studentGroup == null) {
if (userGroupEntity != null)
fireUserGroupRemoved(identifier);
} else {
if (userGroupEntity == null) {
fireUserGroupDiscovered(identifier);
} else {
fireUserGroupUpdated(identifier);
}
}
}
public int updateStudyProgrammeGroupUsers(Long studyProgrammeId) {
// TODO: There's no endpoint to do this efficiently atm
return 0;
}
public int updateStudentGroupUsers(Long studentGroupId) {
String userGroupIdentifier = identifierMapper.getStudentGroupIdentifier(studentGroupId);
UserGroupEntity userGroupEntity = userGroupEntityController.findUserGroupEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier, true);
if (userGroupEntity != null) {
if (userGroupEntity.getArchived()) {
// Just skip archived user groups
return 0;
}
List<UserGroupUserEntity> existingUsers = userGroupEntityController.listUserGroupUserEntitiesByUserGroupEntity(userGroupEntity);
List<String> existingGroupUserIds = new ArrayList<String>();
for (UserGroupUserEntity existingUser : existingUsers) {
existingGroupUserIds.add(existingUser.getIdentifier());
}
List<String> foundGroupUserIds = new ArrayList<String>();
int count = 0;
StudentGroupUser[] userGroupStaffMembers = pyramusClient.get().get(String.format("/students/studentGroups/%d/staffmembers", studentGroupId), StudentGroupUser[].class);
if (userGroupStaffMembers != null) {
for (StudentGroupUser sgStaffMember : userGroupStaffMembers) {
String identifier = identifierMapper.getStudentGroupStaffMemberIdentifier(sgStaffMember.getId());
foundGroupUserIds.add(identifier);
// If not existing, then it's a new one
if (!existingGroupUserIds.contains(identifier)) {
String staffMemberIdentifier = identifierMapper.getStaffIdentifier(sgStaffMember.getStaffMemberId());
fireUserGroupUserDiscovered(identifier, userGroupIdentifier, staffMemberIdentifier);
}
}
count += userGroupStaffMembers.length;
}
StudentGroupStudent[] userGroupStudents = pyramusClient.get().get(String.format("/students/studentGroups/%d/students", studentGroupId), StudentGroupStudent[].class);
if (userGroupStudents != null) {
for (StudentGroupStudent sgs : userGroupStudents) {
String identifier = identifierMapper.getStudentGroupStudentIdentifier(sgs.getId());
foundGroupUserIds.add(identifier);
// If not existing, then it's a new one
if (!existingGroupUserIds.contains(identifier)) {
String studentIdentifier = identifierMapper.getStudentIdentifier(sgs.getStudentId());
fireUserGroupUserDiscovered(identifier, userGroupIdentifier, studentIdentifier);
}
}
count += userGroupStudents.length;
}
// Remove found ids from existing and we'll get the ones to remove
existingGroupUserIds.removeAll(foundGroupUserIds);
for (String identifier : existingGroupUserIds) {
UserGroupUserEntity ugu = userGroupEntityController.findUserGroupUserEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier);
if (ugu != null)
fireUserGroupUserRemoved(identifier, userGroupIdentifier, ugu.getUserSchoolDataIdentifier().getIdentifier());
}
return count;
} else {
logger.log(Level.WARNING, String.format("UserGroup is null for id %d - update of users is skipped", studentGroupId));
}
return 0;
}
public void updateStudentGroupStudent(Long studentGroupId, Long studentGroupStudentId) {
StudentGroupStudent studentGroupStudent = pyramusClient.get().get(String.format("/students/studentGroups/%d/students/%d", studentGroupId, studentGroupStudentId), StudentGroupStudent.class);
String identifier = identifierMapper.getStudentGroupStudentIdentifier(studentGroupStudentId);
UserGroupUserEntity userGroupUserEntity = userGroupEntityController.findUserGroupUserEntityByDataSourceAndIdentifier(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier);
String userGroupIdentifier = identifierMapper.getStudentGroupIdentifier(studentGroupId);
if (studentGroupStudent == null) {
if (userGroupUserEntity != null)
fireUserGroupUserRemoved(identifier, userGroupIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
} else {
if (userGroupUserEntity == null) {
String studentIdentifier = identifierMapper.getStudentIdentifier(studentGroupStudent.getStudentId());
fireUserGroupUserDiscovered(identifier, userGroupIdentifier, studentIdentifier);
} else {
fireUserGroupUserUpdated(identifier, userGroupIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
}
}
}
public void updateStudentGroupStaffMember(Long studentGroupId, Long studentGroupStaffMemberId) {
StudentGroupUser studentGroupStaffMember = pyramusClient.get().get(String.format("/students/studentGroups/%d/staffmembers/%d", studentGroupId, studentGroupStaffMemberId), StudentGroupUser.class);
String identifier = identifierMapper.getStudentGroupStaffMemberIdentifier(studentGroupStaffMemberId);
UserGroupUserEntity userGroupUserEntity = userGroupEntityController.findUserGroupUserEntityByDataSourceAndIdentifier(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier);
String userGroupIdentifier = identifierMapper.getStudentGroupIdentifier(studentGroupId);
if (studentGroupStaffMember == null) {
if (userGroupUserEntity != null)
fireUserGroupUserRemoved(identifier, userGroupIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
} else {
if (userGroupUserEntity == null) {
String staffMemberIdentifier = identifierMapper.getStaffIdentifier(studentGroupStaffMember.getStaffMemberId());
fireUserGroupUserDiscovered(identifier, userGroupIdentifier, staffMemberIdentifier);
} else {
fireUserGroupUserUpdated(identifier, userGroupIdentifier, userGroupUserEntity.getUserSchoolDataIdentifier().getIdentifier());
}
}
}
/**
* Updates a course from Pyramus
*
* @param pyramusId id of course in Pyramus
* @return returns whether new course was created or not
*/
public void updateCourse(Long courseId) {
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseId);
Course course = pyramusClient.get().get("/courses/courses/" + courseId, Course.class);
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier);
if (course != null) {
if (workspaceEntity == null) {
fireWorkspaceDiscovered(course);
} else {
fireWorkspaceUpdated(course);
}
} else {
if (workspaceEntity != null) {
fireWorkspaceRemoved(courseId);
}
}
}
/**
* Updates courses from Pyramus
*
* @param offset first course to be updated
* @param maxCourses maximum batch size
* @return count of updated courses or -1 when no courses were found with given offset
*/
public int updateCourses(int offset, int maxCourses) {
Course[] courses = pyramusClient.get().get("/courses/courses?filterArchived=false&firstResult=" + offset + "&maxResults=" + maxCourses, Course[].class);
if ((courses == null) || (courses.length == 0)) {
return -1;
}
List<String> existingIdentifiers = workspaceEntityController.listWorkspaceEntityIdentifiersByDataSource(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
List<Course> discoveredCourses = new ArrayList<>();
List<Course> removedCourses = new ArrayList<>();
for (Course course : courses) {
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(course.getId());
if (course.getArchived()) {
if (existingIdentifiers.contains(workspaceIdentifier)) {
removedCourses.add(course);
}
} else {
if (!existingIdentifiers.contains(workspaceIdentifier)) {
discoveredCourses.add(course);
}
}
}
for (Course discoveredCourse : discoveredCourses) {
fireWorkspaceDiscovered(discoveredCourse);
}
for (Course removedCourse : removedCourses) {
fireWorkspaceRemoved(removedCourse.getId());
}
return discoveredCourses.size();
}
/**
* Updates course staff member from Pyramus
*
* @param courseStaffMemberId id of course staff member in Pyramus
* @param courseId id of course in Pyramus
* @param staffMemberId id of staff member in Pyramus
* @return returns whether new staff member was created or not
*/
public boolean updateCourseStaffMember(Long courseStaffMemberId, Long courseId, Long staffMemberId) {
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseId);
String identifier = identifierMapper.getWorkspaceStaffIdentifier(courseStaffMemberId);
// TODO: course staff member removals can be left unnoticed if
// webhooks fails because they do not have archived flag
WorkspaceEntity workspaceEntity = workspaceController.findWorkspaceEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier);
if (workspaceEntity == null) {
updateCourse(courseId);
workspaceEntity = workspaceController.findWorkspaceEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier);
}
if (workspaceEntity != null) {
SchoolDataIdentifier workspaceUserIdentifier = new SchoolDataIdentifier(identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
CourseStaffMember staffMember = pyramusClient.get().get("/courses/courses/" + courseId + "/staffMembers/" + courseStaffMemberId, CourseStaffMember.class);
if (staffMember != null) {
if (workspaceUserEntity == null) {
fireCourseStaffMemberDiscovered(staffMember);
return true;
} else {
fireCourseStaffMemberUpdated(staffMember);
}
} else {
if (workspaceUserEntity != null) {
fireCourseStaffMemberRemoved(courseStaffMemberId, staffMemberId, courseId);
return true;
}
}
}
return false;
}
/**
* Updates course staff members from Pyramus
*
* @param courseId id of course in Pyramus
* @return count of updated courses staff members
*/
public int updateCourseStaffMembers(Long courseId) {
CourseStaffMember[] staffMembers = pyramusClient.get().get("/courses/courses/" + courseId + "/staffMembers", CourseStaffMember[].class);
if (staffMembers != null) {
for (CourseStaffMember staffMember : staffMembers) {
String staffIdentifier = identifierMapper.getWorkspaceStaffIdentifier(staffMember.getId());
SchoolDataIdentifier workspaceUserIdentifier = new SchoolDataIdentifier(staffIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifier(workspaceUserIdentifier);
if (workspaceUserEntity == null) {
fireCourseStaffMemberDiscovered(staffMember);
}
}
}
return 0;
}
/**
* Updates user roles from Pyramus
*
* @return count of updates roles
*/
public int updateUserRoles() {
int count = 0;
List<RoleSchoolDataIdentifier> existingRoleIdentifiers = roleSchoolDataIdentifierController.listRoleSchoolDataIdentifiersByDataSource(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
Map<String, RoleSchoolDataIdentifier> removedIdentifiers = new HashMap<>();
for (RoleSchoolDataIdentifier existingRoleIdentifier : existingRoleIdentifiers) {
removedIdentifiers.put(existingRoleIdentifier.getIdentifier(), existingRoleIdentifier);
}
for (fi.otavanopisto.pyramus.rest.model.UserRole userRole : fi.otavanopisto.pyramus.rest.model.UserRole.values()) {
String roleIdentifier = identifierMapper.getEnvironmentRoleIdentifier(userRole);
removedIdentifiers.remove(roleIdentifier);
if (environmentRoleEntityController.findEnvironmentRoleEntity(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, roleIdentifier) == null) {
EnvironmentRole environmentRole = entityFactory.createEntity(userRole);
schoolDataEnvironmentRoleDiscoveredEvent.fire(new SchoolDataEnvironmentRoleDiscoveredEvent(environmentRole.getSchoolDataSource(), environmentRole.getIdentifier(), environmentRole.getArchetype(), environmentRole.getName()));
count++;
}
}
CourseStaffMemberRole[] staffMemberRoles = pyramusClient.get().get("/courses/staffMemberRoles", CourseStaffMemberRole[].class);
if (staffMemberRoles == null || staffMemberRoles.length == 0) {
logger.warning("Aborting role synchronization because Pyramus has no course staff member roles");
return count;
}
for (CourseStaffMemberRole staffMemberRole : staffMemberRoles) {
String identifier = identifierMapper.getWorkspaceStaffRoleIdentifier(staffMemberRole.getId());
removedIdentifiers.remove(identifier);
WorkspaceRoleEntity workspaceRoleEntity = workspaceRoleEntityController.findWorkspaceRoleEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier);
if (workspaceRoleEntity == null) {
WorkspaceRole workspaceRole = entityFactory.createEntity(staffMemberRole);
schoolDataWorkspaceRoleDiscoveredEvent.fire(new SchoolDataWorkspaceRoleDiscoveredEvent(workspaceRole.getSchoolDataSource(), workspaceRole.getIdentifier(), workspaceRole.getArchetype(), workspaceRole.getName()));
count++;
}
}
WorkspaceRole studentRole = entityFactory.createCourseStudentRoleEntity();
removedIdentifiers.remove(studentRole.getIdentifier());
WorkspaceRoleEntity studentWorkspaceRoleEntity = workspaceRoleEntityController.findWorkspaceRoleEntityByDataSourceAndIdentifier(studentRole.getSchoolDataSource(), studentRole.getIdentifier());
if (studentWorkspaceRoleEntity == null) {
schoolDataWorkspaceRoleDiscoveredEvent.fire(new SchoolDataWorkspaceRoleDiscoveredEvent(studentRole.getSchoolDataSource(), studentRole.getIdentifier(), studentRole.getArchetype(), studentRole.getName()));
count++;
}
Set<String> removedIdentifierIds = removedIdentifiers.keySet();
for (String removedIdentifierId : removedIdentifierIds) {
RoleSchoolDataIdentifier removedIdentifier = removedIdentifiers.get(removedIdentifierId);
if (removedIdentifier.getRoleEntity().getType() == UserRoleType.ENVIRONMENT) {
schoolDataEnvironmentRoleRemovedEvent.fire(new SchoolDataEnvironmentRoleRemovedEvent(removedIdentifier.getDataSource().getIdentifier(), removedIdentifier.getIdentifier()));
} else if (removedIdentifier.getRoleEntity().getType() == UserRoleType.WORKSPACE) {
schoolDataWorkspaceRoleRemovedEvent.fire(new SchoolDataWorkspaceRoleRemovedEvent(removedIdentifier.getDataSource().getIdentifier(), removedIdentifier.getIdentifier()));
}
}
return count;
}
/**
* Updates course student from Pyramus
*
* @param courseStudentId id of course student in Pyramus
* @param courseId id of course in Pyramus
* @param studentId id of student in Pyramus
* @return returns whether new course student was created or not
*/
public boolean updateCourseStudent(Long courseStudentId, Long courseId, Long studentId) {
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseId);
String identifier = identifierMapper.getWorkspaceStudentIdentifier(courseStudentId);
WorkspaceEntity workspaceEntity = workspaceController.findWorkspaceEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier);
if (workspaceEntity == null) {
updateCourse(courseId);
workspaceEntity = workspaceController.findWorkspaceEntityByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier);
}
if (workspaceEntity != null) {
SchoolDataIdentifier workspaceUserIdentifier = new SchoolDataIdentifier(identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
CourseStudent courseStudent = pyramusClient.get().get("/courses/courses/" + courseId + "/students/" + courseStudentId, CourseStudent.class);
if (courseStudent != null && !courseStudent.getArchived()) {
boolean studentActive = isStudentActive(courseStudent.getStudentId());
if (workspaceUserEntity == null && studentActive) {
fireCourseStudentDiscovered(courseStudent);
return true;
} else {
if (studentActive) {
fireCourseStudentUpdated(courseStudent);
} else {
fireCourseStudentRemoved(courseStudentId, studentId, courseId);
}
}
} else {
if (workspaceUserEntity != null) {
fireCourseStudentRemoved(courseStudentId, studentId, courseId);
}
}
}
return false;
}
private boolean isStudentActive(Long studentId) {
Student student = pyramusClient.get().get(String.format("/students/students/%d", studentId), Student.class);
if (student == null || student.getArchived()) {
logger.severe(String.format("Tried to resolve activity for non existings student (%d)", studentId));
return false;
}
OffsetDateTime studyStartDate = student.getStudyStartDate();
OffsetDateTime studyEndDate = student.getStudyEndDate();
if (studyStartDate == null && studyEndDate == null) {
// It's a never ending study programme
return true;
}
boolean startedStudies = studyStartDate != null && studyStartDate.isBefore(OffsetDateTime.now());
boolean finishedStudies = studyEndDate != null && studyEndDate.isBefore(OffsetDateTime.now());
return startedStudies && !finishedStudies;
}
/**
* Updates course students from Pyramus
*
* @param courseId id of course in Pyramus
* @return count of updated course students
*/
public int updateWorkspaceStudents(WorkspaceEntity workspaceEntity) {
int count = 0;
Long courseId = identifierMapper.getPyramusCourseId(workspaceEntity.getIdentifier());
CourseStudent[] courseStudents = pyramusClient.get().get("/courses/courses/" + courseId + "/students?filterArchived=false&activeStudents=true", CourseStudent[].class);
if (courseStudents != null) {
for (CourseStudent courseStudent : courseStudents) {
SchoolDataIdentifier workspaceUserIdentifier = toIdentifier(identifierMapper.getWorkspaceStudentIdentifier(courseStudent.getId()));
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
if (courseStudent.getArchived()) {
if (workspaceUserEntity != null) {
fireCourseStudentRemoved(courseStudent.getId(), courseStudent.getStudentId(), courseStudent.getCourseId());
count++;
}
} else {
if (workspaceUserEntity == null) {
fireCourseStudentDiscovered(courseStudent);
count++;
}
}
}
}
CourseStudent[] nonActiveCourseStudents = pyramusClient.get().get("/courses/courses/" + courseId + "/students?filterArchived=false&activeStudents=false", CourseStudent[].class);
if (nonActiveCourseStudents != null) {
for (CourseStudent nonActiveCourseStudent : nonActiveCourseStudents) {
SchoolDataIdentifier workspaceUserIdentifier = toIdentifier(identifierMapper.getWorkspaceStudentIdentifier(nonActiveCourseStudent.getId()));
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
if (workspaceUserEntity != null) {
fireCourseStudentRemoved(nonActiveCourseStudent.getId(), nonActiveCourseStudent.getStudentId(), nonActiveCourseStudent.getCourseId());
count++;
}
}
}
return count;
}
private void fireWorkspaceDiscovered(Course course) {
String identifier = identifierMapper.getWorkspaceIdentifier(course.getId());
Map<String, Object> extra = new HashMap<>();
extra.put("pyramusVariables", course.getVariables());
schoolDataWorkspaceDiscoveredEvent.fire(new SchoolDataWorkspaceDiscoveredEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier, course.getName(), extra));
}
private void fireWorkspaceUpdated(Course course) {
String identifier = identifierMapper.getWorkspaceIdentifier(course.getId());
Map<String, Object> extra = new HashMap<>();
extra.put("pyramusVariables", course.getVariables());
schoolDataWorkspaceUpdatedEvent.fire(new SchoolDataWorkspaceUpdatedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier, course.getName(), extra));
}
private void fireWorkspaceRemoved(Long courseId) {
String identifier = identifierMapper.getWorkspaceIdentifier(courseId);
String searchId = identifier + '/' + SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE;
schoolDataWorkspaceRemovedEvent.fire(new SchoolDataWorkspaceRemovedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier, searchId));
}
private void fireCourseStaffMemberDiscovered(CourseStaffMember courseStaffMember) {
String identifier = identifierMapper.getWorkspaceStaffIdentifier(courseStaffMember.getId());
String userIdentifier = identifierMapper.getStaffIdentifier(courseStaffMember.getStaffMemberId());
String roleIdentifier = identifierMapper.getWorkspaceStaffRoleIdentifier(courseStaffMember.getRoleId());
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseStaffMember.getCourseId());
schoolDataWorkspaceUserDiscoveredEvent.fire(new SchoolDataWorkspaceUserDiscoveredEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, roleIdentifier));
}
private void fireCourseStaffMemberUpdated(CourseStaffMember courseStaffMember) {
String identifier = identifierMapper.getWorkspaceStaffIdentifier(courseStaffMember.getId());
String userIdentifier = identifierMapper.getStaffIdentifier(courseStaffMember.getStaffMemberId());
String roleIdentifier = identifierMapper.getWorkspaceStaffRoleIdentifier(courseStaffMember.getRoleId());
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseStaffMember.getCourseId());
schoolDataWorkspaceUserUpdatedEvent.fire(new SchoolDataWorkspaceUserUpdatedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, roleIdentifier));
}
private void fireCourseStaffMemberRemoved(Long courseStaffMemberId, Long staffMemberId, Long courseId) {
String identifier = identifierMapper.getWorkspaceStaffIdentifier(courseStaffMemberId);
String userIdentifier = identifierMapper.getStaffIdentifier(staffMemberId);
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseId);
schoolDataWorkspaceUserRemovedEvent.fire(new SchoolDataWorkspaceUserRemovedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier));
}
private void fireCourseStudentDiscovered(CourseStudent courseStudent) {
String identifier = identifierMapper.getWorkspaceStudentIdentifier(courseStudent.getId());
String userIdentifier = identifierMapper.getStudentIdentifier(courseStudent.getStudentId());
String roleIdentifier = identifierMapper.getWorkspaceStudentRoleIdentifier();
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseStudent.getCourseId());
schoolDataWorkspaceUserDiscoveredEvent.fire(new SchoolDataWorkspaceUserDiscoveredEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, roleIdentifier));
}
private void fireCourseStudentUpdated(CourseStudent courseStudent) {
String identifier = identifierMapper.getWorkspaceStudentIdentifier(courseStudent.getId());
String userIdentifier = identifierMapper.getStudentIdentifier(courseStudent.getStudentId());
String roleIdentifier = identifierMapper.getWorkspaceStudentRoleIdentifier();
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseStudent.getCourseId());
schoolDataWorkspaceUserUpdatedEvent.fire(new SchoolDataWorkspaceUserUpdatedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, roleIdentifier));
}
private void fireCourseStudentRemoved(Long courseStudentId, Long studentId, Long courseId) {
String identifier = identifierMapper.getWorkspaceStudentIdentifier(courseStudentId);
String userIdentifier = identifierMapper.getStudentIdentifier(studentId);
String workspaceIdentifier = identifierMapper.getWorkspaceIdentifier(courseId);
schoolDataWorkspaceUserRemovedEvent.fire(new SchoolDataWorkspaceUserRemovedEvent(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, workspaceIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE,
userIdentifier));
}
private void fireUserGroupDiscovered(String userGroupIdentifier) {
schoolDataUserGroupDiscoveredEvent.fire(new SchoolDataUserGroupDiscoveredEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier));
}
private void fireUserGroupUpdated(String userGroupIdentifier) {
schoolDataUserGroupUpdatedEvent.fire(new SchoolDataUserGroupUpdatedEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier));
}
private void fireUserGroupRemoved(String userGroupIdentifier) {
String searchId = userGroupIdentifier + '/' + SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE;
schoolDataUserGroupRemovedEvent.fire(new SchoolDataUserGroupRemovedEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier,
searchId));
}
private void fireUserGroupUserDiscovered(String userGroupUserIdentifier, String userGroupIdentifier, String userEntityIdentifier) {
schoolDataUserGroupUserDiscoveredEvent.fire(new SchoolDataUserGroupUserDiscoveredEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupUserIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userEntityIdentifier));
}
private void fireUserGroupUserUpdated(String userGroupUserIdentifier, String userGroupIdentifier, String userIdentifier) {
schoolDataUserGroupUserUpdatedEvent.fire(new SchoolDataUserGroupUserUpdatedEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupUserIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userIdentifier));
}
private void fireUserGroupUserRemoved(String userGroupUserIdentifier, String userGroupIdentifier, String userIdentifier) {
schoolDataUserGroupUserRemovedEvent.fire(new SchoolDataUserGroupUserRemovedEvent(
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupUserIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userGroupIdentifier,
SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, userIdentifier));
}
public void updatePerson(Long personId) {
Person person = pyramusClient.get().get(String.format("/persons/persons/%d", personId), Person.class);
if (person != null) {
updatePerson(person);
} else {
logger.severe(String.format("Person %d could not be found. Skipping synchronization", personId));
}
}
@Lock (LockType.WRITE)
@AccessTimeout(value=30000)
public void updatePerson(Person person) {
Long userEntityId = null;
String defaultIdentifier = null;
Long defaultUserId = person.getDefaultUserId();
UserRole defaultUserPyramusRole = null;
List<String> identifiers = new ArrayList<>();
List<String> removedIdentifiers = new ArrayList<>();
List<String> updatedIdentifiers = new ArrayList<>();
List<String> discoveredIdentifiers = new ArrayList<>();
Map<SchoolDataIdentifier, List<String>> emails = new HashMap<>();
// List all person's students and staffMembers
Student[] students = pyramusClient.get().get(String.format("/persons/persons/%d/students", person.getId()), Student[].class);
StaffMember[] staffMembers = pyramusClient.get().get(String.format("/persons/persons/%d/staffMembers", person.getId()), StaffMember[].class);
// If person does not have a defaultUserId specified, we try to guess something
if (defaultUserId == null) {
if ((staffMembers != null) && (staffMembers.length > 0)) {
// If person has a staffMember instance, lets use that one
defaultUserId = staffMembers[0].getId();
} else {
if (students != null) {
// Otherwise just use first non archived student (if any)
for (Student student : students) {
if (!student.getArchived()) {
defaultUserId = student.getId();
break;
}
}
}
}
}
if (students != null) {
// Iterate over all student instances
for (Student student : students) {
String identifier = identifierMapper.getStudentIdentifier(student.getId());
SchoolDataIdentifier schoolDataIdentifier = toIdentifier(identifier);
List<String> identifierEmails = new ArrayList<String>();
if (!student.getArchived()) {
// If student is not archived, add it to identifiers list
identifiers.add(identifier);
// If it's the specified defaultUserId, update defaultIdentifier and role accordingly
if ((defaultIdentifier == null) && student.getId().equals(defaultUserId)) {
defaultIdentifier = identifier;
defaultUserPyramusRole = UserRole.STUDENT;
}
// List emails and add all emails that are not specified non unique (e.g. contact persons) to the emails list
Email[] studentEmails = pyramusClient.get().get("/students/students/" + student.getId() + "/emails", Email[].class);
if (studentEmails != null) {
for (Email studentEmail : studentEmails) {
if (studentEmail.getContactTypeId() != null) {
ContactType contactType = pyramusClient.get().get("/common/contactTypes/" + studentEmail.getContactTypeId(), ContactType.class);
if (!contactType.getNonUnique() && !identifierEmails.contains(studentEmail.getAddress())) {
identifierEmails.add(studentEmail.getAddress());
}
} else {
logger.log(Level.WARNING, "ContactType of email is null - email is ignored");
}
}
}
} else {
// If the student instance if archived, we add it the the removed identifiers list
removedIdentifiers.add(identifier);
}
emails.put(schoolDataIdentifier, identifierEmails);
}
}
if (staffMembers != null) {
for (StaffMember staffMember : staffMembers) {
// Add staffMember identifier into the identifier list
String identifier = identifierMapper.getStaffIdentifier(staffMember.getId());
SchoolDataIdentifier schoolDataIdentifier = toIdentifier(identifier);
List<String> identifierEmails = new ArrayList<String>();
identifiers.add(identifier);
// If it's the specified defaultUserId, update defaultIdentifier and role accordingly
if ((defaultIdentifier == null) && staffMember.getId().equals(defaultUserId)) {
defaultIdentifier = identifier;
defaultUserPyramusRole = staffMember.getRole();
}
// List emails and add all emails that are not specified non unique (e.g. contact persons) to the emails list
Email[] staffMemberEmails = pyramusClient.get().get("/staff/members/" + staffMember.getId() + "/emails", Email[].class);
if (staffMemberEmails != null) {
for (Email staffMemberEmail : staffMemberEmails) {
if (staffMemberEmail.getContactTypeId() != null) {
ContactType contactType = pyramusClient.get().get("/common/contactTypes/" + staffMemberEmail.getContactTypeId(), ContactType.class);
if (!contactType.getNonUnique() && !identifierEmails.contains(staffMemberEmail.getAddress())) {
identifierEmails.add(staffMemberEmail.getAddress());
}
} else {
logger.log(Level.WARNING, "ContactType of email is null - email is ignored");
}
}
}
emails.put(schoolDataIdentifier, identifierEmails);
}
}
// Iterate over all discovered identifiers (students and staff members)
for (String identifier : identifiers) {
UserSchoolDataIdentifier userSchoolDataIdentifier = userSchoolDataIdentifierController.findUserSchoolDataIdentifierByDataSourceAndIdentifier(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE, identifier);
if (userSchoolDataIdentifier == null) {
// If no user entity can be found by the identifier, add it the the discovered identities list
discoveredIdentifiers.add(identifier);
} else {
// user entity found with given identity, so we need to make sure they all belong to same user
UserEntity userEntity = userSchoolDataIdentifier.getUserEntity();
if (userEntityId == null) {
userEntityId = userEntity.getId();
} else if (!userEntityId.equals(userEntity.getId())) {
logger.warning(String.format("Person %d synchronization failed. Found two userEntitys bound to it (%d and %d)", person.getId(), userEntityId, userEntity.getId()));
return;
}
}
}
UserEntity userEntity = userEntityId != null ? userEntityController.findUserEntityById(userEntityId) : null;
if (userEntity != null) {
// User already exists in the system so we check which of the idetifiers have been removed and which just updated
List<UserSchoolDataIdentifier> existingSchoolDataIdentifiers = userSchoolDataIdentifierController.listUserSchoolDataIdentifiersByUserEntity(userEntity);
for (UserSchoolDataIdentifier existingSchoolDataIdentifier : existingSchoolDataIdentifiers) {
if (existingSchoolDataIdentifier.getDataSource().getIdentifier().equals(SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE)) {
if (!identifiers.contains(existingSchoolDataIdentifier.getIdentifier())) {
if (!removedIdentifiers.contains(existingSchoolDataIdentifier.getIdentifier())) {
removedIdentifiers.add(existingSchoolDataIdentifier.getIdentifier());
}
} else if (!discoveredIdentifiers.contains(existingSchoolDataIdentifier.getIdentifier())) {
updatedIdentifiers.add(existingSchoolDataIdentifier.getIdentifier());
}
}
}
}
// Resolve the user's desired environment role
SchoolDataIdentifier environmentRoleIdentifier = null;
if (defaultUserPyramusRole != null) {
String roleIdentifier = identifierMapper.getEnvironmentRoleIdentifier(defaultUserPyramusRole);
environmentRoleIdentifier = new SchoolDataIdentifier(roleIdentifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
}
// And finally fire the update event
fireSchoolDataUserUpdated(userEntityId, defaultIdentifier, removedIdentifiers, updatedIdentifiers, discoveredIdentifiers, emails, environmentRoleIdentifier);
}
private void fireSchoolDataUserUpdated(Long userEntityId, SchoolDataIdentifier defaultIdentifier, List<SchoolDataIdentifier> removedIdentifiers, List<SchoolDataIdentifier> updatedIdentifiers,
List<SchoolDataIdentifier> discoveredIdentifiers, Map<SchoolDataIdentifier, List<String>> emails, SchoolDataIdentifier enivormentRoleIdentifier) {
if (discoveredIdentifiers == null) {
discoveredIdentifiers = Collections.emptyList();
}
if (updatedIdentifiers == null) {
updatedIdentifiers = Collections.emptyList();
}
if (removedIdentifiers == null) {
removedIdentifiers = Collections.emptyList();
}
schoolDataUserUpdatedEvent.fire(new SchoolDataUserUpdatedEvent(userEntityId,
enivormentRoleIdentifier,
discoveredIdentifiers,
updatedIdentifiers,
removedIdentifiers,
defaultIdentifier,
emails));
}
private void fireSchoolDataUserUpdated(Long userEntityId, String defaultIdentifier, List<String> removedIdentifiers, List<String> updatedIdentifiers,
List<String> discoveredIdentifiers, Map<SchoolDataIdentifier, List<String>> emails, SchoolDataIdentifier enivormentRoleIdentifier) {
fireSchoolDataUserUpdated(userEntityId,
toIdentifier(defaultIdentifier),
toIdentifiers(removedIdentifiers),
toIdentifiers(updatedIdentifiers),
toIdentifiers(discoveredIdentifiers),
emails,
enivormentRoleIdentifier
);
}
private SchoolDataIdentifier toIdentifier(String identifier) {
return new SchoolDataIdentifier(identifier, SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE);
}
private List<SchoolDataIdentifier> toIdentifiers(List<String> identifiers) {
List<SchoolDataIdentifier> result = new ArrayList<>();
if (identifiers != null && !identifiers.isEmpty()) {
for (String identifier : identifiers) {
result.add(toIdentifier(identifier));
}
}
return result;
}
public void updateStaffMember(Long staffMemberId) {
StaffMember staffMember = pyramusClient.get().get(String.format("/staff/members/%d", staffMemberId), StaffMember.class);
if (staffMember != null) {
updatePerson(staffMember.getPersonId());
} else {
identifierRemoved(toIdentifier(identifierMapper.getStaffIdentifier(staffMemberId)));
}
}
public void updateStudent(Long studentId) {
Student student = pyramusClient.get().get(String.format("/students/students/%d", studentId), Student.class);
if (student != null) {
updatePerson(student.getPersonId());
updateStudyProgrammeMember(student);
} else {
identifierRemoved(toIdentifier(identifierMapper.getStudentIdentifier(studentId)));
}
}
private void identifierRemoved(SchoolDataIdentifier identifier) {
UserSchoolDataIdentifier schoolDataIdentifier = userSchoolDataIdentifierController.findUserSchoolDataIdentifierByDataSourceAndIdentifier(identifier.getDataSource(), identifier.getIdentifier());
if (schoolDataIdentifier != null) {
UserEntity userEntity = schoolDataIdentifier.getUserEntity();
List<UserSchoolDataIdentifier> existingIdentifiers = userSchoolDataIdentifierController.listUserSchoolDataIdentifiersByUserEntity(userEntity);
SchoolDataIdentifier defaultIdentifier = null;
List<SchoolDataIdentifier> removedIdentifiers = Arrays.asList(identifier);
List<SchoolDataIdentifier> updatedIdentifiers = new ArrayList<>();
List<SchoolDataIdentifier> discoveredIdentifiers = new ArrayList<>();
Map<SchoolDataIdentifier, List<String>> emails = new HashMap<>();
for (SchoolDataIdentifier removedIdentifier : removedIdentifiers) {
emails.put(removedIdentifier, new ArrayList<String>());
}
for (UserSchoolDataIdentifier existingIdentifier : existingIdentifiers) {
if (!(existingIdentifier.getDataSource().getIdentifier().equals(identifier.getDataSource()) && existingIdentifier.getIdentifier().equals(identifier.getIdentifier()))) {
SchoolDataIdentifier updatedIdentifier = new SchoolDataIdentifier(existingIdentifier.getIdentifier(), existingIdentifier.getDataSource().getIdentifier());
updatedIdentifiers.add(updatedIdentifier);
emails.put(updatedIdentifier, userEmailEntityController.getUserEmailAddresses(updatedIdentifier));
}
}
SchoolDataIdentifier enivormentRoleIdentifier = getUserEntityEnvironmentRoleIdentifier(userEntity);
fireSchoolDataUserUpdated(userEntity.getId(),
defaultIdentifier,
removedIdentifiers,
updatedIdentifiers,
discoveredIdentifiers,
emails,
enivormentRoleIdentifier);
}
}
private SchoolDataIdentifier getUserEntityEnvironmentRoleIdentifier(UserEntity userEntity) {
EnvironmentUser environmentUser = environmentUserController.findEnvironmentUserByUserEntity(userEntity);
if (environmentUser != null) {
List<RoleSchoolDataIdentifier> identifiers = environmentRoleEntityController.listRoleSchoolDataIdentifiersByEnvironmentRoleEntity(environmentUser.getRole());
for (RoleSchoolDataIdentifier identifier : identifiers) {
if (SchoolDataPyramusPluginDescriptor.SCHOOL_DATA_SOURCE.equals(identifier.getDataSource().getIdentifier())) {
return new SchoolDataIdentifier(identifier.getIdentifier(), identifier.getDataSource().getIdentifier());
}
}
}
return null;
}
public int updatePersons(int offset, int maxCourses) {
Person[] persons = pyramusClient.get().get(String.format("/persons/persons?filterArchived=false&firstResult=%d&maxResults=%d", offset, maxCourses), Person[].class);
if ((persons == null) || (persons.length == 0)) {
return -1;
}
for (Person person : persons) {
updatePerson(person);
}
return 0;
}
}