Skip to content

Commit

Permalink
Add tests and javadocs
Browse files Browse the repository at this point in the history
  • Loading branch information
acoburn committed Nov 11, 2024
1 parent fb0fdcb commit b4ead82
Show file tree
Hide file tree
Showing 4 changed files with 372 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -357,45 +357,25 @@ public CompletionStage<AccessCredentialVerification> verify(final AccessCredenti
*/
public <T extends AccessCredential> CompletionStage<CredentialResult<T>> query(final CredentialFilter<T> filter) {
final Class<T> clazz = filter.getCredentialType();
final String type;
final Set<String> supportedTypes;
if (AccessGrant.class.isAssignableFrom(clazz)) {
type = SOLID_ACCESS_GRANT;
supportedTypes = ACCESS_GRANT_TYPES;
} else if (AccessRequest.class.isAssignableFrom(clazz)) {
type = SOLID_ACCESS_REQUEST;
supportedTypes = ACCESS_REQUEST_TYPES;
} else if (AccessDenial.class.isAssignableFrom(clazz)) {
type = SOLID_ACCESS_DENIAL;
supportedTypes = ACCESS_DENIAL_TYPES;
} else {
throw new AccessGrantException("Unsupported type " + clazz + " in query request");
}

return v1Metadata().thenCompose(metadata -> {
final List<T> responses = new ArrayList<>();
// check that query endpoint is nonnull
final URIBuilder query = URIBuilder.newBuilder(metadata.queryEndpoint)
.queryParam("type", type)
.queryParam("pageSize", Integer.toString(filter.getPageSize()));

filter.getFromAgent().map(URI::toString).ifPresent(a -> query.queryParam("fromAgent", a));
filter.getToAgent().map(URI::toString).ifPresent(a -> query.queryParam("toAgent", a));
filter.getStatus().map(CredentialFilter.CredentialStatus::getValue)
.ifPresent(s -> query.queryParam("status", s));
filter.getResource().map(URI::toString).ifPresent(r -> query.queryParam("resource", r));
filter.getPurpose().map(URI::toString).ifPresent(p -> query.queryParam("purpose", p));
filter.getIssuedWithin().map(CredentialFilter.CredentialDuration::name)
.ifPresent(d -> query.queryParam("issuedWithin", d));
filter.getRevokedWithin().map(CredentialFilter.CredentialDuration::name)
.ifPresent(d -> query.queryParam("revokedWithin", d));
filter.getPage().ifPresent(p -> query.queryParam("page", p));

final Request req = Request.newBuilder(query.build()).GET().build();
// TODO check that query endpoint is nonnull
final Request req = Request.newBuilder(filter.asURI(metadata.queryEndpoint)).GET().build();
return client.send(req, Response.BodyHandlers.ofInputStream()).thenApply(response -> {
try (final InputStream input = response.body()) {
if (isSuccess(response.statusCode())) {
final Map<String, URI> links = processFilterResponseHeaders(response.headers());
final Map<String, CredentialFilter<T>> links = processFilterResponseHeaders(response.headers(),
filter);
final List<T> items = processFilterResponseBody(input, supportedTypes, clazz);
return new CredentialResult<>(items, links.get("first"), links.get("prev"),
links.get("next"), links.get("last"));
Expand All @@ -411,22 +391,38 @@ public <T extends AccessCredential> CompletionStage<CredentialResult<T>> query(f
});
}

Map<String, URI> processFilterResponseHeaders(final Headers headers) {
final Map<String, URI> links = new HashMap<>();
<T extends AccessCredential> Map<String, CredentialFilter<T>> processFilterResponseHeaders(final Headers headers,
final CredentialFilter<T> filter) {
final Map<String, CredentialFilter<T>> links = new HashMap<>();
final List<String> linkHeaders = headers.allValues("Link");
if (!linkHeaders.isEmpty()) {
Headers.Link.parse(linkHeaders.toArray(linkHeaders.toArray(new String[0])))
.forEach(link -> {
final String rel = link.getParameter("rel");
final URI uri = link.getUri();
if (rel != null && uri != null) {
links.put(rel, uri);
final String page = getPageQueryParam(uri);
links.put(rel, CredentialFilter.newBuilder(filter).page(page)
.build(filter.getCredentialType()));
}
});
}
return links;
}

static String getPageQueryParam(final URI uri) {
final String params = uri.getQuery();
if (params != null) {
for (final String param : params.split("&")) {
final String parts[] = param.split("=", 2);
if (parts.length == 2 && "page".equals(parts[0])) {
return parts[1];
}
}
}
return null;
}

@SuppressWarnings("unchecked")
<T extends AccessCredential> List<T> processFilterResponseBody(final InputStream input,
final Set<String> validTypes, final Class<T> clazz) throws IOException {
Expand Down
Loading

0 comments on commit b4ead82

Please sign in to comment.