From 5deac7137d61c73984a93e269f391634db43bb4d Mon Sep 17 00:00:00 2001 From: santifuhuo <38684365+santifuhuo@users.noreply.github.com> Date: Wed, 31 Jul 2024 07:32:20 +0800 Subject: [PATCH] Fix the `query/count groups` admin API respond with wrong groups if `memberIds` is specified Fix the `query/count groups` admin API respond with wrong groups if `memberIds` is specified --------- Co-authored-by: sunleiz Co-authored-by: JamesChenX --- .../infra/collection/CollectionUtil.java | 18 +++- .../repository/GroupMemberRepository.java | 4 +- .../group/service/GroupMemberService.java | 5 +- .../domain/group/service/GroupService.java | 92 ++++++++++++------- 4 files changed, 78 insertions(+), 41 deletions(-) diff --git a/turms-server-common/src/main/java/im/turms/server/common/infra/collection/CollectionUtil.java b/turms-server-common/src/main/java/im/turms/server/common/infra/collection/CollectionUtil.java index f9164570ee..79f06d156b 100644 --- a/turms-server-common/src/main/java/im/turms/server/common/infra/collection/CollectionUtil.java +++ b/turms-server-common/src/main/java/im/turms/server/common/infra/collection/CollectionUtil.java @@ -665,7 +665,12 @@ public static Map deepMerge( // region intersection/union public static Set intersection(Set c1, Collection c2) { - Set result = newSetWithExpectedSize(Math.min(c1.size(), c2.size())); + int size1 = c1.size(); + int size2 = c2.size(); + if (size1 == 0 || size2 == 0) { + return Collections.emptySet(); + } + Set result = newSetWithExpectedSize(Math.min(size1, size2)); for (T value : c2) { if (c1.contains(value)) { result.add(value); @@ -674,8 +679,15 @@ public static Set intersection(Set c1, Collection c2) { return result; } - public static List union(List list1, List list2) { - ArrayList result = new ArrayList<>(list1.size() + list2.size()); + public static List union(List list1, List list2) { + int size1 = list1.size(); + int size2 = list2.size(); + if (size1 == 0) { + return list2; + } else if (size2 == 0) { + return list1; + } + ArrayList result = new ArrayList<>(size1 + size2); result.addAll(list1); result.addAll(list2); return result; diff --git a/turms-service/src/main/java/im/turms/service/domain/group/repository/GroupMemberRepository.java b/turms-service/src/main/java/im/turms/service/domain/group/repository/GroupMemberRepository.java index 7739bad6c6..844a60ecd9 100644 --- a/turms-service/src/main/java/im/turms/service/domain/group/repository/GroupMemberRepository.java +++ b/turms-service/src/main/java/im/turms/service/domain/group/repository/GroupMemberRepository.java @@ -204,10 +204,12 @@ public Flux findUserJoinedGroupIds(Long userId) { } public Flux findUsersJoinedGroupIds( + @Nullable Set groupIds, @NotEmpty Set userIds, @Nullable Integer page, @Nullable Integer size) { - Filter filter = Filter.newBuilder(1) + Filter filter = Filter.newBuilder(2) + .inIfNotNull(GroupMember.Fields.ID_GROUP_ID, groupIds) .inIfNotNull(GroupMember.Fields.ID_USER_ID, userIds); QueryOptions options = QueryOptions.newBuilder(3) .paginateIfNotNull(page, size) diff --git a/turms-service/src/main/java/im/turms/service/domain/group/service/GroupMemberService.java b/turms-service/src/main/java/im/turms/service/domain/group/service/GroupMemberService.java index 59572a514c..b1d564a224 100644 --- a/turms-service/src/main/java/im/turms/service/domain/group/service/GroupMemberService.java +++ b/turms-service/src/main/java/im/turms/service/domain/group/service/GroupMemberService.java @@ -884,6 +884,7 @@ public Flux queryUserJoinedGroupIds(@NotNull Long userId) { } public Flux queryUsersJoinedGroupIds( + @Nullable Set groupIds, @NotEmpty Set userIds, @Nullable Integer page, @Nullable Integer size) { @@ -892,7 +893,7 @@ public Flux queryUsersJoinedGroupIds( } catch (ResponseException e) { return Flux.error(e); } - return groupMemberRepository.findUsersJoinedGroupIds(userIds, page, size); + return groupMemberRepository.findUsersJoinedGroupIds(groupIds, userIds, page, size); } public Mono> queryMemberIdsInUsersJoinedGroups( @@ -904,7 +905,7 @@ public Mono> queryMemberIdsInUsersJoinedGroups( return Mono.error(e); } Recyclable> recyclableSet = SetRecycler.obtain(); - return queryUsersJoinedGroupIds(userIds, null, null) + return queryUsersJoinedGroupIds(null, userIds, null, null) .collect(Collectors.toCollection(recyclableSet::getValue)) .flatMap(groupIds -> groupIds.isEmpty() ? PublisherPool.emptySet() diff --git a/turms-service/src/main/java/im/turms/service/domain/group/service/GroupService.java b/turms-service/src/main/java/im/turms/service/domain/group/service/GroupService.java index 42fdc6d553..b825fbb7dd 100644 --- a/turms-service/src/main/java/im/turms/service/domain/group/service/GroupService.java +++ b/turms-service/src/main/java/im/turms/service/domain/group/service/GroupService.java @@ -389,19 +389,35 @@ public Flux queryGroups( @Nullable Set memberIds, @Nullable Integer page, @Nullable Integer size) { - return queryGroupIdsFromGroupIdsAndMemberIds(ids, memberIds) - .defaultIfEmpty(Collections.emptySet()) - .flatMapMany(groupIds -> groupRepository.findGroups(groupIds, - typeIds, - creatorIds, - ownerIds, - isActive, - creationDateRange, - deletionDateRange, - lastUpdatedDateRange, - muteEndDateRange, - page, - size)); + if (CollectionUtil.isEmpty(memberIds)) { + return groupRepository.findGroups(ids, + typeIds, + creatorIds, + ownerIds, + isActive, + creationDateRange, + deletionDateRange, + lastUpdatedDateRange, + muteEndDateRange, + page, + size); + } + return queryGroupIdsFromGroupIdsAndMemberIds(ids, memberIds).flatMapMany(groupIds -> { + if (groupIds.isEmpty()) { + return Flux.empty(); + } + return groupRepository.findGroups(groupIds, + typeIds, + creatorIds, + ownerIds, + isActive, + creationDateRange, + deletionDateRange, + lastUpdatedDateRange, + muteEndDateRange, + page, + size); + }); } /** @@ -1133,17 +1149,31 @@ public Mono countGroups( @Nullable DateRange lastUpdatedDateRange, @Nullable DateRange muteEndDateRange, @Nullable Set memberIds) { - return queryGroupIdsFromGroupIdsAndMemberIds(ids, memberIds) - .defaultIfEmpty(Collections.emptySet()) - .flatMap(groupIds -> groupRepository.countGroups(groupIds, - typeIds, - creatorIds, - ownerIds, - isActive, - creationDateRange, - deletionDateRange, - lastUpdatedDateRange, - muteEndDateRange)); + if (CollectionUtil.isEmpty(memberIds)) { + return groupRepository.countGroups(ids, + typeIds, + creatorIds, + ownerIds, + isActive, + creationDateRange, + deletionDateRange, + lastUpdatedDateRange, + muteEndDateRange); + } + return queryGroupIdsFromGroupIdsAndMemberIds(ids, memberIds).flatMap(groupIds -> { + if (groupIds.isEmpty()) { + return PublisherPool.LONG_ZERO; + } + return groupRepository.countGroups(groupIds, + typeIds, + creatorIds, + ownerIds, + isActive, + creationDateRange, + deletionDateRange, + lastUpdatedDateRange, + muteEndDateRange); + }); } public Mono countDeletedGroups(@Nullable DateRange dateRange) { @@ -1174,20 +1204,12 @@ public Mono isGroupActiveAndNotDeleted(@NotNull Long groupId) { private Mono> queryGroupIdsFromGroupIdsAndMemberIds( @Nullable Set groupIds, - @Nullable Set memberIds) { - if (CollectionUtil.isEmpty(memberIds)) { - return CollectionUtil.isEmpty(groupIds) - ? PublisherPool.emptySet() - : Mono.just(groupIds); - } + @NotEmpty Set memberIds) { Recyclable> recyclableList = ListRecycler.obtain(); Mono> joinedGroupIdListMono = - groupMemberService.queryUsersJoinedGroupIds(memberIds, null, null) + groupMemberService.queryUsersJoinedGroupIds(groupIds, memberIds, null, null) .collect(Collectors.toCollection(recyclableList::getValue)); - return (groupIds == null - ? joinedGroupIdListMono.map(CollectionUtil::newSet) - : joinedGroupIdListMono - .map(groupIdList -> CollectionUtil.newSet(groupIdList, groupIds))) + return joinedGroupIdListMono.map(CollectionUtil::newSet) .doFinally(signalType -> recyclableList.recycle()); }