Add VC rewrite for statistics web-service #796

Change-Id: I6d76cabeec833f685aaceade0724738681ed85c3
diff --git a/src/main/java/de/ids_mannheim/korap/core/service/BasicService.java b/src/main/java/de/ids_mannheim/korap/core/service/BasicService.java
index e833321..da07290 100644
--- a/src/main/java/de/ids_mannheim/korap/core/service/BasicService.java
+++ b/src/main/java/de/ids_mannheim/korap/core/service/BasicService.java
@@ -2,8 +2,31 @@
 
 import java.util.List;
 
-public class BasicService {
+import org.springframework.beans.factory.annotation.Autowired;
 
+import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.authentication.AuthenticationManager;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
+import de.ids_mannheim.korap.web.SearchKrill;
+import jakarta.ws.rs.core.HttpHeaders;
+
+public class BasicService {
+	
+	@Autowired
+	protected SearchKrill searchKrill;
+    @Autowired
+    protected KustvaktConfiguration config;
+    
+	@Autowired
+    protected AuthenticationManager authenticationManager;
+	
+	protected static final boolean DEBUG = false;
+	
     protected String combineMultipleCorpusQuery (List<String> cqList) {
         String combinedCorpusQuery = null;
         if (cqList != null && cqList.size() > 0) {
@@ -14,4 +37,56 @@
         }
         return combinedCorpusQuery;
     }
+    
+    protected User createUser (String username, HttpHeaders headers)
+            throws KustvaktException {
+        User user = authenticationManager.getUser(username);
+        authenticationManager.setAccessAndLocation(user, headers);
+//        if (DEBUG) {
+//            if (user != null) {
+//                jlog.debug("Debug: user location=" + user.locationtoString()
+//                        + ", access=" + user.getCorpusAccess());
+//            }
+//        }
+        return user;
+    }
+    
+	protected String buildKoralQueryFromCorpusQuery (List<String> cqList)
+			throws KustvaktException {
+		KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+		String cq = combineMultipleCorpusQuery(cqList);
+		String json = null;
+		if (cq != null && !cq.isEmpty()) {
+			builder.with(cq);
+			json = builder.toJSON();
+		}
+
+		if (json != null) {
+			checkVC(json);
+		}
+		return json;
+	}
+	
+    protected void checkVC (String json) throws KustvaktException {
+        JsonNode node = JsonUtils.readTree(json);
+        node = node.at("/collection");
+        if (node.has("ref")) {
+            String vcName = node.path("ref").asText();
+            if (vcName.contains("/")) {
+                String[] names = vcName.split("/");
+                if (names.length == 2) {
+                    vcName = names[1];
+                }
+            }
+
+            String vcInCaching = config.getVcInCaching();
+            if (vcName.equals(vcInCaching)) {
+                throw new KustvaktException(
+                        de.ids_mannheim.korap.exceptions.StatusCodes.CACHING_VC,
+                        "VC is currently busy and unaccessible due to "
+                                + "caching process",
+                        node.get("ref").asText());
+            }
+        }
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java b/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
index 8e8c127..8647962 100644
--- a/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
+++ b/src/main/java/de/ids_mannheim/korap/core/service/SearchService.java
@@ -20,8 +20,6 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
-//import de.ids_mannheim.de.init.VCLoader;
-import de.ids_mannheim.korap.authentication.AuthenticationManager;
 import de.ids_mannheim.korap.config.KustvaktCacheable;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -34,7 +32,6 @@
 import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.ClientsHandler;
-import de.ids_mannheim.korap.web.SearchKrill;
 import jakarta.annotation.PostConstruct;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MultivaluedHashMap;
@@ -50,27 +47,19 @@
             super("total_results", "key:hashedKoralQuery");
         }
     }
-
     private static final boolean DEBUG = false;
 
     private static Logger jlog = LogManager.getLogger(SearchService.class);
 
     @Autowired
-    private KustvaktConfiguration config;
-    @Autowired
-    private AuthenticationManager authenticationManager;
-
-    @Autowired
-    private RewriteHandler rewriteHandler;
-
-    @Autowired
-    private SearchKrill searchKrill;
-    @Autowired
     private SearchNetworkEndpoint searchNetwork;
 
     private ClientsHandler graphDBhandler;
 
     private TotalResultCache totalResultCache;
+    
+    @Autowired
+	protected RewriteHandler rewriteHandler;
 
     @PostConstruct
     private void doPostConstruct () {
@@ -113,19 +102,6 @@
         return query;
     }
 
-    private User createUser (String username, HttpHeaders headers)
-            throws KustvaktException {
-        User user = authenticationManager.getUser(username);
-        authenticationManager.setAccessAndLocation(user, headers);
-        if (DEBUG) {
-            if (user != null) {
-                jlog.debug("Debug: user location=" + user.locationtoString()
-                        + ", access=" + user.getCorpusAccess());
-            }
-        }
-        return user;
-    }
-
     public String search (String jsonld, String username, HttpHeaders headers)
             throws KustvaktException {
 
diff --git a/src/main/java/de/ids_mannheim/korap/core/service/StatisticService.java b/src/main/java/de/ids_mannheim/korap/core/service/StatisticService.java
index f7fadb1..54452fa 100644
--- a/src/main/java/de/ids_mannheim/korap/core/service/StatisticService.java
+++ b/src/main/java/de/ids_mannheim/korap/core/service/StatisticService.java
@@ -5,27 +5,28 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import com.fasterxml.jackson.databind.JsonNode;
-
-import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
-import de.ids_mannheim.korap.web.SearchKrill;
+import de.ids_mannheim.korap.rewrite.RewriteHandler;
+import de.ids_mannheim.korap.user.User;
+import jakarta.ws.rs.core.HttpHeaders;
 
 @Service
 public class StatisticService extends BasicService {
 
-    @Autowired
-    private SearchKrill searchKrill;
-    @Autowired
-    private KustvaktConfiguration config;
-
-	public String retrieveStatisticsForCorpusQuery (List<String> cqList)
-			throws KustvaktException {
+	@Autowired
+	private RewriteHandler statisticsRewriteHandler;
+	
+	public String retrieveStatisticsForCorpusQuery (List<String> cqList,
+			String username, HttpHeaders headers) throws KustvaktException {
 
 		String json = buildKoralQueryFromCorpusQuery(cqList);
+		//System.out.println("Before:" + json + "\n");
+		if (!cqList.isEmpty() && !combineMultipleCorpusQuery(cqList).isEmpty()) {
+			User user = createUser(username, headers);
+			json = statisticsRewriteHandler.processQuery(json, user);
+		}
+		//System.out.println("After:" + json);
 		String stats = searchKrill.getStatistics(json);
 
 		if (stats.contains("-1")) {
@@ -34,46 +35,6 @@
 		return stats;
 	}
 
-	public String buildKoralQueryFromCorpusQuery (List<String> cqList)
-			throws KustvaktException {
-		KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
-		String cq = combineMultipleCorpusQuery(cqList);
-		String json = null;
-		if (cq != null && !cq.isEmpty()) {
-			builder.with(cq);
-			json = builder.toJSON();
-		}
-
-		if (json != null) {
-			checkVC(json);
-		}
-		return json;
-	}
-    
-
-    private void checkVC (String json) throws KustvaktException {
-        JsonNode node = JsonUtils.readTree(json);
-        node = node.at("/collection");
-        if (node.has("ref")) {
-            String vcName = node.path("ref").asText();
-            if (vcName.contains("/")) {
-                String[] names = vcName.split("/");
-                if (names.length == 2) {
-                    vcName = names[1];
-                }
-            }
-
-            String vcInCaching = config.getVcInCaching();
-            if (vcName.equals(vcInCaching)) {
-                throw new KustvaktException(
-                        de.ids_mannheim.korap.exceptions.StatusCodes.CACHING_VC,
-                        "VC is currently busy and unaccessible due to "
-                                + "caching process",
-                        node.get("ref").asText());
-            }
-        }
-    }
-
     public String retrieveStatisticsForKoralQuery (String koralQuery)
             throws KustvaktException {
         String stats = null;
diff --git a/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java b/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java
index 965f99e..398e947 100644
--- a/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java
+++ b/src/main/java/de/ids_mannheim/korap/core/web/controller/StatisticController.java
@@ -10,8 +10,10 @@
 
 import de.ids_mannheim.korap.core.service.StatisticService;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.web.CoreResponseHandler;
 import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.utils.ResourceFilters;
 import jakarta.ws.rs.Consumes;
 import jakarta.ws.rs.GET;
@@ -20,6 +22,7 @@
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.QueryParam;
 import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
@@ -35,7 +38,7 @@
  */
 @Controller
 @Path("{version}/statistics/")
-@ResourceFilters({ APIVersionFilter.class})
+@ResourceFilters({ APIVersionFilter.class, DemoUserFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class StatisticController {
 
@@ -63,13 +66,18 @@
      * @return statistics of the virtual corpus defined by the given
      *         corpusQuery parameter.
      */
-    @GET
-    public Response getStatistics (@Context SecurityContext context,
-            @Context Locale locale, @QueryParam("cq") List<String> cq) {
+	@GET
+	public Response getStatistics (@Context SecurityContext securityContext,
+			@Context Locale locale, @Context HttpHeaders headers,
+			@QueryParam("cq") List<String> cq) {
+
+		TokenContext context = (TokenContext) securityContext
+				.getUserPrincipal();
 
         String stats;
         try {
-            stats = service.retrieveStatisticsForCorpusQuery(cq);
+			stats = service.retrieveStatisticsForCorpusQuery(cq,
+					context.getUsername(), headers);
             if (DEBUG) {
                 jlog.debug("Stats: " + stats);
             }
diff --git a/src/main/java/de/ids_mannheim/korap/service/QueryService.java b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
index e3591c3..7cfa9cd 100644
--- a/src/main/java/de/ids_mannheim/korap/service/QueryService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
@@ -23,7 +23,7 @@
 import de.ids_mannheim.korap.constant.PrivilegeType;
 import de.ids_mannheim.korap.constant.QueryType;
 import de.ids_mannheim.korap.constant.ResourceType;
-import de.ids_mannheim.korap.core.service.StatisticService;
+import de.ids_mannheim.korap.core.service.BasicService;
 import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.dao.QueryDao;
 import de.ids_mannheim.korap.dao.RoleDao;
@@ -68,7 +68,7 @@
  *
  */
 @Service
-public class QueryService {
+public class QueryService extends BasicService {
 
     public static Logger jlog = LogManager.getLogger(QueryService.class);
 
@@ -90,8 +90,6 @@
     private AdminDao adminDao;
     @Autowired
     private UserGroupService userGroupService;
-    @Autowired
-    private StatisticService statisticService;
     
     @Autowired
     private SearchKrill krill;
@@ -154,8 +152,7 @@
 				if (query.isCached()) {
 					List<String> cqList = new ArrayList<>(1);
 					cqList.add("referTo " + query.getName());
-					json = statisticService
-							.buildKoralQueryFromCorpusQuery(cqList);
+					json = buildKoralQueryFromCorpusQuery(cqList);
 				}
 				else {
 					json = query.getKoralQuery();
@@ -699,8 +696,7 @@
 			if (query.isCached()) {
 				List<String> cqList = new ArrayList<>(1);
 				cqList.add("referTo " + query.getName());
-				json = statisticService
-						.buildKoralQueryFromCorpusQuery(cqList);
+				json = buildKoralQueryFromCorpusQuery(cqList);
 			}
 			else { 
 				json = query.getKoralQuery();
@@ -709,7 +705,7 @@
 		}
         return converter.createQueryDto(query, statistics);
     }
-
+	
     //EM: unused
 	@Deprecated
     public QueryDto searchQueryById (String username, int queryId)
diff --git a/src/test/java/de/ids_mannheim/korap/rewrite/FoundryRewriteTest.java b/src/test/java/de/ids_mannheim/korap/rewrite/FoundryRewriteTest.java
index 51e7fc5..15c3d7a 100644
--- a/src/test/java/de/ids_mannheim/korap/rewrite/FoundryRewriteTest.java
+++ b/src/test/java/de/ids_mannheim/korap/rewrite/FoundryRewriteTest.java
@@ -38,7 +38,7 @@
     public KustvaktConfiguration config;
 
     @Autowired
-    public RewriteHandler handler;
+    public RewriteHandler rewriteHandler;
 
     @Autowired
     private LayerMapper m;
@@ -79,7 +79,7 @@
         String username = "bubbles";
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[pos=ADJA]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(),
+        String result = rewriteHandler.processQuery(s.toJSON(),
                 new KorAPUser(username));
         JsonNode node = JsonUtils.readTree(result);
         assertEquals(node.at("/query/wrap/foundry").asText(), "corenlp");
@@ -93,7 +93,7 @@
         String username = "bubbles";
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[base=Haus]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(),
+        String result = rewriteHandler.processQuery(s.toJSON(),
                 new KorAPUser(username));
         JsonNode node = JsonUtils.readTree(result);
         // EM: only for testing, in fact, opennlp lemma does not
@@ -117,7 +117,7 @@
             throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[base=Haus]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         assertNotNull(node);
         assertFalse(node.at("/query/wrap/foundry").isMissingNode());
@@ -134,7 +134,7 @@
             throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[pos=ADJA]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         assertNotNull(node);
         assertFalse(node.at("/query/wrap/foundry").isMissingNode());
@@ -151,7 +151,7 @@
             throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[orth=laufe/i & base!=Lauf]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         assertNotNull(node);
         assertEquals(node.at("/query/wrap/@type").asText(), "koral:termGroup");
@@ -166,7 +166,7 @@
             throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[(base=laufen | tt/pos=VVFIN)]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         assertNotNull(node);
         assertEquals(node.at("/query/wrap/@type").asText(), "koral:termGroup");
@@ -180,7 +180,7 @@
     public void testFoundryBaseRewrite () throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[orth=laufen]", "poliqarp");
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         assertEquals(node.at("/query/wrap/@type").asText(), "koral:term");
         assertFalse(node.at("/query/wrap/foundry").isMissingNode());
diff --git a/src/test/java/de/ids_mannheim/korap/rewrite/QueryContextRewriteTest.java b/src/test/java/de/ids_mannheim/korap/rewrite/QueryContextRewriteTest.java
index 699fba2..04bcf43 100644
--- a/src/test/java/de/ids_mannheim/korap/rewrite/QueryContextRewriteTest.java
+++ b/src/test/java/de/ids_mannheim/korap/rewrite/QueryContextRewriteTest.java
@@ -19,7 +19,7 @@
 public class QueryContextRewriteTest extends SpringJerseyTest {
     
     @Autowired
-    public RewriteHandler handler;
+    public RewriteHandler rewriteHandler;
     
     @Autowired
     private KustvaktConfiguration config;
@@ -61,7 +61,7 @@
         assertEquals(60, context.at("/left/1").asInt());
         assertEquals(60, context.at("/right/1").asInt());
         
-        String result = handler.processQuery(s.toJSON(), new KorAPUser("test"));
+        String result = rewriteHandler.processQuery(s.toJSON(), new KorAPUser("test"));
         JsonNode node = JsonUtils.readTree(result);
         
         context = node.at("/meta/context");
diff --git a/src/test/java/de/ids_mannheim/korap/rewrite/ResultRewriteTest.java b/src/test/java/de/ids_mannheim/korap/rewrite/ResultRewriteTest.java
index ba2cbfd..a7507fd 100644
--- a/src/test/java/de/ids_mannheim/korap/rewrite/ResultRewriteTest.java
+++ b/src/test/java/de/ids_mannheim/korap/rewrite/ResultRewriteTest.java
@@ -18,13 +18,13 @@
 public class ResultRewriteTest extends SpringJerseyTest {
 
     @Autowired
-    public RewriteHandler ha;
+    public RewriteHandler rewriteHandler;
 
     @Test
     public void testPostRewriteNothingToDo () throws KustvaktException {
-        assertEquals(true, ha.add(AvailabilityRewrite.class),
+        assertEquals(true, rewriteHandler.add(AvailabilityRewrite.class),
                 "Handler could not be added to rewrite handler instance!");
-        String v = ha.processResult(TestVariables.RESULT, null);
+        String v = rewriteHandler.processResult(TestVariables.RESULT, null);
         assertEquals(JsonUtils.readTree(TestVariables.RESULT),
                 JsonUtils.readTree(v), "results do not match");
     }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
index 6ddc583..6c68ce6 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
@@ -193,17 +193,4 @@
         assertEquals(772, node.at("/paragraphs").asInt());
     }
     
-    @Test
-    public void testStatisticsWithNamedVC () throws KustvaktException {
-        Response response = target().path(API_VERSION).path("statistics")
-                .queryParam("cq", "referTo unknownVC")
-                .request().method("GET");
-        String ent = response.readEntity(String.class);
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-        JsonNode node = JsonUtils.readTree(ent);
-        assertEquals(0, node.at("/documents").asInt());
-        assertEquals(0, node.at("/tokens").asInt());
-        assertEquals(0, node.at("/sentences").asInt());
-        assertEquals(0, node.at("/paragraphs").asInt());
-    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
index c7a3eec..9946649 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
@@ -120,11 +120,41 @@
         Response response = target().path(API_VERSION).path("statistics")
                 .queryParam("cq", corpusQuery).request().get();
         String ent = response.readEntity(String.class);
+        assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+        JsonNode node = JsonUtils.readTree(ent);
+		assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+				node.at("/errors/0/0").asInt());
+        assertEquals("Virtual corpus system/unknown-vc is not found.", 
+        		node.at("/errors/0/1").asText());
+		assertEquals("system/unknown-vc", node.at("/errors/0/2").asText());
+    }
+    
+    @Test
+    public void testStatisticsWithUserUnknownVC () throws KustvaktException {
+        String corpusQuery = "referTo \"nemo/unknown-vc\"";
+        Response response = target().path(API_VERSION).path("statistics")
+                .queryParam("cq", corpusQuery).request().get();
+        String ent = response.readEntity(String.class);
+        assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+        JsonNode node = JsonUtils.readTree(ent);
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+				node.at("/errors/0/0").asInt());
+        assertEquals("Virtual corpus nemo/unknown-vc is not found.", 
+        		node.at("/errors/0/1").asText());
+		assertEquals("nemo/unknown-vc", node.at("/errors/0/2").asText());
+    }
+    
+    private void testStatisticsWithUserVC (String vcName) throws KustvaktException {
+        String corpusQuery = "referTo \"marlin/"+vcName+"\"";
+        Response response = target().path(API_VERSION).path("statistics")
+                .queryParam("cq", corpusQuery).request().get();
+        String ent = response.readEntity(String.class);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         JsonNode node = JsonUtils.readTree(ent);
-        assertEquals(0, node.at("/documents").asInt());
-        assertEquals(0, node.at("/tokens").asInt());
-        assertEquals(0, node.at("/sentences").asInt());
+        assertEquals(11, node.at("/documents").asInt());
+        assertEquals(665842, node.at("/tokens").asInt());
+        assertEquals(25074, node.at("/sentences").asInt());
+        assertEquals(772, node.at("/paragraphs").asInt());
     }
     
     @Test
@@ -155,10 +185,11 @@
 
     @Test
     public void testSearchWithRefPublishedVcGuest () throws KustvaktException {
+    	String vcName = "published-vc";
     	createMarlinPublishedVC();
         Response response = target().path(API_VERSION).path("search")
                 .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
-                .queryParam("cq", "referTo \"marlin/published-vc\"").request()
+                .queryParam("cq", "referTo \"marlin/"+vcName+"\"").request()
                 .get();
         String ent = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
@@ -178,14 +209,14 @@
                 node.at("/rewrites/0/original/@type").asText());
         assertEquals("marlin/published-vc",
                 node.at("/rewrites/0/original/ref").asText());
+        
+        testStatisticsWithUserVC(vcName);
+        testSearchWithRefPublishedVc(vcName);
+        
         deleteVC("published-vc", "marlin", "marlin");
     }
 
-    @Test
-    public void testSearchWithRefPublishedVc () throws KustvaktException {
-        String vcName = "marlin-published-vc";
-        createPublishedVC("marlin", vcName);
-
+    private void testSearchWithRefPublishedVc (String vcName) throws KustvaktException {
         Response response = target().path(API_VERSION).path("search")
                 .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
                 .queryParam("cq", "referTo \"marlin/" + vcName + "\"").request()
@@ -196,12 +227,17 @@
         JsonNode node = JsonUtils.readTree(ent);
         assertTrue(node.at("/matches").size() > 0);
 
+		node = node.at("/collection/rewrites/0");
+		assertEquals("operation:override", node.at("/operation").asText());
+		assertEquals("marlin/published-vc",
+				node.at("/original/ref").asText());
+		assertEquals("koral:docGroupRef", node.at("/original/@type").asText());
+        
         node = getHiddenGroup(vcName);
         assertEquals("system", node.at("/owner").asText());
         assertEquals(UserGroupStatus.HIDDEN.name(),
                 node.at("/status").asText());
         node = node.at("/members");
         assertEquals("squirt", node.at("/0/userId").asText());
-        deleteVC(vcName, "marlin", "marlin");
     }
 }
diff --git a/src/test/resources/log4j2-test.properties b/src/test/resources/log4j2-test.properties
index 186ab06..54fbc8b 100644
--- a/src/test/resources/log4j2-test.properties
+++ b/src/test/resources/log4j2-test.properties
@@ -20,7 +20,7 @@
 rootLogger.appenderRefs = console
 rootLogger.appenderRef.stdout.ref = STDOUT
 
-loggers=hibernate,auth,ldap
+loggers=hibernate,auth,ldap,krill
 #loggers=console
 #logger.console.name=com.sun.jersey.test.framework.spi.container
 #logger.console.level = info
@@ -52,4 +52,10 @@
 logger.ldap.level = info
 logger.ldap.appenderRefs = file
 logger.ldap.appenderRef.file.ref = LDAP_LOG
-logger.ldap.additivity=false
\ No newline at end of file
+logger.ldap.additivity=false
+
+logger.krill.name=de.ids_mannheim.korap.KrillCollection
+logger.krill.level = info
+logger.krill.appenderRefs = file
+logger.krill.appenderRef.file.ref = MAIN_LOG
+logger.krill.additivity=false
\ No newline at end of file
diff --git a/src/test/resources/test-config.xml b/src/test/resources/test-config.xml
index 343ca96..7a95588 100644
--- a/src/test/resources/test-config.xml
+++ b/src/test/resources/test-config.xml
@@ -81,6 +81,30 @@
 		<property name="testConnectionOnCheckout" value="true" />
 	</bean>
 
+<!-- <bean id="sqliteDataSource"
+		class="org.springframework.jdbc.datasource.SingleConnectionDataSource"
+		lazy-init="true">
+		<property name="driverClassName" value="${jdbc.driverClassName}" />
+		<property name="url" value="${jdbc.url}" />
+		<property name="username" value="${jdbc.username}" />
+		<property name="password" value="${jdbc.password}" />
+		<property name="connectionProperties">
+			<props>
+				<prop key="date_string_format">yyyy-MM-dd HH:mm:ss</prop>
+			</props>
+		</property>
+
+		Sqlite can only have a single connection
+		<property name="suppressClose">
+			<value>true</value>
+		</property>
+	</bean>
+ -->
+ 
+ <!-- <bean id='cacheManager' class='org.springframework.cache.ehcache.EhCacheCacheManager' 
+		p:cacheManager-ref='ehcache' /> <bean id='ehcache' class='org.springframework.cache.ehcache.EhCacheManagerFactoryBean' 
+		p:configLocation='classpath:ehcache.xml' p:shared='true' /> -->
+		
 	<!-- to configure database for sqlite, mysql, etc. migrations -->
 	<bean id="flywayConfig"
 		class="org.flywaydb.core.api.configuration.ClassicConfiguration">
@@ -213,6 +237,18 @@
 		class="de.ids_mannheim.korap.rewrite.RewriteHandler">
 		<constructor-arg ref="rewriteTasks" />
 	</bean>
+	
+	<util:list id="statisticsRewriteTasks"
+		value-type="de.ids_mannheim.korap.rewrite.RewriteTask">
+		<ref bean="foundryRewrite" />
+		<ref bean="virtualCorpusRewrite" />
+		<ref bean="queryReferenceRewrite" />
+	</util:list>
+	
+	<bean id="statisticsRewriteHandler"
+		class="de.ids_mannheim.korap.rewrite.RewriteHandler">
+		<constructor-arg ref="statisticsRewriteTasks" />
+	</bean>
 
 	<bean id="kustvaktResponseHandler"
 		class="de.ids_mannheim.korap.web.KustvaktResponseHandler">