Skip to content

Commit

Permalink
Improving typing of PaginatedResponse.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisoelkers committed Nov 8, 2022
1 parent 285f910 commit 702d68b
Show file tree
Hide file tree
Showing 26 changed files with 117 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public PaginatedResponse<EventDefinitionDto> list(@ApiParam(name = "page") @Quer
return isPermitted(RestPermissions.EVENT_DEFINITIONS_READ, event.id());
}, "title", page, perPage);
final ImmutableMap<String, Object> context = contextService.contextFor(result.delegate());
return PaginatedResponse.create("event_definitions", result, query, context);
return PaginatedResponse.create(result, query, context);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public PaginatedResponse<NotificationDto> listNotifications(@ApiParam(name = "pa
final PaginatedList<NotificationDto> result = dbNotificationService.searchPaginated(searchQuery, notification -> {
return isPermitted(RestPermissions.EVENT_NOTIFICATIONS_READ, notification.id());
}, "title", page, perPage);
return PaginatedResponse.create("notifications", result, query);
return PaginatedResponse.create(result, query);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public PaginatedResponse<PipelineSource> getPage(@ApiParam(name = "page") @Query
.collect(Collectors.toList());
final PaginatedList<PipelineSource> pipelines = new PaginatedList<>(pipelineList,
result.pagination().total(), result.pagination().page(), result.pagination().perPage());
return PaginatedResponse.create("pipelines", pipelines);
return PaginatedResponse.create(pipelines);
}

@ApiOperation(value = "Get a processing pipeline", notes = "It can take up to a second until the change is applied")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ public PaginatedResponse<RuleSource> getPage(@ApiParam(name = "page") @QueryPara
.collect(Collectors.toList());
final PaginatedList<RuleSource> rules = new PaginatedList<>(ruleSourceList,
result.pagination().total(), result.pagination().page(), result.pagination().perPage());
return PaginatedResponse.create("rules", rules,
prepareContextForPaginatedResponse(result.delegate()));
return PaginatedResponse.create(rules, prepareContextForPaginatedResponse(result.delegate()));
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
import static org.graylog2.shared.rest.documentation.generator.Generator.CLOUD_VISIBLE;

@RequiresAuthentication
@Api(value = "Dashboards", tags = {CLOUD_VISIBLE})
@Api(value = "Dashboards", description = "Provide a list of existing dashboards", tags = {CLOUD_VISIBLE})
@Produces(MediaType.APPLICATION_JSON)
@Path("/dashboards")
public class DashboardsResource extends RestResource {
Expand Down Expand Up @@ -94,7 +94,7 @@ public PaginatedResponse<ViewSummaryDTO> views(@ApiParam(name = "page") @QueryPa
page,
perPage);

return PaginatedResponse.create("views", result, query);
return PaginatedResponse.create(result, query);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public PaginatedResponse<ViewSummaryDTO> views(@ApiParam(name = "page") @QueryPa
page,
perPage);

return PaginatedResponse.create("views", result, query);
return PaginatedResponse.create(result, query);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public PaginatedResponse<ViewDTO> views(@ApiParam(name = "page") @QueryParam("pa
page,
perPage);

return PaginatedResponse.create("views", result, query);
return PaginatedResponse.create(result, query);
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ public PaginatedResponse<AuthServiceBackendDTO> list(@ApiParam(name = "paginatio
final PaginatedList<AuthServiceBackendDTO> list = dbService.findPaginated(paginationParameters, this::checkReadPermission);

return PaginatedResponse.create(
"backends",
list,
Collections.singletonMap("active_backend", activeBackendConfig)
);
Expand Down Expand Up @@ -201,7 +200,6 @@ public PaginatedResponse<UserOverviewDTO> getUsers(
parseSearchQuery(query), page, perPage, sort, order, activeConfig.id());

return PaginatedResponse.create(
"users",
userList,
query,
Collections.singletonMap("roles", createRoleContext(userList.delegate()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public PaginatedResponse<AuthzRoleDTO> getList(
searchQuery, page, perPage,sort, order);
final Map<String, Set<Map<String, String>>> userRoleMap = userRoleContext(result);

return PaginatedResponse.create("roles", result, query, ImmutableMap.of("users", userRoleMap));
return PaginatedResponse.create(result, query, ImmutableMap.of("users", userRoleMap));
}

@GET
Expand Down Expand Up @@ -170,7 +170,7 @@ public PaginatedResponse<UserOverviewDTO> getUsersForRole(

final PaginatedList<UserOverviewDTO> enrichedResult = new PaginatedList<>(users, result.pagination().total(),
result.pagination().page(), result.pagination().perPage());
return PaginatedResponse.create("users", enrichedResult, query);
return PaginatedResponse.create(enrichedResult, query);
}

@GET
Expand Down Expand Up @@ -212,7 +212,7 @@ public PaginatedResponse<AuthzRoleDTO> getListForUser(

final PaginatedList<AuthzRoleDTO> result = authzRolesService.findPaginatedByIds(
searchQuery, page, perPage,sort, order, user.getRoleIds());
return PaginatedResponse.create("roles", result, query);
return PaginatedResponse.create(result, query);
}

@PUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public PaginatedResponse<EntityDescriptor> get(@ApiParam(name = "pagination para

final GranteeSharesService.SharesResponse response = granteeSharesService.getPaginatedSharesFor(grnRegistry.ofUser(user), paginationParameters, capabilityFilter, entityTypeFilter);

return PaginatedResponse.create("entities", response.paginatedEntities(), Collections.singletonMap("grantee_capabilities", response.capabilities()));
return PaginatedResponse.create(response.paginatedEntities(), Collections.singletonMap("grantee_capabilities", response.capabilities()));
}

@POST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,62 +17,81 @@
package org.graylog2.rest.models;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import org.graylog2.database.PaginatedList;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@JsonAutoDetect
public class PaginatedResponse<T> {
private final String listKey;
private final PaginatedList<T> paginatedList;
private final String query;
private final Map<String, Object> context;

private PaginatedResponse(String listKey, PaginatedList<T> paginatedList, @Nullable String query, @Nullable Map<String, Object> context) {
this.listKey = listKey;
this.paginatedList = paginatedList;
this.query = query;
this.context = context;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@AutoValue
public abstract class PaginatedResponse<T> {
@JsonProperty("entities")
@JsonInclude()
public List<T> entities() {
return new ArrayList<>(paginatedList());
}

@JsonValue
public Map<String, Object> jsonValue() {
final ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
.putAll(paginatedList.pagination().asMap())
.put(listKey, new ArrayList<>(paginatedList));
@JsonIgnore
public abstract PaginatedList<T> paginatedList();

if (query != null) {
builder.put("query", query);
}
@JsonProperty("query")
@Nullable
@JsonInclude()
public abstract String query();

if (paginatedList.grandTotal().isPresent()) {
builder.put("grand_total", paginatedList.grandTotal().get());
}
@JsonProperty("context")
@Nullable
public abstract Map<String, Object> context();

if (context != null && !context.isEmpty()) {
builder.put("context", context);
}
@JsonProperty("grand_total")
public Optional<Long> grandTotal() {
return paginatedList().grandTotal();
}

@JsonProperty("total")
public int total() {
return paginatedList().pagination().total();
}

@JsonProperty("count")
public int count() {
return paginatedList().pagination().count();
}

@JsonProperty("page")
public int page() {
return paginatedList().pagination().page();
}

return builder.build();
@JsonProperty("per_page")
public int perPage() {
return paginatedList().pagination().perPage();
}

public static <T> PaginatedResponse<T> create(String listKey, PaginatedList<T> paginatedList) {
return new PaginatedResponse<>(listKey, paginatedList, null, null);

public static <T> PaginatedResponse<T> create(PaginatedList<T> paginatedList) {
return create(paginatedList, null, null);
}

public static <T> PaginatedResponse<T> create(String listKey, PaginatedList<T> paginatedList, Map<String, Object> context) {
return new PaginatedResponse<>(listKey, paginatedList, null, context);
public static <T> PaginatedResponse<T> create(PaginatedList<T> paginatedList, Map<String, Object> context) {
return create(paginatedList, null, context);
}

public static <T> PaginatedResponse<T> create(String listKey, PaginatedList<T> paginatedList, String query) {
return new PaginatedResponse<>(listKey, paginatedList, query, null);
public static <T> PaginatedResponse<T> create(PaginatedList<T> paginatedList, String query) {
return create(paginatedList, query, null);
}

public static <T> PaginatedResponse<T> create(String listKey, PaginatedList<T> paginatedList, String query, Map<String, Object> context) {
return new PaginatedResponse<>(listKey, paginatedList, query, context);
public static <T> PaginatedResponse<T> create(PaginatedList<T> paginatedList, String query, Map<String, Object> context) {
return new AutoValue_PaginatedResponse<>(paginatedList, query, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public PaginatedResponse<GrokPattern> getPage(@ApiParam(name = "page") @QueryPar
final PaginatedList<GrokPattern> result = paginatedGrokPatternService
.findPaginated(searchQuery, page, perPage, sort, order);

return PaginatedResponse.create("patterns", result);
return PaginatedResponse.create(result);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public PaginatedResponse<UserOverviewDTO> getPage(@ApiParam(name = "page") @Quer

final PaginatedList<UserOverviewDTO> userOverviewDTOS = new PaginatedList<>(users, result.pagination().total(),
result.pagination().page(), result.pagination().perPage());
return PaginatedResponse.create("users", userOverviewDTOS, query, Collections.singletonMap("admin_user", adminUser));
return PaginatedResponse.create(userOverviewDTOS, query, Collections.singletonMap("admin_user", adminUser));
}

@POST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void setUp() throws Exception {
public void serialize() throws Exception {
final ImmutableList<String> values = ImmutableList.of("hello", "world");
final PaginatedList<String> paginatedList = new PaginatedList<>(values, values.size(), 1, 10);
final PaginatedResponse<String> response = PaginatedResponse.create("foo", paginatedList);
final PaginatedResponse<String> response = PaginatedResponse.create(paginatedList);

final DocumentContext ctx = JsonPath.parse(objectMapper.writeValueAsString(response));
final JsonPathAssert jsonPathAssert = JsonPathAssert.assertThat(ctx);
Expand All @@ -53,8 +53,8 @@ public void serialize() throws Exception {
jsonPathAssert.jsonPathAsInteger("$.count").isEqualTo(2);
jsonPathAssert.jsonPathAsInteger("$.page").isEqualTo(1);
jsonPathAssert.jsonPathAsInteger("$.per_page").isEqualTo(10);
jsonPathAssert.jsonPathAsString("$.foo[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.foo[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.entities[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.entities[1]").isEqualTo("world");
assertThatThrownBy(() -> jsonPathAssert.jsonPathAsString("$.context")).isInstanceOf(PathNotFoundException.class);
}

Expand All @@ -63,7 +63,7 @@ public void serializeWithContext() throws Exception {
final ImmutableList<String> values = ImmutableList.of("hello", "world");
final ImmutableMap<String, Object> context = ImmutableMap.of("context1", "wow");
final PaginatedList<String> paginatedList = new PaginatedList<>(values, values.size(), 1, 10);
final PaginatedResponse<String> response = PaginatedResponse.create("foo", paginatedList, context);
final PaginatedResponse<String> response = PaginatedResponse.create(paginatedList, context);

final DocumentContext ctx = JsonPath.parse(objectMapper.writeValueAsString(response));
final JsonPathAssert jsonPathAssert = JsonPathAssert.assertThat(ctx);
Expand All @@ -72,16 +72,16 @@ public void serializeWithContext() throws Exception {
jsonPathAssert.jsonPathAsInteger("$.count").isEqualTo(2);
jsonPathAssert.jsonPathAsInteger("$.page").isEqualTo(1);
jsonPathAssert.jsonPathAsInteger("$.per_page").isEqualTo(10);
jsonPathAssert.jsonPathAsString("$.foo[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.foo[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.entities[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.entities[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.context.context1").isEqualTo("wow");
}

@Test
public void serializeWithQuery() throws Exception {
final ImmutableList<String> values = ImmutableList.of("hello", "world");
final PaginatedList<String> paginatedList = new PaginatedList<>(values, values.size(), 1, 10);
final PaginatedResponse<String> response = PaginatedResponse.create("foo", paginatedList, "query1");
final PaginatedResponse<String> response = PaginatedResponse.create(paginatedList, "query1");

final DocumentContext ctx = JsonPath.parse(objectMapper.writeValueAsString(response));
final JsonPathAssert jsonPathAssert = JsonPathAssert.assertThat(ctx);
Expand All @@ -91,8 +91,8 @@ public void serializeWithQuery() throws Exception {
jsonPathAssert.jsonPathAsInteger("$.count").isEqualTo(2);
jsonPathAssert.jsonPathAsInteger("$.page").isEqualTo(1);
jsonPathAssert.jsonPathAsInteger("$.per_page").isEqualTo(10);
jsonPathAssert.jsonPathAsString("$.foo[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.foo[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.entities[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.entities[1]").isEqualTo("world");
assertThatThrownBy(() -> jsonPathAssert.jsonPathAsString("$.context")).isInstanceOf(PathNotFoundException.class);
}

Expand All @@ -101,7 +101,7 @@ public void serializeWithQueryAndContext() throws Exception {
final ImmutableList<String> values = ImmutableList.of("hello", "world");
final ImmutableMap<String, Object> context = ImmutableMap.of("context1", "wow");
final PaginatedList<String> paginatedList = new PaginatedList<>(values, values.size(), 1, 10);
final PaginatedResponse<String> response = PaginatedResponse.create("foo", paginatedList, "query1", context);
final PaginatedResponse<String> response = PaginatedResponse.create(paginatedList, "query1", context);

final DocumentContext ctx = JsonPath.parse(objectMapper.writeValueAsString(response));
final JsonPathAssert jsonPathAssert = JsonPathAssert.assertThat(ctx);
Expand All @@ -111,8 +111,8 @@ public void serializeWithQueryAndContext() throws Exception {
jsonPathAssert.jsonPathAsInteger("$.count").isEqualTo(2);
jsonPathAssert.jsonPathAsInteger("$.page").isEqualTo(1);
jsonPathAssert.jsonPathAsInteger("$.per_page").isEqualTo(10);
jsonPathAssert.jsonPathAsString("$.foo[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.foo[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.entities[0]").isEqualTo("hello");
jsonPathAssert.jsonPathAsString("$.entities[1]").isEqualTo("world");
jsonPathAssert.jsonPathAsString("$.context.context1").isEqualTo("wow");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ type PaginatedBackendsResponse = PaginatedResponseType & {
context: {
active_backend: AuthenticationBackendJSON | null | undefined,
},
backends: Array<AuthenticationBackendJSON>,
entities: Array<AuthenticationBackendJSON>,
};

type PaginatedUsersResponse = PaginatedResponseType & {
users: Array<UserOverviewJSON>,
entities: Array<UserOverviewJSON>,
};

export const AuthenticationStore = singletonStore(
Expand Down Expand Up @@ -234,7 +234,7 @@ export const AuthenticationStore = singletonStore(
context: {
activeBackend: response.context.active_backend,
},
list: Immutable.List(response.backends.map((backend) => AuthenticationBackend.fromJSON(backend))),
list: Immutable.List(response.entities.map((backend) => AuthenticationBackend.fromJSON(backend))),
pagination: {
page: response.page,
perPage: response.per_page,
Expand All @@ -254,7 +254,7 @@ export const AuthenticationStore = singletonStore(

const promise = fetch('GET', qualifyUrl(url))
.then((response: PaginatedUsersResponse) => ({
list: Immutable.List(response.users.map((user) => UserOverview.fromJSON(user))),
list: Immutable.List(response.entities.map((user) => UserOverview.fromJSON(user))),
pagination: {
page: response.page,
perPage: response.per_page,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export const EventDefinitionsStore = singletonStore(
const promise = fetch('GET', this.eventDefinitionsUrl({ query: { per_page: 0 } }));

promise.then((response) => {
this.all = response.event_definitions;
this.all = response.entities;
this.context = response.context;
this.propagateChanges();

Expand All @@ -122,7 +122,7 @@ export const EventDefinitionsStore = singletonStore(
}));

promise.then((response) => {
this.eventDefinitions = response.event_definitions;
this.eventDefinitions = response.entities;
this.context = response.context;
this.query = response.query;

Expand Down
Loading

0 comments on commit 702d68b

Please sign in to comment.