Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - REST API search now returns total count of filtered objects trough X-Total-Count response header #30

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions midpoint-client-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@
<artifactId>schema-pure-jaxb</artifactId>
<version>${midpoint.version}</version>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ default S resolveNames() {

S exclude(String path);

S returnTotalCount();

default S distinct() {
option(GetOption.DISTINCT);
return self();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class GetOptionsBuilder<F extends GetOptionSupport<F>> implements GetOpti
List<GetOption> options = new ArrayList<>();
List<String> include = new ArrayList<>();
List<String> exclude = new ArrayList<>();
Boolean returnTotalCount = false;

@Override
public F include(String path) {
Expand Down Expand Up @@ -51,6 +52,12 @@ public F removeOption(GetOption option) {
return self();
}

@Override
public F returnTotalCount() {
this.returnTotalCount = true;
return self();
}

public List<String> getExclude() {
return exclude;
}
Expand All @@ -59,6 +66,10 @@ public List<String> getInclude() {
return include;
}

public Boolean getReturnTotalCount() {
return returnTotalCount;
}

public List<String> optionsAsStringList() {
List<String> ret = new ArrayList<>(options.size());
for (var opt : options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

import jakarta.ws.rs.core.MultivaluedMap;

/**
* @author semancik
*
*/
public interface SearchResult<O extends ObjectType> extends List<O> {

MultivaluedMap<String, Object> getHeaders();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.ListIterator;

import jakarta.ws.rs.core.MultivaluedMap;
import org.apache.cxf.common.util.CollectionUtils;

import com.evolveum.midpoint.client.api.SearchResult;
Expand All @@ -34,6 +35,7 @@
public class JaxbSearchResult<O extends ObjectType> implements SearchResult<O> {

private List<O> list = null;
private MultivaluedMap<String, Object> headers;

public JaxbSearchResult() {
}
Expand All @@ -43,6 +45,16 @@ public JaxbSearchResult(List<O> list) {
this.list = list;
}

public JaxbSearchResult(List<O> list, MultivaluedMap<String, Object> headers) {
this.list = list;
this.headers = headers;
}

@Override
public MultivaluedMap<String, Object> getHeaders() {
return headers;
}

@Override
public int size() {
if (list == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.evolveum.midpoint.client.impl.restjaxb;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -81,10 +82,13 @@ public SearchResult<O> get() throws ObjectNotFoundException {
if (!options.getExclude().isEmpty()) {
queryParams.put("exclude", options.getExclude());
}
if (options.getReturnTotalCount()) {
queryParams.put("returnTotalCount", Collections.singletonList(Boolean.toString(options.getReturnTotalCount())));
}
Response response = getService().post(path, query, queryParams);

if (Status.OK.getStatusCode() == response.getStatus()) {
return new JaxbSearchResult<>(getSearchResultList(response));
return new JaxbSearchResult<>(getSearchResultList(response), response.getHeaders());
}

if (Status.NOT_FOUND.getStatusCode() == response.getStatus()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;

import jakarta.ws.rs.core.MultivaluedMap;
import org.apache.cxf.endpoint.Server;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
Expand Down Expand Up @@ -227,6 +228,15 @@ public void test014UserFilterQuerySearchMock() throws Exception {
assertEquals(result.size(), 0);
}

@Test
public void test015SearchResultResponseHeaders() throws Exception {
Service service = getService();

SearchResult<? extends ObjectType> searchResult = service.users().search().get();

MultivaluedMap<String, Object> responseHeaders = searchResult.getHeaders();
assertNotNull(responseHeaders);
}

@Test
public void test011ValuePolicyGet() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;

import jakarta.ws.rs.core.MultivaluedMap;
import org.apache.commons.lang3.StringUtils;
import org.testng.AssertJUnit;
import org.testng.annotations.BeforeClass;
Expand Down Expand Up @@ -414,6 +415,31 @@ public void test610searchUserFilterQuery() throws Exception {
assertEquals(users.size(), 1);
}

@Test
public void test615SearchResultResponseHeaders() throws Exception {
SearchResult<? extends ObjectType> searchResult = service.users().search().queryFor(UserType.class).get();

MultivaluedMap<String, Object> responseHeaders = searchResult.getHeaders();
assertNotNull(responseHeaders);
}

/**
* Currently this test will pass with only with midpoint branch Z14tk0:feature/rest-search-total-count-header (currently found in this PR https://github.com/Evolveum/midpoint/pull/232)
*/
@Test
public void test620UserSearchWithTotalCount() throws Exception {
SearchResult<UserType> searchResult = service.users().search().queryFor(UserType.class).build()
.options()
.returnTotalCount()
.get();

MultivaluedMap<String, Object> headers = searchResult.getHeaders();
assertNotNull(headers);
assertTrue(headers.containsKey("X-Total-Count"));

String totalCountHeader = headers.getFirst("X-Total-Count").toString();
assertNotNull(totalCountHeader);
}

@Test
public void test700addSecurityPolicy() throws Exception {
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<surefire.version>3.5.2</surefire.version>
<jakarta.annotation.version>3.0.0</jakarta.annotation.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<jakarta.ws.rs-api.version>4.0.0</jakarta.ws.rs-api.version>
</properties>

<scm>
Expand Down Expand Up @@ -137,6 +138,11 @@
<artifactId>jakarta.xml.bind-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>${jakarta.ws.rs-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
Expand Down