Skip to content

Commit 843e87f

Browse files
authored
Add support for pagination in the get-role-mappings REST operation (#4331)
1 parent 4f4d569 commit 843e87f

27 files changed

+619
-244
lines changed

app/src/main/java/io/apicurio/registry/rest/v3/AdminResourceImpl.java

+54-48
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,36 @@
11
package io.apicurio.registry.rest.v3;
22

3-
import io.apicurio.common.apps.config.*;
3+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_FOR_BROWSER;
4+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_NAME;
5+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_PRINCIPAL_ID;
6+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_ROLE_MAPPING;
7+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_RULE;
8+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_RULE_TYPE;
9+
import static io.apicurio.common.apps.logging.audit.AuditingConstants.KEY_UPDATE_ROLE;
10+
import static io.apicurio.registry.util.DtoUtil.appAuthPropertyToRegistry;
11+
import static io.apicurio.registry.util.DtoUtil.registryAuthPropertyToApp;
12+
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.math.BigInteger;
16+
import java.nio.charset.StandardCharsets;
17+
import java.util.HashMap;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.function.Supplier;
21+
import java.util.stream.Collectors;
22+
import java.util.stream.Stream;
23+
import java.util.zip.ZipInputStream;
24+
25+
import org.eclipse.microprofile.config.Config;
26+
import org.eclipse.microprofile.config.inject.ConfigProperty;
27+
import org.slf4j.Logger;
28+
29+
import io.apicurio.common.apps.config.Dynamic;
30+
import io.apicurio.common.apps.config.DynamicConfigPropertyDef;
31+
import io.apicurio.common.apps.config.DynamicConfigPropertyDto;
32+
import io.apicurio.common.apps.config.DynamicConfigPropertyIndex;
33+
import io.apicurio.common.apps.config.Info;
434
import io.apicurio.common.apps.logging.Logged;
535
import io.apicurio.common.apps.logging.audit.Audited;
636
import io.apicurio.registry.auth.Authorized;
@@ -10,21 +40,28 @@
1040
import io.apicurio.registry.metrics.health.liveness.ResponseErrorLivenessCheck;
1141
import io.apicurio.registry.metrics.health.readiness.ResponseTimeoutReadinessCheck;
1242
import io.apicurio.registry.rest.MissingRequiredParameterException;
13-
import io.apicurio.registry.rest.v3.beans.*;
43+
import io.apicurio.registry.rest.v3.beans.ArtifactTypeInfo;
44+
import io.apicurio.registry.rest.v3.beans.ConfigurationProperty;
45+
import io.apicurio.registry.rest.v3.beans.DownloadRef;
46+
import io.apicurio.registry.rest.v3.beans.RoleMapping;
47+
import io.apicurio.registry.rest.v3.beans.RoleMappingSearchResults;
48+
import io.apicurio.registry.rest.v3.beans.Rule;
49+
import io.apicurio.registry.rest.v3.beans.UpdateConfigurationProperty;
50+
import io.apicurio.registry.rest.v3.beans.UpdateRole;
1451
import io.apicurio.registry.rest.v3.shared.DataExporter;
1552
import io.apicurio.registry.rules.DefaultRuleDeletionException;
1653
import io.apicurio.registry.rules.RulesProperties;
1754
import io.apicurio.registry.storage.RegistryStorage;
1855
import io.apicurio.registry.storage.dto.DownloadContextDto;
1956
import io.apicurio.registry.storage.dto.DownloadContextType;
2057
import io.apicurio.registry.storage.dto.RoleMappingDto;
58+
import io.apicurio.registry.storage.dto.RoleMappingSearchResultsDto;
2159
import io.apicurio.registry.storage.dto.RuleConfigurationDto;
2260
import io.apicurio.registry.storage.error.ConfigPropertyNotFoundException;
2361
import io.apicurio.registry.storage.error.InvalidPropertyValueException;
2462
import io.apicurio.registry.storage.error.RuleNotFoundException;
2563
import io.apicurio.registry.storage.impexp.EntityInputStream;
2664
import io.apicurio.registry.types.Current;
27-
import io.apicurio.registry.types.RoleType;
2865
import io.apicurio.registry.types.RuleType;
2966
import io.apicurio.registry.types.provider.ArtifactTypeUtilProviderFactory;
3067
import io.apicurio.registry.utils.impexp.Entity;
@@ -36,24 +73,6 @@
3673
import jakarta.ws.rs.core.Context;
3774
import jakarta.ws.rs.core.MediaType;
3875
import jakarta.ws.rs.core.Response;
39-
import org.eclipse.microprofile.config.Config;
40-
import org.eclipse.microprofile.config.inject.ConfigProperty;
41-
import org.slf4j.Logger;
42-
43-
import java.io.IOException;
44-
import java.io.InputStream;
45-
import java.nio.charset.StandardCharsets;
46-
import java.util.HashMap;
47-
import java.util.List;
48-
import java.util.Map;
49-
import java.util.function.Supplier;
50-
import java.util.stream.Collectors;
51-
import java.util.stream.Stream;
52-
import java.util.zip.ZipInputStream;
53-
54-
import static io.apicurio.common.apps.logging.audit.AuditingConstants.*;
55-
import static io.apicurio.registry.util.DtoUtil.appAuthPropertyToRegistry;
56-
import static io.apicurio.registry.util.DtoUtil.registryAuthPropertyToApp;
5776

5877
@ApplicationScoped
5978
@Interceptors({ResponseErrorLivenessCheck.class, ResponseTimeoutReadinessCheck.class})
@@ -287,16 +306,21 @@ public void createRoleMapping(RoleMapping data) {
287306
}
288307

289308
/**
290-
* @see io.apicurio.registry.rest.v3.AdminResource#listRoleMappings()
309+
* @see io.apicurio.registry.rest.v3.AdminResource#listRoleMappings(java.math.BigInteger, java.math.BigInteger)
291310
*/
292311
@Override
293312
@Authorized(style=AuthorizedStyle.None, level=AuthorizedLevel.Admin)
294313
@RoleBasedAccessApiOperation
295-
public List<RoleMapping> listRoleMappings() {
296-
List<RoleMappingDto> mappings = storage.getRoleMappings();
297-
return mappings.stream().map(dto -> {
298-
return dtoToRoleMapping(dto);
299-
}).collect(Collectors.toList());
314+
public RoleMappingSearchResults listRoleMappings(BigInteger limit, BigInteger offset) {
315+
if (offset == null) {
316+
offset = BigInteger.valueOf(0);
317+
}
318+
if (limit == null) {
319+
limit = BigInteger.valueOf(20);
320+
}
321+
322+
RoleMappingSearchResultsDto dto = storage.searchRoleMappings(offset.intValue(), limit.intValue());
323+
return V3ApiUtil.dtoToRoleMappingSearchResults(dto);
300324
}
301325

302326
/**
@@ -307,7 +331,7 @@ public List<RoleMapping> listRoleMappings() {
307331
@RoleBasedAccessApiOperation
308332
public RoleMapping getRoleMapping(String principalId) {
309333
RoleMappingDto dto = storage.getRoleMapping(principalId);
310-
return dtoToRoleMapping(dto);
334+
return V3ApiUtil.dtoToRoleMapping(dto);
311335
}
312336

313337
/**
@@ -352,7 +376,7 @@ public List<ConfigurationProperty> listConfigProperties() {
352376
// on whether the value is actually configured and stored in the DB or not).
353377
return dynamicPropertyIndex.getAcceptedPropertyNames().stream()
354378
.sorted((pname1, pname2) -> pname1.compareTo(pname2))
355-
.map(pname -> propsI.containsKey(pname) ? dtoToConfigurationProperty(dynamicPropertyIndex.getProperty(pname), propsI.get(pname)) : defToConfigurationProperty(dynamicPropertyIndex.getProperty(pname)))
379+
.map(pname -> propsI.containsKey(pname) ? V3ApiUtil.dtoToConfigurationProperty(dynamicPropertyIndex.getProperty(pname), propsI.get(pname)) : defToConfigurationProperty(dynamicPropertyIndex.getProperty(pname)))
356380
.collect(Collectors.toList());
357381
}
358382

@@ -369,7 +393,7 @@ public ConfigurationProperty getConfigProperty(String propertyName) {
369393
if (dto == null) {
370394
return defToConfigurationProperty(def);
371395
} else {
372-
return dtoToConfigurationProperty(def, dto);
396+
return V3ApiUtil.dtoToConfigurationProperty(def, dto);
373397
}
374398
}
375399

@@ -401,14 +425,6 @@ public void resetConfigProperty(String propertyName) {
401425
storage.deleteConfigProperty(propertyName);
402426
}
403427

404-
private static RoleMapping dtoToRoleMapping(RoleMappingDto dto) {
405-
RoleMapping mapping = new RoleMapping();
406-
mapping.setPrincipalId(dto.getPrincipalId());
407-
mapping.setRole(RoleType.valueOf(dto.getRole()));
408-
mapping.setPrincipalName(dto.getPrincipalName());
409-
return mapping;
410-
}
411-
412428

413429
private static boolean isNullOrTrue(Boolean value) {
414430
return value == null || value;
@@ -418,16 +434,6 @@ private String createDownloadHref(String downloadId) {
418434
return "/apis/registry/v3/downloads/" + downloadId;
419435
}
420436

421-
private static ConfigurationProperty dtoToConfigurationProperty(DynamicConfigPropertyDef def, DynamicConfigPropertyDto dto) {
422-
ConfigurationProperty rval = new ConfigurationProperty();
423-
rval.setName(def.getName());
424-
rval.setValue(dto.getValue());
425-
rval.setType(def.getType().getName());
426-
rval.setLabel(def.getLabel());
427-
rval.setDescription(def.getDescription());
428-
return rval;
429-
}
430-
431437
private ConfigurationProperty defToConfigurationProperty(DynamicConfigPropertyDef def) {
432438
String propertyValue = config.getOptionalValue(def.getName(), String.class).orElse(def.getDefaultValue());
433439

app/src/main/java/io/apicurio/registry/rest/v3/GroupsResourceImpl.java

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ public void deleteGroupById(String groupId) {
271271
* @see io.apicurio.registry.rest.v3.GroupsResource#updateGroupById(java.lang.String, io.apicurio.registry.rest.v3.beans.EditableGroupMetaData)
272272
*/
273273
@Override
274+
@Authorized(style = AuthorizedStyle.GroupOnly, level = AuthorizedLevel.Write)
274275
public void updateGroupById(String groupId, EditableGroupMetaData data) {
275276
requireParameter("groupId", groupId);
276277

app/src/main/java/io/apicurio/registry/rest/v3/V3ApiUtil.java

+58-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,41 @@
11
package io.apicurio.registry.rest.v3;
22

3-
import io.apicurio.registry.rest.v3.beans.*;
4-
import io.apicurio.registry.storage.dto.*;
5-
63
import java.util.ArrayList;
74
import java.util.Comparator;
85
import java.util.Date;
96
import java.util.Optional;
107
import java.util.stream.Collectors;
118

9+
import io.apicurio.common.apps.config.DynamicConfigPropertyDef;
10+
import io.apicurio.common.apps.config.DynamicConfigPropertyDto;
11+
import io.apicurio.registry.rest.v3.beans.ArtifactMetaData;
12+
import io.apicurio.registry.rest.v3.beans.ArtifactReference;
13+
import io.apicurio.registry.rest.v3.beans.ArtifactSearchResults;
14+
import io.apicurio.registry.rest.v3.beans.Comment;
15+
import io.apicurio.registry.rest.v3.beans.ConfigurationProperty;
16+
import io.apicurio.registry.rest.v3.beans.GroupMetaData;
17+
import io.apicurio.registry.rest.v3.beans.GroupSearchResults;
18+
import io.apicurio.registry.rest.v3.beans.RoleMapping;
19+
import io.apicurio.registry.rest.v3.beans.RoleMappingSearchResults;
20+
import io.apicurio.registry.rest.v3.beans.SearchedArtifact;
21+
import io.apicurio.registry.rest.v3.beans.SearchedGroup;
22+
import io.apicurio.registry.rest.v3.beans.SearchedVersion;
23+
import io.apicurio.registry.rest.v3.beans.SortOrder;
24+
import io.apicurio.registry.rest.v3.beans.VersionMetaData;
25+
import io.apicurio.registry.rest.v3.beans.VersionSearchResults;
26+
import io.apicurio.registry.storage.dto.ArtifactMetaDataDto;
27+
import io.apicurio.registry.storage.dto.ArtifactReferenceDto;
28+
import io.apicurio.registry.storage.dto.ArtifactSearchResultsDto;
29+
import io.apicurio.registry.storage.dto.ArtifactVersionMetaDataDto;
30+
import io.apicurio.registry.storage.dto.CommentDto;
31+
import io.apicurio.registry.storage.dto.EditableArtifactMetaDataDto;
32+
import io.apicurio.registry.storage.dto.GroupMetaDataDto;
33+
import io.apicurio.registry.storage.dto.GroupSearchResultsDto;
34+
import io.apicurio.registry.storage.dto.RoleMappingDto;
35+
import io.apicurio.registry.storage.dto.RoleMappingSearchResultsDto;
36+
import io.apicurio.registry.storage.dto.VersionSearchResultsDto;
37+
import io.apicurio.registry.types.RoleType;
38+
1239
public final class V3ApiUtil {
1340

1441
private V3ApiUtil() {
@@ -296,4 +323,32 @@ public static Comment commentDtoToComment(CommentDto dto) {
296323
.value(dto.getValue())
297324
.build();
298325
}
326+
327+
public static RoleMapping dtoToRoleMapping(RoleMappingDto dto) {
328+
RoleMapping mapping = new RoleMapping();
329+
mapping.setPrincipalId(dto.getPrincipalId());
330+
mapping.setRole(RoleType.valueOf(dto.getRole()));
331+
mapping.setPrincipalName(dto.getPrincipalName());
332+
return mapping;
333+
}
334+
335+
public static RoleMappingSearchResults dtoToRoleMappingSearchResults(RoleMappingSearchResultsDto dto) {
336+
RoleMappingSearchResults results = new RoleMappingSearchResults();
337+
results.setCount((int) dto.getCount());
338+
results.setRoleMappings(dto.getRoleMappings().stream().map(rm -> {
339+
return dtoToRoleMapping(rm);
340+
}).collect(Collectors.toList()));
341+
return results;
342+
}
343+
344+
public static ConfigurationProperty dtoToConfigurationProperty(DynamicConfigPropertyDef def, DynamicConfigPropertyDto dto) {
345+
ConfigurationProperty rval = new ConfigurationProperty();
346+
rval.setName(def.getName());
347+
rval.setValue(dto.getValue());
348+
rval.setType(def.getType().getName());
349+
rval.setLabel(def.getLabel());
350+
rval.setDescription(def.getDescription());
351+
return rval;
352+
}
353+
299354
}

app/src/main/java/io/apicurio/registry/storage/RegistryStorage.java

+7
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,13 @@ void updateArtifactRule(String groupId, String artifactId, RuleType rule, RuleCo
649649
*/
650650
List<RoleMappingDto> getRoleMappings() throws RegistryStorageException;
651651

652+
/**
653+
* Search for role mappings.
654+
* @param offset the number of artifacts to skip
655+
* @param limit the result size limit
656+
*/
657+
RoleMappingSearchResultsDto searchRoleMappings(int offset, int limit) throws RegistryStorageException;
658+
652659
/**
653660
* Gets the details of a single role mapping.
654661
*

app/src/main/java/io/apicurio/registry/storage/decorator/RegistryStorageDecoratorReadOnlyBase.java

+5
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ public String getRoleForPrincipal(String principalId) throws RegistryStorageExce
263263
public List<RoleMappingDto> getRoleMappings() throws RegistryStorageException {
264264
return delegate.getRoleMappings();
265265
}
266+
267+
@Override
268+
public RoleMappingSearchResultsDto searchRoleMappings(int offset, int limit) throws RegistryStorageException {
269+
return delegate.searchRoleMappings(offset, limit);
270+
}
266271

267272

268273
@Override

app/src/main/java/io/apicurio/registry/storage/dto/ArtifactSearchResultsDto.java

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
@ToString
1515
public class ArtifactSearchResultsDto {
1616

17+
@Builder.Default
1718
private List<SearchedArtifactDto> artifacts = new ArrayList<>();
1819
private long count;
1920
}

app/src/main/java/io/apicurio/registry/storage/dto/GroupSearchResultsDto.java

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@ToString
1616
public class GroupSearchResultsDto {
1717

18+
@Builder.Default
1819
private List<SearchedGroupDto> groups = new ArrayList<SearchedGroupDto>();
1920

2021
private Integer count;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.apicurio.registry.storage.dto;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import io.quarkus.runtime.annotations.RegisterForReflection;
7+
import lombok.AllArgsConstructor;
8+
import lombok.Builder;
9+
import lombok.EqualsAndHashCode;
10+
import lombok.Getter;
11+
import lombok.NoArgsConstructor;
12+
import lombok.Setter;
13+
import lombok.ToString;
14+
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
@Builder
18+
@Getter
19+
@Setter
20+
@EqualsAndHashCode
21+
@ToString
22+
@RegisterForReflection
23+
public class RoleMappingSearchResultsDto {
24+
25+
@Builder.Default
26+
private List<RoleMappingDto> roleMappings = new ArrayList<>();
27+
private long count;
28+
29+
}

app/src/main/java/io/apicurio/registry/storage/dto/VersionSearchResultsDto.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
@ToString
1515
public class VersionSearchResultsDto {
1616

17-
private long count;
17+
@Builder.Default
1818
private List<SearchedVersionDto> versions = new ArrayList<>();
19+
private long count;
1920
}

app/src/main/java/io/apicurio/registry/storage/impl/gitops/GitOpsRegistryStorage.java

+5
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ public long countTotalArtifactVersions() {
374374
public List<RoleMappingDto> getRoleMappings() {
375375
return proxy(RegistryStorage::getRoleMappings);
376376
}
377+
378+
@Override
379+
public RoleMappingSearchResultsDto searchRoleMappings(int offset, int limit) throws RegistryStorageException {
380+
return proxy(storage -> storage.searchRoleMappings(offset, limit));
381+
}
377382

378383

379384
@Override

app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java

+22
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import io.apicurio.registry.storage.dto.OrderBy;
6969
import io.apicurio.registry.storage.dto.OrderDirection;
7070
import io.apicurio.registry.storage.dto.RoleMappingDto;
71+
import io.apicurio.registry.storage.dto.RoleMappingSearchResultsDto;
7172
import io.apicurio.registry.storage.dto.RuleConfigurationDto;
7273
import io.apicurio.registry.storage.dto.SearchFilter;
7374
import io.apicurio.registry.storage.dto.SearchFilterType;
@@ -2419,6 +2420,27 @@ public List<RoleMappingDto> getRoleMappings() throws RegistryStorageException {
24192420
});
24202421
}
24212422

2423+
@Override
2424+
@Transactional
2425+
public RoleMappingSearchResultsDto searchRoleMappings(int offset, int limit) throws RegistryStorageException {
2426+
log.debug("Searching role mappings.");
2427+
return handles.withHandleNoException(handle -> {
2428+
String query = sqlStatements.selectRoleMappings() + " LIMIT ? OFFSET ?";
2429+
String countQuery = sqlStatements.countRoleMappings();
2430+
List<RoleMappingDto> mappings = handle.createQuery(query)
2431+
.bind(0, limit)
2432+
.bind(1, offset)
2433+
.map(RoleMappingDtoMapper.instance)
2434+
.list();
2435+
Integer count = handle.createQuery(countQuery)
2436+
.mapTo(Integer.class)
2437+
.one();
2438+
return RoleMappingSearchResultsDto.builder()
2439+
.count(count)
2440+
.roleMappings(mappings)
2441+
.build();
2442+
});
2443+
}
24222444

24232445
@Override
24242446
@Transactional

0 commit comments

Comments
 (0)