Как связать всех пользователей с пользователем (прямо или косвенно) - PullRequest
1 голос
/ 12 июля 2020

У меня проблема, когда мне нужно получить всех пользователей, связанных с пользователем, с помощью настраиваемого свойства LDAP, на данный момент я могу добиться этого только с помощью рекурсивной функции с запросом, который будет расти с каждым вызовом, я знаю это не масштабируется, есть ли лучший способ добиться этого.

это код, который я использую.

/*
 * at start accumlatedUsers === usersToBeSearched accumlatedUsers will be
 * updated
 */
public void GetSubordinatesRecurisve(ArrayList<String> usersToBeSearched, ArrayList<String> accumlatedUsers)
        throws NamingException {

    String searchFilter = "(&(ObjectCategory=User)(|";
    for (String user : usersToBeSearched) {
        searchFilter += "(supeirorName=" + user + ")";
    }
    searchFilter += "))";

    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    NamingEnumeration<SearchResult> results = ldapContext.search(ldapSearchBase, searchFilter, searchControls);

    ArrayList<String> usersFounded = new ArrayList<String>();
    SearchResult searchResult = null;
    while (results.hasMoreElements()) {
        searchResult = (SearchResult) results.nextElement();
        usersFounded.add((String) searchResult.getAttributes().get("sAMAccountName").get());
    }

    accumlatedUsers.addAll(usersFounded);

    if (usersFounded.size() != 0) {
        this.GetSubordinatesRecurisve(usersFounded, accumlatedUsers);
    }

    return;
}

спасибо.

1 Ответ

1 голос
/ 12 июля 2020

Да, проблема в том, что количество пользователей в вашем запросе ldapContext.search будет расти экспоненциально, поэтому он вообще не масштабируется. Например, 1-й запрос предназначен для 1 пользователя, 2-й запрос - для 3 пользователей, 3-й запрос для 9 пользователей и т. Д.

Пользователи, относящиеся к одному пользователю, можно увидеть в виде дерева (если нет циклы). Наиболее распространенный способ обхода дерева - это алгоритм глубокого поиска (DFS) или поиска по хлебу (BFS). Если ваша цель - найти ВСЕ пользователей, связанных с пользователем, тогда подойдет любой вариант.

DFS (или BFS) более масштабируемый, чем ваше решение, потому что он всегда будет запрашивать LDAP с 1 пользователя за раз.

Я не могу протестировать ваш метод, но я показываю вам, как можно реализовать DFS:

// ...
accumlatedUsers.addAll(usersFounded);

for(String userFounded : usersFounded){
    if(!visited.contains(userFounded)){
        visited.add(userFounded);
        List<String> singleUserList = new ArrayList<>();
        singleUserList.add(userFounded);
        this.GetSubordinatesRecurisve(singleUserList, accumlatedUsers);
    }
}

return;

Примечание список посещенных, он предназначен для предотвращения циклы в вашем графике пользователей.

...