| package org.eclipse.openk.contactbasedata.service; |
| |
| import lombok.extern.log4j.Log4j2; |
| import org.apache.commons.lang.StringUtils; |
| import org.eclipse.openk.contactbasedata.exceptions.NotFoundException; |
| import org.eclipse.openk.contactbasedata.model.RefCommunicationType; |
| import org.eclipse.openk.contactbasedata.model.TblCommunication; |
| import org.eclipse.openk.contactbasedata.model.TblInternalPerson; |
| import org.eclipse.openk.contactbasedata.repository.CommunicationRepository; |
| import org.eclipse.openk.contactbasedata.repository.CommunicationTypeRepository; |
| import org.eclipse.openk.contactbasedata.repository.InternalPersonRepository; |
| import org.eclipse.openk.contactbasedata.service.util.LdapUserAttributesMapper; |
| import org.eclipse.openk.contactbasedata.viewmodel.LdapUser; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.beans.factory.annotation.Value; |
| import org.springframework.ldap.core.LdapTemplate; |
| import org.springframework.stereotype.Service; |
| import org.springframework.transaction.annotation.Transactional; |
| |
| import java.util.*; |
| import java.util.function.Function; |
| import java.util.stream.Collectors; |
| |
| import static org.springframework.ldap.query.LdapQueryBuilder.query; |
| |
| @Log4j2 |
| @Service |
| public class LdapService { |
| |
| @Value("${ldap.enabled}") |
| private Boolean ldapEnabled; |
| |
| @Value("${ldap-sync.attribute-mapping.uid}") |
| private String uid; |
| |
| @Value("${ldap-sync.db-id-mapping.telephone-number-id}") |
| private Long telephoneNumberId; |
| |
| @Value("${ldap-sync.db-id-mapping.mail-id}") |
| private Long mailId; |
| |
| @Autowired |
| LdapUserAttributesMapper ldapUserAttributesMapper; |
| |
| @Autowired |
| private InternalPersonRepository internalPersonRepository; |
| |
| @Autowired |
| private LdapTemplate ldapTemplate; |
| |
| @Autowired |
| private CommunicationTypeRepository communicationTypeRepository; |
| |
| @Autowired |
| CommunicationRepository communicationRepository; |
| |
| /** |
| * Retrieves all the LdapUsers in the ldap server, using {@link LdapUserAttributesMapper} |
| * @return list of LdapUsers |
| */ |
| public List<LdapUser> getAllLdapUsers() { |
| return ldapEnabled.booleanValue() |
| ? ldapTemplate.search(query().where("objectclass").is("person"), ldapUserAttributesMapper) |
| : new ArrayList<>(); |
| } |
| |
| /** |
| * Retrieves the distinct the LdapUsers from the ldap server, using {@link LdapUserAttributesMapper} |
| * @return ldapUsers |
| */ |
| public List<LdapUser> getLdapUserByUID(String uid) { |
| return ldapTemplate.search(query() |
| .where("objectclass").is("person").and(this.uid).is(uid), ldapUserAttributesMapper); |
| } |
| |
| @Transactional |
| public void synchronizeLDAP() { |
| List<TblInternalPerson> internalPersonList = internalPersonRepository.findByUidNotNull(); |
| |
| Map<String, TblInternalPerson> uidToInternalPersonMap = internalPersonList.stream().collect( |
| Collectors.toMap(TblInternalPerson::getUid, Function.identity())); |
| |
| List<LdapUser> allFoundLdapUsers = new ArrayList<>(); |
| List<TblInternalPerson> allNotExistingLdapUsers = new ArrayList<>(); |
| findExistingAndNotExistingLdapUsers(internalPersonList, allFoundLdapUsers, allNotExistingLdapUsers); |
| |
| List<TblInternalPerson> internalPersonListSynchronized = new ArrayList<>(); |
| |
| RefCommunicationType refCommunicationTypeMail = getRefCommunicationType(mailId); |
| RefCommunicationType refCommunicationTypePhone = getRefCommunicationType(telephoneNumberId); |
| |
| for (LdapUser ldapUser : allFoundLdapUsers) { |
| TblInternalPerson tblInternalPerson = uidToInternalPersonMap.get(ldapUser.getUid()); |
| if (tblInternalPerson == null) continue; |
| boolean attributesChanged = mapLdapUserToInternaPerson(tblInternalPerson, ldapUser, refCommunicationTypeMail, refCommunicationTypePhone); |
| if (attributesChanged) { |
| internalPersonListSynchronized.add(tblInternalPerson); |
| } |
| } |
| |
| //Update all not found users notes with the sync error message |
| internalPersonRepository.saveAll(allNotExistingLdapUsers); |
| |
| //Update all found Users with the synchronized LDAP data |
| internalPersonRepository.saveAll(internalPersonListSynchronized); |
| |
| log.info("Synchronization changed data of: " + internalPersonListSynchronized.size() + " internal user/s"); |
| log.info("Attribute/s of the following internal user/s were updated:"); |
| for (TblInternalPerson tblInternalPerson : internalPersonListSynchronized) { |
| log.info("Id: " + tblInternalPerson.getId() + " Firstname: " + tblInternalPerson.getFirstName() + " Lastname: " + tblInternalPerson.getLastName()); |
| } |
| } |
| |
| private RefCommunicationType getRefCommunicationType(Long refCommunicationTypeId) { |
| return communicationTypeRepository.findAll().stream() |
| .filter(x -> x.getId().equals(refCommunicationTypeId)) |
| .findFirst() |
| .orElseThrow(NotFoundException::new); |
| } |
| |
| private void findExistingAndNotExistingLdapUsers(List<TblInternalPerson> internalPersonList, List<LdapUser> allFoundLdapUsers, List<TblInternalPerson> allNotExistingLdapUsers) { |
| for (TblInternalPerson tblInternalPerson : internalPersonList) { |
| String uidTblInternalPerson = tblInternalPerson.getUid(); |
| List<LdapUser> ldapUserByUIDResult = getLdapUserByUID(uidTblInternalPerson); |
| |
| if(ldapUserByUIDResult.isEmpty()){ |
| String errorMsg = String.format("[LDAP Sync Error] User with Uid: [ %s ] can not be found in LDAP", uidTblInternalPerson); |
| setNoteAndLogSyncError(allNotExistingLdapUsers, tblInternalPerson, errorMsg); |
| } |
| else if(ldapUserByUIDResult.size() > 1){ |
| String errorMsg = String.format("[LDAP Sync Error] More than one result for UID: [ %s ] in LDAP", uidTblInternalPerson); |
| setNoteAndLogSyncError(allNotExistingLdapUsers, tblInternalPerson, errorMsg); |
| } |
| else { |
| LdapUser ldapUser = ldapUserByUIDResult.get(0); |
| allFoundLdapUsers.add(ldapUser); |
| } |
| } |
| } |
| |
| private void setNoteAndLogSyncError(List<TblInternalPerson> allNotExistingLdapUsers, TblInternalPerson tblInternalPerson, String errorMsg) { |
| log.error(errorMsg); |
| String note = tblInternalPerson.getContact().getNote(); |
| if (note == null) note = ""; |
| if (!note.contains(errorMsg)) { |
| note = note + System.lineSeparator() + errorMsg; |
| tblInternalPerson.getContact().setNote(note); |
| allNotExistingLdapUsers.add(tblInternalPerson); |
| } |
| } |
| |
| private boolean mapLdapUserToInternaPerson(TblInternalPerson tblInternalPerson, LdapUser ldapUser, RefCommunicationType refCommunicationTypeMail, RefCommunicationType refCommunicationTypePhone) { |
| boolean attributesChanged = false; |
| |
| attributesChanged = isCommunicationDataChangedAndSync(tblInternalPerson, ldapUser.getMail(), refCommunicationTypeMail, attributesChanged, mailId); |
| attributesChanged = isCommunicationDataChangedAndSync(tblInternalPerson, ldapUser.getTelephoneNumber(), refCommunicationTypePhone, attributesChanged, telephoneNumberId); |
| |
| if (!Objects.equals(tblInternalPerson.getFirstName(), ldapUser.getFirstName()) |
| || !Objects.equals(tblInternalPerson.getLastName(), ldapUser.getLastName()) |
| || !Objects.equals(tblInternalPerson.getTitle(), ldapUser.getTitle()) |
| || !Objects.equals(tblInternalPerson.getDepartment(), ldapUser.getDepartment())) { |
| attributesChanged = true; |
| tblInternalPerson.setFirstName(ldapUser.getFirstName()); |
| tblInternalPerson.setLastName(ldapUser.getLastName()); |
| tblInternalPerson.setTitle(ldapUser.getTitle()); |
| tblInternalPerson.setDepartment(ldapUser.getDepartment()); |
| } |
| return attributesChanged; |
| } |
| |
| private boolean isCommunicationDataChangedAndSync(TblInternalPerson tblInternalPerson, String communicationdata, RefCommunicationType refCommunicationType, boolean attributesChanged, Long communicationTypeId) { |
| List<TblCommunication> tblCommunicationList = tblInternalPerson.getContact().getCommunications(); |
| |
| Optional<TblCommunication> optionalTblCommunication = tblCommunicationList.stream() |
| .filter(tblCommunication -> tblCommunication.getRefCommunicationType().getId().equals(communicationTypeId)) |
| .findFirst(); |
| |
| if (optionalTblCommunication.isPresent()) { |
| if (!Objects.equals(optionalTblCommunication.get().getCommunicationData(), communicationdata)){ |
| optionalTblCommunication.get().setCommunicationData(communicationdata); |
| attributesChanged = true; |
| } |
| } else { |
| attributesChanged = createAndSaveNewTblCommunication(tblInternalPerson, communicationdata, refCommunicationType, attributesChanged); |
| } |
| return attributesChanged; |
| } |
| |
| private boolean createAndSaveNewTblCommunication(TblInternalPerson tblInternalPerson, String communicationData, RefCommunicationType refCommunicationType, boolean attributesChanged) { |
| if (StringUtils.isEmpty(communicationData)) return attributesChanged; |
| TblCommunication tblCommunication = new TblCommunication(); |
| tblCommunication.setUuid(UUID.randomUUID()); |
| tblCommunication.setTblContact(tblInternalPerson.getContact()); |
| tblCommunication.setRefCommunicationType(refCommunicationType); |
| tblCommunication.setCommunicationData(communicationData); |
| communicationRepository.save(tblCommunication); |
| tblInternalPerson.getContact().getCommunications().add(tblCommunication); |
| return true; |
| } |
| |
| |
| } |