Added API versioning backwards compability and tests.

Change-Id: I8a7b512bea67e07e449074a4d04c257b65ae1454
diff --git a/full/src/main/java/de/ids_mannheim/korap/server/KustvaktServer.java b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktServer.java
index 01da674..5e97ea1 100644
--- a/full/src/main/java/de/ids_mannheim/korap/server/KustvaktServer.java
+++ b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktServer.java
@@ -42,8 +42,7 @@
         if (kargs.getSpringConfig() == null){
             kargs.setSpringConfig("default-config.xml");
         }
-        rootPackages = "de.ids_mannheim.korap.web.utils;"
-                + "de.ids_mannheim.korap.web.service.full";
+        rootPackages = "de.ids_mannheim.korap.web;";
         server.start();
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/SearchService.java b/full/src/main/java/de/ids_mannheim/korap/service/SearchService.java
index 1aea369..e1c8ae8 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/SearchService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/SearchService.java
@@ -56,6 +56,7 @@
         this.graphDBhandler = new ClientsHandler(builder.build());
     }
 
+    @SuppressWarnings("unchecked")
     public String serializeQuery (String q, String ql, String v, String cq,
             Integer pageIndex, Integer startPage, Integer pageLength,
             String context, Boolean cutoff) {
@@ -91,6 +92,7 @@
         return searchKrill.search(jsonld);
     }
 
+    @SuppressWarnings("unchecked")
     public String search (String engine, String username, HttpHeaders headers,
             String q, String ql, String v, String cq, Integer pageIndex,
             Integer pageInteger, String ctx, Integer pageLength, Boolean cutoff)
@@ -123,7 +125,7 @@
         else {
             result = searchKrill.search(query);
         }
-        jlog.debug("Query result: " + result);
+//        jlog.debug("Query result: " + result);
         return result;
 
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/KustvaktController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/KustvaktController.java
index 37792b6..230afe1 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/KustvaktController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/KustvaktController.java
@@ -38,7 +38,7 @@
         
         Map m = new HashMap();
         m.put("version", ServiceInfo.getInfo().getVersion());
-        m.put("supported_api_version(s)", config.getVersion());
+        m.put("supported_api_version(s)", config.getSupportedVersions());
         m.put("service_name", ServiceInfo.getInfo().getName());
         try {
             return Response.ok(JsonUtils.toJSON(m)).build();
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index a74c83a..41e5e2c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -43,7 +43,7 @@
  * 
  */
 @Controller
-@Path("/{version}/")
+@Path("/")
 @ResourceFilters({ APIVersionFilter.class, AuthenticationFilter.class,
         DemoUserFilter.class, PiwikFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
@@ -83,7 +83,7 @@
      */
     // ref query parameter removed!
     @GET
-    @Path("query")
+    @Path("{version}/query")
     public Response serializeQuery (@Context Locale locale,
             @Context SecurityContext securityContext, @QueryParam("q") String q,
             @QueryParam("ql") String ql, @QueryParam("v") String v,
@@ -108,7 +108,7 @@
     }
 
     @POST
-    @Path("search")
+    @Path("{version}/search")
     public Response searchPost (@Context SecurityContext context,
             @Context Locale locale, @QueryParam("engine") String engine,
             String jsonld) {
@@ -127,7 +127,7 @@
     }
 
     @GET
-    @Path("search")
+    @Path("{version}/search")
     public Response searchGet (@Context SecurityContext securityContext,
             @Context HttpHeaders headers, @Context Locale locale,
             @QueryParam("q") String q, @QueryParam("ql") String ql,
@@ -156,7 +156,7 @@
     }
 
     @GET
-    @Path("/corpus/{corpusId}/{docId}/{textId}/{matchId}/matchInfo")
+    @Path("{version}/corpus/{corpusId}/{docId}/{textId}/{matchId}/matchInfo")
     public Response getMatchInfo (@Context SecurityContext ctx,
             @Context HttpHeaders headers, @Context Locale locale,
             @PathParam("corpusId") String corpusId,
@@ -184,7 +184,7 @@
     // This is currently identical to LiteService#getMeta(),
     // but may need auth code to work following policies
     @GET
-    @Path("/corpus/{corpusId}/{docId}/{textId}")
+    @Path("{version}/corpus/{corpusId}/{docId}/{textId}")
     public Response getMetadata (@PathParam("corpusId") String corpusId,
             @PathParam("docId") String docId, @PathParam("textId") String textId
     // @QueryParam("fields") Set<String> fields
@@ -195,7 +195,7 @@
     }
 
     @POST
-    @Path("colloc")
+    @Path("{version}/colloc")
     public Response getCollocationBase (@QueryParam("q") String query) {
         String result;
         try {
diff --git a/full/src/main/resources/kustvakt.conf b/full/src/main/resources/kustvakt.conf
index 0a1ddc3..3932b82 100644
--- a/full/src/main/resources/kustvakt.conf
+++ b/full/src/main/resources/kustvakt.conf
@@ -12,8 +12,9 @@
 ldap.config = file-path-to-ldap-config
 
 # Kustvakt
+current.api.version = v1.0
 # multiple versions separated by space
-supported.api.version = v0.1 v1.0
+supported.api.version = v1.0
 
 ## server
 server.port=8089
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/ApiVersionTest.java b/full/src/test/java/de/ids_mannheim/korap/web/ApiVersionTest.java
new file mode 100644
index 0000000..b8ca799
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/ApiVersionTest.java
@@ -0,0 +1,39 @@
+package de.ids_mannheim.korap.web;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.URI;
+
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.Test;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+
+public class ApiVersionTest extends SpringJerseyTest {
+
+    @Test
+    public void testSearchWithoutVersion () throws KustvaktException {
+        ClientResponse response = resource().path("api").path("search")
+                .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
+                .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+        assertEquals(HttpStatus.PERMANENT_REDIRECT_308, response.getStatus());
+        URI location = response.getLocation();
+        assertEquals("/api/v1.0/search", location.getPath());
+    }
+
+    @Test
+    public void testSearchWrongVersion () throws KustvaktException {
+        ClientResponse response = resource().path("api").path("v0.2")
+                .path("search").queryParam("q", "[orth=der]")
+                .queryParam("ql", "poliqarp").accept(MediaType.APPLICATION_JSON)
+                .get(ClientResponse.class);
+        assertEquals(HttpStatus.PERMANENT_REDIRECT_308, response.getStatus());
+        URI location = response.getLocation();
+        assertEquals("/api/v1.0/search", location.getPath());
+    }
+}
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index 304e649..9a522ba 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -12,6 +12,8 @@
 ldap.config = file-path-to-ldap-config
 
 # Kustvakt
+
+current.api.version = v1.0
 # multiple versions separated by space
 supported.api.version = v0.1 v1.0