Introduced experimental X-Index-Revision header

Change-Id: Ida1bf82a59217ff8953cef0e1e5e2c5276f04a39
diff --git a/core/Changes b/core/Changes
index 51e40ed..e5fb999 100644
--- a/core/Changes
+++ b/core/Changes
@@ -8,6 +8,8 @@
 29/05/2020
    - Improved conversion tool to deal with Cosmas-II VC definitions
      (diewald)
+02/06/2020
+   - Introduced experimental X-Index-Revision header (diewald)
 
 # version 0.62.3
 03/12/2019
diff --git a/core/pom.xml b/core/pom.xml
index c7b4e8b..334f9dc 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -298,7 +298,7 @@
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Krill</artifactId>
-			<version>[0.59.1,)</version>
+			<version>[0.59.2,)</version>
 			<exclusions>
 				<exclusion>
 					<groupId>org.glassfish.jersey.containers</groupId>
diff --git a/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java b/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
index a40cbda..2d414f9 100644
--- a/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
+++ b/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
@@ -437,5 +437,11 @@
                     "Admin token is incorrect");
         }
     }
-    
+
+    /**
+     * Return the fingerprint of the latest index revision.
+     */
+    public String getIndexFingerprint () {
+        return searchKrill.getIndexFingerprint();
+    }
 }
diff --git a/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java b/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java
index 694e57b..ef016a1 100644
--- a/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java
+++ b/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java
@@ -95,4 +95,11 @@
         }
         return stats;
     }
+
+    /**
+     * Return the fingerprint of the latest index revision.
+     */
+    public String getIndexFingerprint () {
+        return searchKrill.getIndexFingerprint();
+    }
 }
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java b/core/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
index bac5912..8096c77 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
@@ -359,4 +359,15 @@
                 .append(textID);
         return sb.toString();
     };
+
+    /**
+     * Return the fingerprint of the latest index revision.
+     */
+    public String getIndexFingerprint() {
+        if (index != null) {
+            return index.getFingerprint();
+        };
+        return "null";
+    }
+
 };
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index 3329a4f..128a0de 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -71,7 +71,10 @@
     @GET
     @Path("{version}")
     public Response index (){
-        return Response.ok(config.getApiWelcomeMessage()).build();
+        return Response
+            .ok(config.getApiWelcomeMessage())
+            .header("X-Index-Revision", searchService.getIndexFingerprint())
+            .build();
     }
     
     @POST
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java b/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
index 9105af3..229fb08 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
@@ -82,7 +82,11 @@
             if (DEBUG) {
                 jlog.debug("Stats: " + stats);
             }
-            return Response.ok(stats).build();
+
+            return Response
+                .ok(stats)
+                .header("X-Index-Revision", service.getIndexFingerprint())
+                .build();
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -96,7 +100,10 @@
             String koralQuery) {
         try {
             String stats = service.retrieveStatisticsForKoralQuery(koralQuery);
-            return Response.ok(stats).build();
+            return Response
+                .ok(stats)
+                .header("X-Index-Revision", service.getIndexFingerprint())
+                .build();
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
index a97ab50..829ed63 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
@@ -62,6 +62,11 @@
                 .get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
+
         String message = response.getEntity(String.class);
         assertEquals(message, config.getApiWelcomeMessage());
     }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
index 8ac68fa..f7ad853 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
@@ -35,6 +35,11 @@
 
         assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
 
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
+
         String ent = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
         assertEquals(node.get("documents").asInt(),0);
@@ -187,6 +192,11 @@
                         + "\"match:eq\", \"type\": \"type:regex\", \"value\": "
                         + "\"CC-BY.*\"} }");
 
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
+        
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                      response.getStatus());
         String ent = response.getEntity(String.class);
diff --git a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteSearchControllerTest.java b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteSearchControllerTest.java
index 54367ab..4c2dd28 100644
--- a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteSearchControllerTest.java
+++ b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteSearchControllerTest.java
@@ -91,6 +91,10 @@
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
         String message = response.getEntity(String.class);
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
         assertEquals(message, config.getApiWelcomeMessage());
     }
 
diff --git a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
index 0d56d92..8619003 100644
--- a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
+++ b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
@@ -7,6 +7,7 @@
 
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.junit.Test;
 
@@ -28,6 +29,12 @@
                 .method("GET", ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
+
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
+        
         String query = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(query);
         assertEquals(2, node.at("/documents").asInt());
@@ -120,6 +127,11 @@
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                      response.getStatus());
         String ent = response.getEntity(String.class);
+
+        assertEquals(
+            "Wes8Bd4h1OypPqbWF5njeQ==",
+            response.getMetadata().getFirst("X-Index-Revision")
+            );
         
         JsonNode node = JsonUtils.readTree(ent);
         assertEquals(2, node.at("/documents").asInt());