Search in sources :

Example 1 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class VosManagerBlImpl method findCandidates.

public List<Candidate> findCandidates(PerunSession sess, Vo vo, String searchString, int maxNumOfResults) throws InternalErrorException {
    List<Candidate> candidates = new ArrayList<Candidate>();
    int numOfResults = 0;
    try {
        // Iterate through all registered extSources
        for (ExtSource source : getPerunBl().getExtSourcesManagerBl().getVoExtSources(sess, vo)) {
            // Info if this is only simple ext source, change behavior if not
            boolean simpleExtSource = true;
            // Get potential subjects from the extSource
            List<Map<String, String>> subjects;
            try {
                if (source instanceof ExtSourceApi) {
                    // find subjects with all their properties
                    subjects = ((ExtSourceApi) source).findSubjects(searchString, maxNumOfResults);
                    simpleExtSource = false;
                } else {
                    // find subjects only with logins - they then must be retrieved by login
                    subjects = ((ExtSourceSimpleApi) source).findSubjectsLogins(searchString, maxNumOfResults);
                }
            } catch (ExtSourceUnsupportedOperationException e1) {
                log.warn("ExtSource {} doesn't support findSubjects", source.getName());
                continue;
            } catch (InternalErrorException e) {
                log.error("Error occurred on ExtSource {},  Exception {}.", source.getName(), e);
                continue;
            } finally {
                try {
                    ((ExtSourceSimpleApi) source).close();
                } catch (ExtSourceUnsupportedOperationException e) {
                // ExtSource doesn't support that functionality, so silently skip it.
                } catch (InternalErrorException e) {
                    log.error("Can't close extSource connection. Cause: {}", e);
                }
            }
            Set<String> uniqueLogins = new HashSet<>();
            for (Map<String, String> s : subjects) {
                // Check if the user has unique identifier within extSource
                if ((s.get("login") == null) || (s.get("login") != null && ((String) s.get("login")).isEmpty())) {
                    log.error("User '{}' cannot be added, because he/she doesn't have a unique identifier (login)", s);
                    // Skip to another user
                    continue;
                }
                String extLogin = (String) s.get("login");
                // check uniqueness of every login in extSource
                if (uniqueLogins.contains(extLogin)) {
                    throw new InternalErrorException("There are more than 1 login '" + extLogin + "' getting from extSource '" + source + "'");
                } else {
                    uniqueLogins.add(extLogin);
                }
                // Get Candidate
                Candidate candidate;
                try {
                    if (simpleExtSource) {
                        // retrieve data about subjects from ext source based on ext. login
                        candidate = getPerunBl().getExtSourcesManagerBl().getCandidate(sess, source, extLogin);
                    } else {
                        // retrieve data about subjects from subjects we already have locally
                        candidate = getPerunBl().getExtSourcesManagerBl().getCandidate(sess, s, source, extLogin);
                    }
                } catch (ExtSourceNotExistsException e) {
                    throw new ConsistencyErrorException("Getting candidate from non-existing extSource " + source, e);
                } catch (CandidateNotExistsException e) {
                    throw new ConsistencyErrorException("findSubjects returned that candidate, but getCandidate cannot find him using login " + extLogin, e);
                } catch (ExtSourceUnsupportedOperationException e) {
                    throw new InternalErrorException("extSource supports findSubjects but not getCandidate???", e);
                }
                try {
                    getPerunBl().getMembersManagerBl().getMemberByUserExtSources(sess, vo, candidate.getUserExtSources());
                    // Candidate is already a member of the VO, so do not add him to the list of candidates
                    continue;
                } catch (MemberNotExistsException e) {
                // This is OK
                }
                // Add candidate to the list of candidates
                log.debug("findCandidates: returning candidate: {}", candidate);
                candidates.add(candidate);
                numOfResults++;
                // Stop getting new members if the number of already retrieved members exceeded the maxNumOfResults
                if (maxNumOfResults > 0 && numOfResults >= maxNumOfResults) {
                    break;
                }
            }
            // Stop walking through next sources if the number of already retrieved members exceeded the maxNumOfResults
            if (maxNumOfResults > 0 && numOfResults >= maxNumOfResults) {
                break;
            }
        }
        log.debug("Returning {} potential members for vo {}", candidates.size(), vo);
        return candidates;
    } catch (RuntimeException e) {
        throw new InternalErrorException(e);
    }
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) ConsistencyErrorException(cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException) MemberNotExistsException(cz.metacentrum.perun.core.api.exceptions.MemberNotExistsException) ArrayList(java.util.ArrayList) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) ExtSourceApi(cz.metacentrum.perun.core.implApi.ExtSourceApi) ExtSource(cz.metacentrum.perun.core.api.ExtSource) ExtSourceUnsupportedOperationException(cz.metacentrum.perun.core.api.exceptions.ExtSourceUnsupportedOperationException) ExtSourceNotExistsException(cz.metacentrum.perun.core.api.exceptions.ExtSourceNotExistsException) Map(java.util.Map) ExtSourceSimpleApi(cz.metacentrum.perun.core.implApi.ExtSourceSimpleApi) HashSet(java.util.HashSet) CandidateNotExistsException(cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)

Example 2 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class GroupsManagerBlImpl method synchronizeGroup.

@Override
public List<String> synchronizeGroup(PerunSession sess, Group group) throws AttributeNotExistsException, WrongAttributeAssignmentException, ExtSourceNotExistsException, GroupNotExistsException {
    // needed variables for whole method
    List<String> skippedMembers = new ArrayList<>();
    ExtSource source = null;
    ExtSource membersSource = null;
    try {
        // set Logback's Mapped Diagnostic Context key for the current thread
        MDC.put(MDC_LOG_FILE_NAME, "groupsync/group_" + group.getId());
        long startTime = System.nanoTime();
        getPerunBl().getAuditer().log(sess, new GroupSyncStarted(group));
        log.debug("Group synchronization for {} has been started.", group);
        // Initialization of group extSource
        source = getGroupExtSourceForSynchronization(sess, group);
        // Initialization of groupMembers extSource (if it is set), in other case set membersSource = source
        membersSource = getGroupMembersExtSourceForSynchronization(sess, group, source);
        // Prepare info about userAttributes which need to be overwritten (not just updated) and memberAttributes which need to be merged not overwritten
        List<String> overwriteUserAttributesList = getAttributesListFromExtSource(membersSource, OVERWRITE_USER_ATTRIBUTES);
        List<String> mergeMemberAttributesList = getAttributesListFromExtSource(membersSource, MERGE_MEMBER_ATTRIBUTES);
        // Get info about type of synchronization (with or without update)
        boolean lightweightSynchronization = isThisLightweightSynchronization(sess, group);
        log.debug("Group synchronization {}: using configuration extSource for membership {}, extSource for members {}", group, membersSource, membersSource.getName());
        // Prepare containers for work with group members
        List<Candidate> candidatesToAdd = new ArrayList<>();
        Map<Candidate, RichMember> membersToUpdate = new HashMap<>();
        List<RichMember> membersToRemove = new ArrayList<>();
        // get all direct members of synchronized group (only direct, because we want to set direct membership with this group by synchronization)
        List<RichMember> actualGroupMembers = getPerunBl().getGroupsManagerBl().getGroupDirectRichMembers(sess, group);
        if (lightweightSynchronization) {
            categorizeMembersForLightweightSynchronization(sess, group, source, membersSource, actualGroupMembers, candidatesToAdd, membersToRemove, skippedMembers);
        } else {
            // Get subjects from extSource
            List<Map<String, String>> subjects = getSubjectsFromExtSource(sess, source, group);
            // Convert subjects to candidates
            List<Candidate> candidates = convertSubjectsToCandidates(sess, subjects, membersSource, source, actualGroupMembers, skippedMembers);
            categorizeMembersForSynchronization(sess, actualGroupMembers, candidates, candidatesToAdd, membersToUpdate, membersToRemove);
        }
        // Remove members from group who are not present in synchronized ExtSource
        boolean isAuthoritative = isAuthoritative(sess, group);
        Collections.sort(membersToRemove);
        for (RichMember memberToRemove : membersToRemove) {
            removeFormerMemberWhileSynchronization(sess, group, memberToRemove, isAuthoritative);
        }
        List<AttributeDefinition> attrDefs = new ArrayList<>();
        // Update members already presented in group
        for (Candidate candidate : membersToUpdate.keySet()) {
            RichMember memberToUpdate = membersToUpdate.get(candidate);
            // Load attrDefinitions just once for first candidate
            if (!candidate.getAttributes().isEmpty() && attrDefs.isEmpty()) {
                attrDefs = getAttributesToSynchronizeFromCandidates(sess, group, candidate);
            }
            updateExistingMemberWhileSynchronization(sess, group, candidate, memberToUpdate, overwriteUserAttributesList, mergeMemberAttributesList, attrDefs);
        }
        // Add not presented candidates to group
        Collections.sort(candidatesToAdd);
        for (Candidate candidateToAdd : candidatesToAdd) {
            addMissingMemberWhileSynchronization(sess, group, candidateToAdd, overwriteUserAttributesList, mergeMemberAttributesList, skippedMembers);
        }
        long endTime = System.nanoTime();
        getPerunBl().getAuditer().log(sess, new GroupSyncFinished(group, startTime, endTime));
        log.info("Group synchronization for {} has been finished.", group);
    } finally {
        closeExtSourcesAfterSynchronization(membersSource, source);
        MDC.remove(MDC_LOG_FILE_NAME);
    }
    return skippedMembers;
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) GroupSyncFinished(cz.metacentrum.perun.audit.events.GroupManagerEvents.GroupSyncFinished) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AttributeDefinition(cz.metacentrum.perun.core.api.AttributeDefinition) GroupSyncStarted(cz.metacentrum.perun.audit.events.GroupManagerEvents.GroupSyncStarted) RichMember(cz.metacentrum.perun.core.api.RichMember) RichUserExtSource(cz.metacentrum.perun.core.api.RichUserExtSource) ExtSource(cz.metacentrum.perun.core.api.ExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap)

Example 3 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class GroupsManagerBlImpl method categorizeMembersForSynchronization.

/**
 * This method fill 3 member structures which get as parameters:
 * 1. membersToUpdate - Candidates with equivalent Members from Perun for purpose of updating attributes and statuses
 * 2. candidateToAdd - New members of the group
 * 3. membersToRemove - Former members who are not in synchronized ExtSource now
 *
 * @param sess
 * @param groupMembers current group members
 * @param candidates to be synchronized from extSource
 * @param membersToUpdate 1. container (more above)
 * @param candidatesToAdd 2. container (more above)
 * @param membersToRemove 3. container (more above)
 */
private void categorizeMembersForSynchronization(PerunSession sess, List<RichMember> groupMembers, List<Candidate> candidates, List<Candidate> candidatesToAdd, Map<Candidate, RichMember> membersToUpdate, List<RichMember> membersToRemove) {
    candidatesToAdd.addAll(candidates);
    membersToRemove.addAll(groupMembers);
    // mapping structure for more efficient searching
    Map<UserExtSource, RichMember> mappingStructure = this.createMappingStructure(groupMembers);
    // try to find already existing candidates between members in group
    for (Candidate candidate : candidates) {
        List<UserExtSource> candidateExtSources = candidate.getUserExtSources();
        for (UserExtSource key : candidateExtSources) {
            // candidate exists, will be updated
            if (mappingStructure.containsKey(key)) {
                membersToUpdate.put(candidate, mappingStructure.get(key));
                candidatesToAdd.remove(candidate);
                membersToRemove.remove(mappingStructure.get(key));
                break;
            }
        }
    }
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) RichUserExtSource(cz.metacentrum.perun.core.api.RichUserExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) RichMember(cz.metacentrum.perun.core.api.RichMember)

Example 4 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class ServicesManagerEntryIntegrationTest method setUpMemberInVo2.

private Member setUpMemberInVo2(Vo vo2) throws Exception {
    String userFirstName = Long.toHexString(Double.doubleToLongBits(Math.random()));
    String userLastName = Long.toHexString(Double.doubleToLongBits(Math.random()));
    // his login in external source
    String extLogin = Long.toHexString(Double.doubleToLongBits(Math.random()));
    Candidate candidate;
    // Mockito.mock(Candidate.class);
    candidate = new Candidate();
    candidate.setFirstName(userFirstName);
    candidate.setId(0);
    candidate.setMiddleName("");
    candidate.setLastName(userLastName);
    candidate.setTitleBefore("");
    candidate.setTitleAfter("");
    UserExtSource ues = new UserExtSource(new ExtSource(0, "testExtSource", "cz.metacentrum.perun.core.impl.ExtSourceInternal"), extLogin);
    candidate.setUserExtSource(ues);
    candidate.setAttributes(new HashMap<>());
    Member createdMember = perun.getMembersManagerBl().createMemberSync(sess, vo2, candidate);
    assertNotNull("No member created", createdMember);
    usersForDeletion.add(perun.getUsersManager().getUserByMember(sess, createdMember));
    // save user for deletion after test
    return createdMember;
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) ExtSource(cz.metacentrum.perun.core.api.ExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) Member(cz.metacentrum.perun.core.api.Member)

Example 5 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class UsersManagerEntryIntegrationTest method testCreateServiceUserSetsUes.

@Test
public void testCreateServiceUserSetsUes() throws Exception {
    System.out.println(CLASS_NAME + "testCreateServiceUserSetsUes");
    Candidate candidate = setUpCandidateForSpecificUser1();
    User createdUser = usersManager.createServiceUser(sess, candidate, Collections.emptyList());
    UserExtSource candidateUes = candidate.getUserExtSource();
    User userByUes = usersManager.getUserByExtSourceNameAndExtLogin(sess, candidateUes.getExtSource().getName(), candidateUes.getLogin());
    assertThat(createdUser).isEqualByComparingTo(userByUes);
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) User(cz.metacentrum.perun.core.api.User) RichUser(cz.metacentrum.perun.core.api.RichUser) RichUserExtSource(cz.metacentrum.perun.core.api.RichUserExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) AbstractPerunIntegrationTest(cz.metacentrum.perun.core.AbstractPerunIntegrationTest) Test(org.junit.Test)

Aggregations

Candidate (cz.metacentrum.perun.core.api.Candidate)100 UserExtSource (cz.metacentrum.perun.core.api.UserExtSource)52 Test (org.junit.Test)41 Member (cz.metacentrum.perun.core.api.Member)37 AbstractPerunIntegrationTest (cz.metacentrum.perun.core.AbstractPerunIntegrationTest)30 ExtSource (cz.metacentrum.perun.core.api.ExtSource)25 RichMember (cz.metacentrum.perun.core.api.RichMember)24 User (cz.metacentrum.perun.core.api.User)23 HashMap (java.util.HashMap)23 ArrayList (java.util.ArrayList)21 Group (cz.metacentrum.perun.core.api.Group)15 Attribute (cz.metacentrum.perun.core.api.Attribute)14 Map (java.util.Map)12 MemberCandidate (cz.metacentrum.perun.core.api.MemberCandidate)11 RichUser (cz.metacentrum.perun.core.api.RichUser)11 Vo (cz.metacentrum.perun.core.api.Vo)11 LinkedHashMap (java.util.LinkedHashMap)11 RichUserExtSource (cz.metacentrum.perun.core.api.RichUserExtSource)9 InternalErrorException (cz.metacentrum.perun.core.api.exceptions.InternalErrorException)9 CandidateNotExistsException (cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)8