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

Add ability to query just for the number of assets #52

Merged
merged 1 commit into from
Sep 15, 2015
Merged
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
21 changes: 21 additions & 0 deletions server/src/fat/java/com/ibm/ws/lars/rest/ApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,27 @@ public void testGetAllAssetsSorted() throws Exception {
assertThat(collatePages(page1, page2), contains(smallFoo, bigFoo, giantBar));
}

@SuppressWarnings("unused")
@Test
public void countAllAssets() throws Exception {
Asset bigFoo = addLittleAsset("name", "Big Foo", "category", "foo", "size", "20");
Asset smallFoo = addLittleAsset("name", "Small Foo", "category", "foo", "size", "10");
Asset giantBar = addLittleAsset("name", "Giant Bar", "category", "bar", "size", "40");
Asset smallBar = addLittleAsset("name", "Small Bar", "category", "bar", "size", "10");

int result = repository.getAssetCount("");
assertEquals(4, result);

result = repository.getAssetCount("category=foo");
assertEquals(2, result);

result = repository.getAssetCount("q=foo");
assertEquals(2, result);

result = repository.getAssetCount("q=foo&size=10");
assertEquals(1, result);
}

@SuppressWarnings("unchecked")
@Test
public void testGetAssetSummary() throws Exception {
Expand Down
16 changes: 16 additions & 0 deletions server/src/fat/java/com/ibm/ws/lars/rest/RepositoryContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
Expand All @@ -47,6 +48,7 @@
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
Expand Down Expand Up @@ -273,6 +275,15 @@ public String doDelete(String url, int expectedStatusCode)
return doRequest(delete, expectedStatusCode);
}

public HttpResponse doHead(String url, int expectedStatusCode)
throws ClientProtocolException, IOException {
HttpHead head = new HttpHead(fullURL + url);
HttpResponse response = httpClient.execute(targetHost, head, context);

assertStatusCode(expectedStatusCode, response);
return response;
}

public String doRequest(HttpEntityEnclosingRequestBase request,
String content,
int expectedStatusCode)
Expand Down Expand Up @@ -444,6 +455,11 @@ void getBadAssetSummary(String parameters, int expectedRC) throws IOException {
doGet("/assets/summary?" + parameters, expectedRC);
}

int getAssetCount(String parameters) throws IOException {
HttpResponse response = doHead("/assets?" + parameters, HttpStatus.SC_NO_CONTENT);
return Integer.parseInt(response.getFirstHeader("count").getValue());
}

protected Attachment doPostAttachmentNoContent(String assetId, String name, Attachment attachment) throws ClientProtocolException, IOException, InvalidJsonAssetException {
List<NameValuePair> qparams = new ArrayList<>();
qparams.add(new BasicNameValuePair("name", name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public AssetList retrieveAllAssets(Map<String, List<Condition>> filters, String
return persistenceBean.retrieveAllAssets(filters, searchTerm, pagination, sortOptions);
}

/**
* @see Persistor#countAllAssets(Map, String)
*/
public int countAllAssets(Map<String, List<Condition>> filters, String searchTerm) {
return persistenceBean.countAllAssets(filters, searchTerm);
}

/**
* Summarizes a list of fields from the assets matched by the given filters and search term.
* <p>
Expand Down
22 changes: 22 additions & 0 deletions server/src/main/java/com/ibm/ws/lars/rest/PersistenceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ public AssetList retrieveAllAssets(Map<String, List<Condition>> filters, String
return AssetList.createAssetListFromMaps(assets);
}

/** {@inheritDoc} */
@Override
public int countAllAssets(Map<String, List<Condition>> filters, String searchTerm) {
BasicDBObject filterObject = createFilterObject(filters, searchTerm);
return queryCount(filterObject);
}

/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
Expand Down Expand Up @@ -278,6 +285,21 @@ private List<DBObject> query(DBObject filterObject, DBObject sortObject, DBObjec
return results;
}

private int queryCount(DBObject filterObject) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("queryCount: Querying database with query object " + filterObject);
}

DBCursor cursor = getAssetCollection().find(filterObject);
int count = cursor.count();

if (logger.isLoggable(Level.FINE)) {
logger.fine("queryCount: found " + count + " assets.");
}

return count;
}

private int getMongoSortOrder(SortOrder sortOrder) {
switch (sortOrder) {
case ASCENDING:
Expand Down
12 changes: 12 additions & 0 deletions server/src/main/java/com/ibm/ws/lars/rest/Persistor.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ public interface Persistor {
*/
public AssetList retrieveAllAssets(Map<String, List<Condition>> filters, String searchTerm, PaginationOptions pagination, SortOptions sortOptions);

/**
* Retrieve the number of assets which match the given set of filters.
* <p>
* <code>filters</code> and <code>searchTerm</code> have the same meaning as in
* {@link #retrieveAllAssets(Map, String, PaginationOptions, SortOptions)}
*
* @param filters filters to apply to the results, may be empty to not filter
* @param searchTerm search to match against the results, may be null to not search
* @return the number of assets which match the given filter and search term.
*/
public int countAllAssets(Map<String, List<Condition>> filters, String searchTerm);

/**
* Gets the list of distinct values of the given field in all assets which match the given
* filters and searchTerm.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
Expand Down Expand Up @@ -128,6 +129,20 @@ public Response getAssets(@Context UriInfo info) throws JsonProcessingException,
return Response.ok(json).build();
}

@HEAD
@Path("/assets")
public Response countAssets(@Context UriInfo info) throws InvalidParameterException {
if (logger.isLoggable(Level.FINE)) {
logger.fine("countAssets called with query parameters: " + info.getRequestUri().getRawQuery());
}

AssetQueryParameters params = AssetQueryParameters.create(info);

int count = assetService.countAllAssets(params.getFilterMap(), params.getSearchTerm());

return Response.noContent().header("count", count).build();
}

@POST
@Path("/assets")
@Produces(MediaType.APPLICATION_JSON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ public List<Object> getDistinctValues(String field, Map<String, List<Condition>>
throw new UnsupportedOperationException("Filtering is not supported in this test facade");
}

/** {@inheritDoc} */
@Override
public int countAllAssets(Map<String, List<Condition>> filters, String searchTerm) {
throw new UnsupportedOperationException("Filtering is not supported in this test facade");
}

/*
* (non-Javadoc)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*******************************************************************************/
package com.ibm.ws.lars.rest;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -201,4 +203,50 @@ public void testRetrieveAllAssetsWithSearchAndSort(final @Mocked DBCollection co
SortOptions sortOptions = new SortOptions("key2", SortOrder.DESCENDING);
createTestBean().retrieveAllAssets(filters, "foo", null, sortOptions);
}

@Test
public void testCountAllAssets(final @Mocked DBCollection collection, final @Injectable DBCursor cursor) {
BasicDBList list = new BasicDBList();
list.add(new BasicDBObject("key1", "value1"));
final BasicDBObject searchObject = new BasicDBObject("$and", list);

new Expectations() {
{
collection.find(searchObject);
result = cursor;

cursor.count();
result = 3;
}
};

HashMap<String, List<Condition>> filters = new HashMap<>();
filters.put("key1", Arrays.asList(new Condition[] { new Condition(Operation.EQUALS, "value1") }));
int count = createTestBean().countAllAssets(filters, null);
assertEquals(3, count);
}

@Test
public void testCountAllAssetsWithSearch(final @Mocked DBCollection collection, final @Injectable DBCursor cursor) {
BasicDBList list = new BasicDBList();
list.add(new BasicDBObject("key1", "value1"));
list.add(new BasicDBObject("$text", new BasicDBObject("$search", "foo")));
final BasicDBObject searchObject = new BasicDBObject("$and", list);

new Expectations() {
{
collection.find(searchObject);
result = cursor;

cursor.count();
result = 3;
}
};

HashMap<String, List<Condition>> filters = new HashMap<>();
filters.put("key1", Arrays.asList(new Condition[] { new Condition(Operation.EQUALS, "value1") }));
int count = createTestBean().countAllAssets(filters, "foo");
assertEquals(3, count);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.ibm.ws.lars.rest.model.Asset;
import com.ibm.ws.lars.rest.model.Attachment;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;

public class PersistenceBeanLoggingTest {

Expand Down Expand Up @@ -144,4 +145,22 @@ public void testFindAttachmentsForAsset() {
createTestBean().findAttachmentsForAsset(NON_EXISTENT_ID);
}

@Test
public void testQueryCount(@Mocked final DBCursor cursor) {
final BasicDBObject filterObject = new BasicDBObject("key1", "value1");
new Expectations() {
{
logger.isLoggable(Level.FINE);
result = true;

logger.fine("queryCount: Querying database with query object " + filterObject);

cursor.count();
result = 3;

logger.fine("queryCount: found 3 assets.");
}
};
Deencapsulation.invoke(createTestBean(), "queryCount", filterObject);
}
}
35 changes: 35 additions & 0 deletions server/src/test/java/com/ibm/ws/lars/rest/PersistenceBeanTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,41 @@ public void testSortOptions() throws Exception {
assertThat(collatePages(page1, page2), contains(asset1, asset2, asset3, asset4));
}

@Test
public void testCountAllAssets() throws Exception {
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"hot\", \"ground\":\"flat\", \"name\":\"hot and flat\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"hot\", \"ground\":\"hilly\", \"name\":\"hot and hilly\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"hot\", \"ground\":\"mountainous\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"cold\", \"ground\":\"flat\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"cold\", \"ground\":\"hilly\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"cold\", \"ground\":\"mountainous\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"warm\", \"ground\":\"flat\", \"name\":\"warm and flat\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"warm\", \"ground\":\"hilly\"}"));
persistenceBean.createAsset(Asset.deserializeAssetFromJson("{\"weather\":\"warm\", \"ground\":\"mountainous\"}"));

Map<String, List<Condition>> emptyFilter = Collections.emptyMap();

// Test counting all assets
int result = persistenceBean.countAllAssets(emptyFilter, null);
assertEquals(9, result);

// Test counting assets with a filter
Map<String, List<Condition>> filter = new HashMap<>();
filter.put("weather", Arrays.asList(eq("hot")));
result = persistenceBean.countAllAssets(filter, null);
assertEquals(3, result);

// Test counting assets with a search
result = persistenceBean.countAllAssets(emptyFilter, "flat");
assertEquals(2, result);

// Test counting assets with a filter and a search
filter.clear();
filter.put("weather", Arrays.asList(eq("hot")));
result = persistenceBean.countAllAssets(filter, "flat");
assertEquals(1, result);
}

/**
* Collate the contents of several AssetLists into one List.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,26 @@ public void testGetAssets(@Mocked final Logger logger, @Mocked final UriInfo inf
getRestResource().getAssets(info);
}

@Test
public void testCountAssets(@Mocked final Logger logger, @Mocked final UriInfo info) throws URISyntaxException, InvalidParameterException {

new Expectations() {
{
info.getQueryParameters(false);

logger.isLoggable(Level.FINE);
result = true;

info.getRequestUri();
result = new URI("http://localhost:9085/ma/v1/assets?foo=bar");

logger.fine("countAssets called with query parameters: foo=bar");
}
};

getRestResource().countAssets(info);
}

@Test
public void testPostAssets(@Mocked final Logger logger) {

Expand Down