有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用Microsoft Graph API加载所有联系人有时会丢失/跳过页面

我们有一个应用程序,使用Microsoft Graph API加载存储在帐户中的所有联系人。我们发出的最初调用是https://graph.microsoft.com/v1.0/users/{userPrincipalName}/contacts$count=true&$orderBy=displayName%20ASC&$top=100,但我们使用JavaJDK来实现这一点。然后我们遍历所有页面,并将所有加载的联系人存储在一个集合(本地缓存)中

我们每5分钟使用一个拥有3000多个联系人的帐户执行一次,有时,由于使用$count,我们收到的联系人数与我们加载并存储在本地缓存中的联系人数不匹配

手动验证数字我们可以说,计数总是正确的,但仍有联系人丢失

我们使用以下代码来实现这一点

public List<Contact> loadContacts() {
    Set<Contact> contacts = new TreeSet<>((contact1, contact2) -> StringUtils.compare(contact1.id, contact2.id));

    List<QueryOption> requestOptions = List.of(
            new QueryOption("$count", true),
            new QueryOption("$orderBy", "displayName ASC"),
            new QueryOption("$top", 100)
    );

    ContactCollectionRequestBuilder pageRequestBuilder = null;
    ContactCollectionRequest pageRequest;
    boolean hasNextPage = true;

    while (hasNextPage) {
        // initialize page request
        if (pageRequestBuilder == null) {
            pageRequestBuilder = graphClient.users(userId).contacts();
            pageRequest = pageRequestBuilder.buildRequest(requestOptions);
        } else {
            pageRequest = pageRequestBuilder.buildRequest();
        }

        // load
        ContactCollectionPage contactsPage = pageRequest.get();
        if (contactsPage == null) {
            throw new IllegalStateException("request returned a null page");
        } else {
            contacts.addAll(contactsPage.getCurrentPage());
        }

        // handle next page
        hasNextPage = contactsPage.getNextPage() != null;
        if (hasNextPage) {
            pageRequestBuilder = contactsPage.getNextPage();
        } else if (contactsPage.getCount() != null && !Objects.equals(contactsPage.getCount(), (long) contacts.size())) {
            throw new IllegalStateException(String.format("loaded %d contacts but response indicated %d contacts", contacts.size(), contactsPage.getCount()));
        } else {
            // done
        }
    }

    log.info("{} contacts loaded using graph API", contacts.size());

    return new ArrayList<>(contacts);
}

最初,我们没有把加载的联系人放在Set by ID中,而是放在一个列表中。有了这个列表,我们的联系人通常比$count多。我的想法是,有一些缓存正在进行,一些页面被多次获取。使用该集合,我们可以确保本地缓存中只有唯一的联系人

但是使用这个集合,我们有时的联系人少于$count,这意味着一些页面被跳过,我们最终处于抛出IllegalStateException的状态

目前,我们使用microsoft graph 5.8.0和azure identiy 1.4.2

您是否遇到过类似的问题,可以帮助我们解决这个问题? 或者你知道是什么导致了这些不一致的结果吗

非常感谢你的帮助


共 (0) 个答案