>From f88124209eec90fd3b1a2bbb9f1347fa1932232c Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Thu, 9 Jun 2016 08:51:57 -0500
Subject: [PATCH] Fixed VLV usage in TPS token and activity services.

The TPS token and activity services have been modified to use VLV
only when the search filter matches the VLV, which is the default
filter when there is no search keyword/attributes specified by
the client. In other cases the services will use a normal search.

https://fedorahosted.org/pki/ticket/2342
---
 .../dogtagpki/server/tps/rest/ActivityService.java | 79 +++++++++++++++-----
 .../dogtagpki/server/tps/rest/TokenService.java    | 84 +++++++++++++++++-----
 2 files changed, 128 insertions(+), 35 deletions(-)

diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java b/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java
index dbf5f8d63e7004f9ba9a71ea94d4105b765a9a1c..d9b4939cca027fe9e086be64ab4db3c802f41be0 100644
--- a/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java
+++ b/base/tps/src/org/dogtagpki/server/tps/rest/ActivityService.java
@@ -21,6 +21,7 @@ package org.dogtagpki.server.tps.rest;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URLEncoder;
+import java.util.Iterator;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.Context;
@@ -120,32 +121,20 @@ public class ActivityService extends PKIService implements ActivityResource {
         try {
             TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
             ActivityDatabase database = subsystem.getActivityDatabase();
-
-            IDBVirtualList<ActivityRecord> list = database.findRecords(filter, null, new String[] { "-date" }, size);
-            int total = list.getSize();
-
             ActivityCollection response = new ActivityCollection();
 
-            // return entries in the requested page
-            for (int i = start; i < start + size && i < total; i++) {
-                ActivityRecord record = list.getElementAt(i);
-
-                if (record == null) {
-                    CMS.debug("ActivityService: Activity record not found");
-                    throw new PKIException("Activity record not found");
-                }
-
-                response.addEntry(createActivityData(record));
+            if (filter == null) {
+                findActivitiesWithVLV(database, start, size, response);
+            } else {
+                findActivities(database, filter, start, size, response);
             }
 
-            response.setTotal(total);
-
             if (start > 0) {
                 URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start - size, 0)).build();
                 response.addLink(new Link("prev", uri));
             }
 
-            if (start+size < total) {
+            if (start + size < response.getTotal()) {
                 URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start + size).build();
                 response.addLink(new Link("next", uri));
             }
@@ -158,6 +147,62 @@ public class ActivityService extends PKIService implements ActivityResource {
         }
     }
 
+    public void findActivitiesWithVLV(
+            ActivityDatabase database,
+            Integer start,
+            Integer size,
+            ActivityCollection response) throws Exception {
+
+        // search with VLV sorted by date in reverse order
+        IDBVirtualList<ActivityRecord> list = database.findRecords(
+                null, null, new String[] { "-date" }, size);
+
+        int total = list.getSize();
+
+        // return entries in the requested page
+        for (int i = start; i < start + size && i < total; i++) {
+            ActivityRecord record = list.getElementAt(i);
+
+            if (record == null) {
+                CMS.debug("ActivityService: Activity record not found");
+                throw new PKIException("Activity record not found");
+            }
+
+            response.addEntry(createActivityData(record));
+        }
+
+        response.setTotal(total);
+    }
+
+    public void findActivities(
+            ActivityDatabase database,
+            String filter,
+            Integer start,
+            Integer size,
+            ActivityCollection response) throws Exception {
+
+        // search without VLV
+        Iterator<ActivityRecord> activities = database.findRecords(filter).iterator();
+
+        // TODO: sort results by date in reverse order
+
+        int i = 0;
+
+        // skip to the start of the page
+        for (; i < start && activities.hasNext(); i++)
+            activities.next();
+
+        // return entries in the requested page
+        for (; i < start + size && activities.hasNext(); i++) {
+            ActivityRecord record = activities.next();
+            response.addEntry(createActivityData(record));
+        }
+
+        // count the total entries
+        for (; activities.hasNext(); i++) activities.next();
+        response.setTotal(i);
+    }
+
     @Override
     public Response getActivity(String activityID) {
 
diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
index 8e508aac8e05ebde92bc7c013c1c7a0f9d5d0870..1905bce3b284f75750bec373a387281882ef7a81 100644
--- a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
+++ b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
@@ -24,6 +24,7 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
@@ -267,33 +268,20 @@ public class TokenService extends PKIService implements TokenResource {
         try {
             TPSSubsystem subsystem = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID);
             TokenDatabase database = subsystem.getTokenDatabase();
-
-            IDBVirtualList<TokenRecord> list = database.findRecords(
-                    filter, null, new String[] { "-modifyTimestamp", "-createTimestamp" }, size);
-            int total = list.getSize();
-
             TokenCollection response = new TokenCollection();
 
-            // return entries up to the page size
-            for (int i = start; i < start + size && i < total; i++) {
-                TokenRecord record = list.getElementAt(i);
-
-                if (record == null) {
-                    CMS.debug("TokenService: Token record not found");
-                    throw new PKIException("Token record not found");
-                }
-
-                response.addEntry(createTokenData(record));
+            if (filter == null && attributes.isEmpty()) {
+                findTokensWithVLV(database, start, size, response);
+            } else {
+                findTokens(database, filter, attributes, start, size, response);
             }
 
-            response.setTotal(total);
-
             if (start > 0) {
                 URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start - size, 0)).build();
                 response.addLink(new Link("prev", uri));
             }
 
-            if (start + size < total) {
+            if (start + size < response.getTotal()) {
                 URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start + size).build();
                 response.addLink(new Link("next", uri));
             }
@@ -316,6 +304,66 @@ public class TokenService extends PKIService implements TokenResource {
         }
     }
 
+    public void findTokensWithVLV(
+            TokenDatabase database,
+            Integer start,
+            Integer size,
+            TokenCollection response) throws Exception {
+
+        // search with VLV sorted by date in reverse order
+        IDBVirtualList<TokenRecord> list = database.findRecords(
+                null, null, new String[] { "-modifyTimestamp", "-createTimestamp" }, size);
+
+        int total = list.getSize();
+
+        // return entries in the requested page
+        for (int i = start; i < start + size && i < total; i++) {
+            TokenRecord record = list.getElementAt(i);
+
+            if (record == null) {
+                CMS.debug("TokenService: Token record not found");
+                throw new PKIException("Token record not found");
+            }
+
+            response.addEntry(createTokenData(record));
+        }
+
+        response.setTotal(total);
+    }
+
+    public void findTokens(
+            TokenDatabase database,
+            String filter,
+            Map<String, String> attributes,
+            Integer start,
+            Integer size,
+            TokenCollection response) throws Exception {
+
+        // search without VLV
+        Iterator<TokenRecord> tokens = database.findRecords(filter, attributes).iterator();
+
+        // TODO: sort results by date in reverse order
+
+        int i = 0;
+
+        // skip to the start of the page
+        for (; i < start && tokens.hasNext(); i++)
+            tokens.next();
+
+        // return entries in the requested page
+        for (; i < start + size && tokens.hasNext(); i++) {
+            TokenRecord record = tokens.next();
+
+            response.addEntry(createTokenData(record));
+        }
+
+        // count the total entries
+        for (; tokens.hasNext(); i++)
+            tokens.next();
+
+        response.setTotal(i);
+    }
+
     @Override
     public Response getToken(String tokenID) {
 
-- 
2.4.11

