AclDAO { public Map<Long, List<Group>> getGroupsForSecrets(Set<Long> secretIdList) { Map<Long, Group> groupMap = dslContext.select().from(GROUPS) .join(ACCESSGRANTS).on(ACCESSGRANTS.GROUPID.eq(GROUPS.ID)) .join(SECRETS).on(ACCESSGRANTS.SECRETID.eq(SECRETS.ID)) .where(SECRETS.ID.in(secretIdList)) .fetchInto(GROUPS).map(groupMapper).stream().collect(Collectors.toMap(Group::getId, g -> g, (g1, g2) -> g1)); Map<Long, List<Long>> secretsIdGroupsIdMap = dslContext.select().from(GROUPS) .join(ACCESSGRANTS).on(ACCESSGRANTS.GROUPID.eq(GROUPS.ID)) .join(SECRETS).on(ACCESSGRANTS.SECRETID.eq(SECRETS.ID)) .where(SECRETS.ID.in(secretIdList)) .fetch().intoGroups(SECRETS.ID, GROUPS.ID); ImmutableMap.Builder<Long, List<Group>> builder = ImmutableMap.builder(); for (Map.Entry<Long, List<Long>> entry : secretsIdGroupsIdMap.entrySet()) { List<Group> groupList = entry.getValue().stream().map(groupMap::get).collect(toList()); builder.put(entry.getKey(), groupList); } return builder.build(); } private  AclDAO(DSLContext dslContext, ClientDAOFactory clientDAOFactory, GroupDAOFactory groupDAOFactory,
                 SecretContentDAOFactory secretContentDAOFactory, SecretSeriesDAOFactory secretSeriesDAOFactory,
                 ClientMapper clientMapper, GroupMapper groupMapper, SecretSeriesMapper secretSeriesMapper,
                 SecretContentMapper secretContentMapper, RowHmacGenerator rowHmacGenerator,
                 KeywhizConfig config); void findAndAllowAccess(long secretId, long groupId, AuditLog auditLog, String user, Map<String, String> extraInfo); void findAndRevokeAccess(long secretId, long groupId, AuditLog auditLog, String user, Map<String, String> extraInfo); void findAndEnrollClient(long clientId, long groupId, AuditLog auditLog, String user, Map<String, String> extraInfo); void findAndEvictClient(long clientId, long groupId, AuditLog auditLog, String user, Map<String, String> extraInfo); ImmutableSet<SanitizedSecret> getSanitizedSecretsFor(Group group); Set<Group> getGroupsFor(Secret secret); Set<Group> getGroupsFor(Client client); Set<Client> getClientsFor(Group group); ImmutableSet<SanitizedSecret> getSanitizedSecretsFor(Client client); Set<Client> getClientsFor(Secret secret); Optional<SanitizedSecret> getSanitizedSecretFor(Client client, String secretName); List<SanitizedSecret> getBatchSanitizedSecretsFor(Client client, List<String> secretNames); Map<Long, List<Group>> getGroupsForSecrets(Set<Long> secretIdList);  }
@Test public void getGroupsForSecrets() { aclDAO.allowAccess(jooqContext.configuration(), secret1.getId(), group2.getId()); aclDAO.allowAccess(jooqContext.configuration(), secret1.getId(), group1.getId()); aclDAO.allowAccess(jooqContext.configuration(), secret2.getId(), group2.getId()); aclDAO.allowAccess(jooqContext.configuration(), secret2.getId(), group1.getId()); Map<Long, List<Group>> groupsForSecrets = aclDAO.getGroupsForSecrets(ImmutableSet.of(secret1.getId(), secret2.getId())); assertThat(groupsForSecrets.size()).isEqualTo(2); assertThat(groupsForSecrets.get(secret1.getId())).containsOnly(group1, group2); assertThat(groupsForSecrets.get(secret2.getId())).containsOnly(group1, group2); }