From 548a3a33b7594a59e3941829bb8c9d7d5c3a1c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radoslav=20=C4=8Cerh=C3=A1k?= Date: Wed, 31 Mar 2021 13:48:15 +0200 Subject: [PATCH] Core - new methods for group stats - New methods were added to Core, RPC and OpenAPI: getGroupMembersCountsByVoStatus and getGroupMembersCountsByGroupStatus. They return a map with (group / VO) member status as key, and count of the group members with the status as value. --- perun-base/src/main/resources/perun-roles.yml | 20 +++++++ .../perun/core/api/GroupsManager.java | 22 ++++++++ .../perun/core/bl/GroupsManagerBl.java | 18 +++++++ .../core/blImpl/GroupsManagerBlImpl.java | 26 +++++++++ .../perun/core/entry/GroupsManagerEntry.java | 26 +++++++++ .../GroupsManagerEntryIntegrationTest.java | 54 +++++++++++++++++++ perun-openapi/openapi.yml | 37 +++++++++++++ .../rpc/methods/GroupsManagerMethod.java | 40 ++++++++++++++ 8 files changed, 243 insertions(+) diff --git a/perun-base/src/main/resources/perun-roles.yml b/perun-base/src/main/resources/perun-roles.yml index 5f3b04de68..19cf6e12c8 100644 --- a/perun-base/src/main/resources/perun-roles.yml +++ b/perun-base/src/main/resources/perun-roles.yml @@ -1456,6 +1456,26 @@ perun_policies: include_policies: - default_policy + getGroupMembersCountsByVoStatus_Group_policy: + policy_roles: + - PERUNOBSERVER: + - VOOBSERVER: Vo + - GROUPADMIN: Group + - GROUPOBSERVER: Group + - VOADMIN: Vo + include_policies: + - default_policy + + getGroupMembersCountsByGroupStatus_Group_policy: + policy_roles: + - PERUNOBSERVER: + - VOOBSERVER: Vo + - GROUPADMIN: Group + - GROUPOBSERVER: Group + - VOADMIN: Vo + include_policies: + - default_policy + addAdmin_Group_User_policy: policy_roles: - GROUPADMIN: Group diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/api/GroupsManager.java b/perun-core/src/main/java/cz/metacentrum/perun/core/api/GroupsManager.java index 06b589d852..cf9033e48b 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/api/GroupsManager.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/api/GroupsManager.java @@ -564,6 +564,28 @@ public interface GroupsManager { */ int getGroupMembersCount(PerunSession perunSession, Group group) throws GroupNotExistsException, PrivilegeException; + /** + * Returns counts of group members by their status in VO. + * + * @param sess + * @param group + * @return map of member status in VO to count of group members with the status + * @throws GroupNotExistsException when the group doesn't exist + * @throws PrivilegeException + */ + Map getGroupMembersCountsByVoStatus(PerunSession sess, Group group) throws GroupNotExistsException, PrivilegeException; + + /** + * Returns counts of group members by their group status. + * + * @param sess + * @param group + * @return map of member status in group to count of group members with the status + * @throws GroupNotExistsException when the group doesn't exist + * @throws PrivilegeException + */ + Map getGroupMembersCountsByGroupStatus(PerunSession sess, Group group) throws GroupNotExistsException, PrivilegeException; + /** * Get groups of Vo by ACCESS RIGHTS: * If user is: diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/bl/GroupsManagerBl.java b/perun-core/src/main/java/cz/metacentrum/perun/core/bl/GroupsManagerBl.java index 4d5c2750ba..162c3cbcb3 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/bl/GroupsManagerBl.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/bl/GroupsManagerBl.java @@ -655,6 +655,24 @@ public interface GroupsManagerBl { */ int getGroupMembersCount(PerunSession perunSession, Group group); + /** + * Returns counts of group members by their status in VO. + * + * @param sess + * @param group + * @return map of member status in VO to count of group members with the status + */ + Map getGroupMembersCountsByVoStatus(PerunSession sess, Group group); + + /** + * Returns counts of group members by their group status. + * + * @param sess + * @param group + * @return map of member status in group to count of group members with the status + */ + Map getGroupMembersCountsByGroupStatus(PerunSession sess, Group group); + /** * Checks whether the user is member of the group. * diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/GroupsManagerBlImpl.java b/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/GroupsManagerBlImpl.java index edad1caaf5..8a82487be3 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/GroupsManagerBlImpl.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/GroupsManagerBlImpl.java @@ -1297,6 +1297,32 @@ public int getGroupMembersCount(PerunSession sess, Group group) { return members.size(); } + @Override + public Map getGroupMembersCountsByVoStatus(PerunSession sess, Group group) { + List members = this.getGroupMembers(sess, group); + + Map counts = new HashMap<>(); + for (Status status : Status.values()) { + counts.put(status, 0); + } + members.forEach(member -> counts.computeIfPresent(member.getStatus(), (key, value) -> value + 1)); + + return counts; + } + + @Override + public Map getGroupMembersCountsByGroupStatus(PerunSession sess, Group group) { + List members = this.getGroupMembers(sess, group); + + Map counts = new HashMap<>(); + for (MemberGroupStatus status : MemberGroupStatus.values()) { + counts.put(status, 0); + } + members.forEach(member -> counts.computeIfPresent(member.getGroupStatus(), (key, value) -> value + 1)); + + return counts; + } + @Override public List getAdmins(PerunSession perunSession, Group group, boolean onlyDirectAdmins) { if(onlyDirectAdmins) { diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/entry/GroupsManagerEntry.java b/perun-core/src/main/java/cz/metacentrum/perun/core/entry/GroupsManagerEntry.java index c5d212b782..8f08a9db4a 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/entry/GroupsManagerEntry.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/entry/GroupsManagerEntry.java @@ -621,6 +621,32 @@ public int getGroupMembersCount(PerunSession sess, Group group) throws GroupNotE return getGroupsManagerBl().getGroupMembersCount(sess, group); } + @Override + public Map getGroupMembersCountsByVoStatus(PerunSession sess, Group group) throws GroupNotExistsException, PrivilegeException { + Utils.checkPerunSession(sess); + getGroupsManagerBl().checkGroupExists(sess, group); + + // Authorization + if (!AuthzResolver.authorizedInternal(sess, "getGroupMembersCountsByVoStatus_Group_policy", group)) { + throw new PrivilegeException(sess, "getGroupMembersCountsByVoStatus"); + } + + return getGroupsManagerBl().getGroupMembersCountsByVoStatus(sess, group); + } + + @Override + public Map getGroupMembersCountsByGroupStatus(PerunSession sess, Group group) throws GroupNotExistsException, PrivilegeException { + Utils.checkPerunSession(sess); + getGroupsManagerBl().checkGroupExists(sess, group); + + // Authorization + if (!AuthzResolver.authorizedInternal(sess, "getGroupMembersCountsByGroupStatus_Group_policy", group)) { + throw new PrivilegeException(sess, "getGroupMembersCountsByGroupStatus"); + } + + return getGroupsManagerBl().getGroupMembersCountsByGroupStatus(sess, group); + } + @Override public void addAdmin(PerunSession sess, Group group, User user) throws AlreadyAdminException, PrivilegeException, GroupNotExistsException, UserNotExistsException, RoleCannotBeManagedException { Utils.checkPerunSession(sess); diff --git a/perun-core/src/test/java/cz/metacentrum/perun/core/entry/GroupsManagerEntryIntegrationTest.java b/perun-core/src/test/java/cz/metacentrum/perun/core/entry/GroupsManagerEntryIntegrationTest.java index 12dc6e89ca..57182b0449 100644 --- a/perun-core/src/test/java/cz/metacentrum/perun/core/entry/GroupsManagerEntryIntegrationTest.java +++ b/perun-core/src/test/java/cz/metacentrum/perun/core/entry/GroupsManagerEntryIntegrationTest.java @@ -3004,6 +3004,60 @@ public void getGroupMembersCountWhenGroupNotExists() throws Exception { } + @Test + public void getGroupMembersCountsByVoStatus() throws Exception { + System.out.println(CLASS_NAME + "getGroupMembersCountsByVoStatus"); + + vo = setUpVo(); + setUpGroup(vo); + + Member member = setUpMember(vo); + groupsManager.addMember(sess, group, member); + + Member disabledMember = setUpMember(vo); + groupsManager.addMember(sess, group, disabledMember); + perun.getMembersManager().setStatus(sess, disabledMember, Status.DISABLED); + + Map counts = groupsManager.getGroupMembersCountsByVoStatus(sess, group); + assertThat(counts.get(Status.VALID)).isEqualTo(1); + assertThat(counts.get(Status.DISABLED)).isEqualTo(1); + assertThat(counts.get(Status.INVALID)).isEqualTo(0); + assertThat(counts.get(Status.EXPIRED)).isEqualTo(0); + } + + @Test (expected=GroupNotExistsException.class) + public void getGroupMembersCountsByVoStatusWhenGroupNotExists() throws Exception { + System.out.println(CLASS_NAME + "getGroupMembersCountsByVoStatusWhenGroupNotExists"); + + groupsManager.getGroupMembersCountsByVoStatus(sess, new Group()); + } + + @Test + public void getGroupMembersCountsByGroupStatus() throws Exception { + System.out.println(CLASS_NAME + "getGroupMembersCountsByGroupStatus"); + + vo = setUpVo(); + setUpGroup(vo); + + Member member = setUpMember(vo); + groupsManager.addMember(sess, group, member); + + Member expiredMember = setUpMember(vo); + groupsManager.addMember(sess, group, expiredMember); + groupsManager.setMemberGroupStatus(sess, expiredMember, group, MemberGroupStatus.EXPIRED); + + Map counts = groupsManager.getGroupMembersCountsByGroupStatus(sess, group); + assertThat(counts.get(MemberGroupStatus.VALID)).isEqualTo(1); + assertThat(counts.get(MemberGroupStatus.EXPIRED)).isEqualTo(1); + } + + @Test (expected=GroupNotExistsException.class) + public void getGroupMembersCountsByGroupStatusWhenGroupNotExists() throws Exception { + System.out.println(CLASS_NAME + "getGroupMembersCountsByGroupStatusWhenGroupNotExists"); + + groupsManager.getGroupMembersCountsByGroupStatus(sess, new Group()); + } + @Test public void getAllGroups() throws Exception { System.out.println(CLASS_NAME + "getAllGroups"); diff --git a/perun-openapi/openapi.yml b/perun-openapi/openapi.yml index 3c8a42fb4a..ec42e829f2 100644 --- a/perun-openapi/openapi.yml +++ b/perun-openapi/openapi.yml @@ -1146,6 +1146,15 @@ components: additionalProperties: type: string + MapStringIntegerResponse: + description: "returns Map" + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + MapStringMapStringStringResponse: description: "returns Map>" content: @@ -11358,6 +11367,34 @@ paths: default: $ref: '#/components/responses/ExceptionResponse' + /json/groupsManager/getGroupMembersCountsByVoStatus: + get: + tags: + - GroupsManager + operationId: getGroupMembersCountsByVoStatus + summary: Returns counts of group members by their status in VO. + parameters: + - $ref: '#/components/parameters/groupId' + responses: + '200': + $ref: '#/components/responses/MapStringIntegerResponse' + default: + $ref: '#/components/responses/ExceptionResponse' + + /json/groupsManager/getGroupMembersCountsByGroupStatus: + get: + tags: + - GroupsManager + operationId: getGroupMembersCountsByGroupStatus + summary: Returns counts of group members by their group status. + parameters: + - $ref: '#/components/parameters/groupId' + responses: + '200': + $ref: '#/components/responses/MapStringIntegerResponse' + default: + $ref: '#/components/responses/ExceptionResponse' + /json/groupsManager/getMemberRichGroupsWithAttributesByNames: get: tags: diff --git a/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/GroupsManagerMethod.java b/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/GroupsManagerMethod.java index 27eae98b6b..39627ac1f5 100644 --- a/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/GroupsManagerMethod.java +++ b/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/GroupsManagerMethod.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import cz.metacentrum.perun.core.api.Group; import cz.metacentrum.perun.core.api.Member; @@ -13,6 +14,7 @@ import cz.metacentrum.perun.core.api.RichGroup; import cz.metacentrum.perun.core.api.RichMember; import cz.metacentrum.perun.core.api.RichUser; +import cz.metacentrum.perun.core.api.Status; import cz.metacentrum.perun.core.api.User; import cz.metacentrum.perun.core.api.Vo; import cz.metacentrum.perun.core.api.exceptions.NotGroupMemberException; @@ -715,6 +717,44 @@ public Integer call(ApiCaller ac, Deserializer parms) throws PerunException { } }, + /*# + * Returns counts of group members by their status in VO. + * + * @throw GroupNotExistsException When the group doesn't exist + * + * @param group int Group id + * @return Map map of member status in VO to count of group members with the status + */ + getGroupMembersCountsByVoStatus { + @Override + public Map call(ApiCaller ac, Deserializer parms) throws PerunException { + Map counts = ac.getGroupsManager().getGroupMembersCountsByVoStatus(ac.getSession(), + ac.getGroupById(parms.readInt("group"))); + + // convert Status to String + return counts.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toString(), Map.Entry::getValue)); + } + }, + + /*# + * Returns counts of group members by their group status. + * + * @throw GroupNotExistsException When the group doesn't exist + * + * @param group int Group id + * @return Map map of member status in group to count of group members with the status + */ + getGroupMembersCountsByGroupStatus { + @Override + public Map call(ApiCaller ac, Deserializer parms) throws PerunException { + Map counts = ac.getGroupsManager().getGroupMembersCountsByGroupStatus(ac.getSession(), + ac.getGroupById(parms.readInt("group"))); + + // convert MemberGroupStatus to String + return counts.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toString(), Map.Entry::getValue)); + } + }, + /*# * Returns all groups in a VO. *