Added Shutdown handler to Jetty server and fixed NamedVCLoader.

Change-Id: I18fe51031103deb966843cc248e154011efb8abe
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java b/core/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
index c318536..5ff29ea 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -15,6 +15,7 @@
 import de.ids_mannheim.korap.util.KrillProperties;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.Getter;
+import lombok.Setter;
 
 /**
  * if configuration class is extended, loadSubTypes method should be
@@ -27,6 +28,7 @@
  * - cleaned up log4j loader
  */
 
+@Setter
 @Getter
 public class KustvaktConfiguration {
 
@@ -89,6 +91,10 @@
     protected Pattern freeLicensePattern;
     protected Pattern allLicensePattern;
 
+    // random code generator
+    private String secureRandomAlgorithm;
+    private String messageDigestAlgorithm;
+    
     public KustvaktConfiguration (Properties properties) throws Exception {
         load(properties);
         KrillProperties.setProp(properties);
@@ -165,6 +171,13 @@
         // passcodeSaltField =
         // properties.getProperty("security.passcode.salt",
         // "accountCreation");
+        
+        setSecureRandomAlgorithm(properties
+                .getProperty("security.secure.random.algorithm", "SHA1PRNG"));
+
+        setMessageDigestAlgorithm(
+                properties.getProperty("security.md.algorithm", "MD5"));
+
     }
 
     /**
diff --git a/full/Changes b/full/Changes
index 5d23f15..c742c97 100644
--- a/full/Changes
+++ b/full/Changes
@@ -14,7 +14,10 @@
     - Added "fields" parameter to search controllers (margaretha)
     - Integrated lite controllers, services and tests in full version (margaretha)
 29/10/2018
-    - Moved javax.servlet-api to core
+    - Moved javax.servlet-api to core (margaretha)
+13/11/2018
+    - Added Shutdown handler to Jetty server (margaretha)
+    - Fixed storing VC order in NamedVCLoader (margaretha)  
 
 # version 0.61.2
 12/09/2018
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
index ba5a5a4..0b46164 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
@@ -63,8 +63,6 @@
     private boolean isSoftDeleteGroupMember;
 
     private EncryptionIface.Encryption secureHashAlgorithm;
-    private String secureRandomAlgorithm;
-    private String messageDigestAlgorithm;
 
     private AuthenticationMethod OAuth2passwordAuthentication;
     private String nativeClientHost;
@@ -83,7 +81,7 @@
     private RSAPrivateKey rsaPrivateKey;
     private JWKSet publicKeySet;
     private String rsaKeyId;
-    
+
     private String namedVCPath;
 
     public FullConfiguration (Properties properties) throws Exception {
@@ -107,9 +105,8 @@
         setOAuth2Configuration(properties);
         setOpenIdConfiguration(properties);
         setRSAKeys(properties);
-        
-        setNamedVCPath(properties
-                .getProperty("krill.namedVC", ""));
+
+        setNamedVCPath(properties.getProperty("krill.namedVC", ""));
     }
 
     private void setSecurityConfiguration (Properties properties) {
@@ -117,11 +114,6 @@
                 properties.getProperty("security.secure.hash.algorithm",
                         "BCRYPT")));
 
-        setSecureRandomAlgorithm(properties
-                .getProperty("security.secure.random.algorithm", "SHA1PRNG"));
-
-        setMessageDigestAlgorithm(
-                properties.getProperty("security.md.algorithm", "MD5"));
     }
 
     private void setOpenIdConfiguration (Properties properties)
@@ -321,7 +313,6 @@
         return list;
     }
 
-
     private Pattern compilePattern (String patternStr) {
         if (!patternStr.isEmpty()) {
             return Pattern.compile(patternStr);
@@ -634,22 +625,6 @@
         this.authorizationCodeExpiry = authorizationCodeExpiry;
     }
 
-    public String getSecureRandomAlgorithm () {
-        return secureRandomAlgorithm;
-    }
-
-    public void setSecureRandomAlgorithm (String secureRandomAlgorithm) {
-        this.secureRandomAlgorithm = secureRandomAlgorithm;
-    }
-
-    public String getMessageDigestAlgorithm () {
-        return messageDigestAlgorithm;
-    }
-
-    public void setMessageDigestAlgorithm (String messageDigestAlgorithm) {
-        this.messageDigestAlgorithm = messageDigestAlgorithm;
-    }
-
     public String getNamedVCPath () {
         return namedVCPath;
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java b/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
index 1e4c4c4..38f0fc9 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
@@ -61,7 +61,9 @@
             }
 
             String filename = file.getName();
-            String json = readFile(file, filename);
+            String[] strArr = readFile(file, filename);
+            filename = strArr[0];
+            String json = strArr[1];
             if (json != null) {
                 cacheVC(json, filename);
                 vcService.storeVC(filename, VirtualCorpusType.SYSTEM, json, null,
@@ -70,7 +72,7 @@
         }
     }
 
-    private String readFile (File file, String filename) throws IOException {
+    private String[] readFile (File file, String filename) throws IOException, KustvaktException {
         String json = null;
         long start = System.currentTimeMillis();
         if (filename.endsWith(".jsonld")) {
@@ -92,17 +94,22 @@
         }
         long end = System.currentTimeMillis();
         jlog.debug("READ " + filename + " duration: " + (end - start));
-        return json;
+        
+        return new String[]{filename, json};
     }
 
     private void cacheVC (String json, String filename)
             throws IOException, QueryException {
+        jlog.info("Create KrillCollection: "+filename);
         long start, end;
         start = System.currentTimeMillis();
 
         KrillCollection collection = new KrillCollection(json);
+        jlog.debug("Finished creating KrillCollection");
+        jlog.debug("Set Index to collection");
         collection.setIndex(searchKrill.getIndex());
-
+                
+        jlog.debug("StoreInCache "+filename);
         if (collection != null) {
             collection.storeInCache(filename);
         }
diff --git a/full/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java b/full/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
index 2b85f94..ea451aa 100644
--- a/full/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
+++ b/full/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
@@ -1,7 +1,5 @@
 package de.ids_mannheim.korap.encryption;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
@@ -14,7 +12,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import de.ids_mannheim.korap.config.FullConfiguration;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 
@@ -29,7 +27,7 @@
 public class RandomCodeGenerator {
 
     @Autowired
-    private FullConfiguration config;
+    public KustvaktConfiguration config;
 
     public static SecureRandom secureRandom;
 
@@ -39,6 +37,13 @@
                 SecureRandom.getInstance(config.getSecureRandomAlgorithm());
     }
 
+    public String createRandomCode (KustvaktConfiguration c)
+            throws KustvaktException, NoSuchAlgorithmException {
+        config = c;
+        init();
+        return createRandomCode();
+    }
+
     public String createRandomCode () throws KustvaktException {
         UUID randomUUID = UUID.randomUUID();
         byte[] uuidBytes = randomUUID.toString().getBytes();
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktBaseServer.java
similarity index 73%
rename from core/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java
rename to full/src/main/java/de/ids_mannheim/korap/server/KustvaktBaseServer.java
index 60065aa..2af1912 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java
+++ b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktBaseServer.java
@@ -1,10 +1,19 @@
-package de.ids_mannheim.korap.web;
+package de.ids_mannheim.korap.server;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.NoSuchAlgorithmException;
 
 import javax.servlet.ServletContextListener;
 
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.server.handler.ShutdownHandler;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.springframework.web.context.ContextLoaderListener;
@@ -12,6 +21,8 @@
 import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
 
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.encryption.RandomCodeGenerator;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -53,7 +64,8 @@
         return kargs;
     }
 
-    protected void start () {
+    protected void start ()
+            throws KustvaktException, IOException, NoSuchAlgorithmException {
 
         if (kargs.port == -1) {
             kargs.setPort(config.getPort());
@@ -82,7 +94,22 @@
         connector.setPort(kargs.port);
         connector.setIdleTimeout(60000);
 
-        server.setHandler(contextHandler);
+        RandomCodeGenerator random = new RandomCodeGenerator();
+        String shutdownToken = random.createRandomCode(config);
+        ShutdownHandler shutdownHandler = new ShutdownHandler(shutdownToken,true,true);
+
+        FileOutputStream fos = new FileOutputStream(new File("shutdownToken"));
+        OutputStreamWriter writer =
+                new OutputStreamWriter(fos, StandardCharsets.UTF_8.name());
+        writer.write(shutdownToken);
+        writer.flush();
+        writer.close();
+
+        HandlerList handlers = new HandlerList();
+        handlers.addHandler(shutdownHandler);
+        handlers.addHandler(contextHandler);
+
+        server.setHandler(handlers);
 
         server.setConnectors(new Connector[] { connector });
         try {
diff --git a/full/src/main/java/de/ids_mannheim/korap/server/KustvaktLiteServer.java b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktLiteServer.java
index 448d4f6..b2510ec 100644
--- a/full/src/main/java/de/ids_mannheim/korap/server/KustvaktLiteServer.java
+++ b/full/src/main/java/de/ids_mannheim/korap/server/KustvaktLiteServer.java
@@ -6,7 +6,6 @@
 import java.util.Properties;
 
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
-import de.ids_mannheim.korap.web.KustvaktBaseServer;
 
 public class KustvaktLiteServer extends KustvaktBaseServer {
 
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 5e97ea1..9b2f8ee 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
@@ -6,7 +6,6 @@
 import java.util.Properties;
 
 import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.web.KustvaktBaseServer;
 
 /**
  * pu
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
index 5d2ce4b..a9a1fb4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
@@ -258,7 +258,7 @@
         }
 
         CorpusAccess requiredAccess = determineRequiredAccess(koralQuery);
-
+        jlog.debug("Storing VC");
         int vcId = 0;
         try {
             vcId = vcDao.createVirtualCorpus(name, type, requiredAccess,
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/JettyServerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/JettyServerTest.java
new file mode 100644
index 0000000..e2127ea
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/JettyServerTest.java
@@ -0,0 +1,36 @@
+package de.ids_mannheim.korap.web;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.server.handler.ShutdownHandler;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JettyServerTest {
+
+    @BeforeClass
+    public static void testServerStarts () throws Exception {
+        Server server = new Server(8000);
+        HandlerList handlers = new HandlerList();
+        handlers.setHandlers(
+                new Handler[] { new ShutdownHandler("secret", true, true) });
+        server.setHandler(handlers);
+        server.start();
+    }
+    
+    @Test
+    public void testShutdown () throws IOException {
+        URL url = new URL(
+                "http://localhost:8000/shutdown?token=secret");
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setRequestMethod("POST");
+        assertEquals(200, connection.getResponseCode());
+    }
+}
diff --git a/full/src/test/resources/test-jdbc.properties b/full/src/test/resources/test-jdbc.properties
index db40081..bbf5f6b 100644
--- a/full/src/test/resources/test-jdbc.properties
+++ b/full/src/test/resources/test-jdbc.properties
@@ -8,4 +8,4 @@
 jdbc.username=pc
 jdbc.password=pc
 #jdbc.schemaPath=classpath:db.sqlite
-jdbc.schemaPath=classpath:db.new-sqlite, db.insert, db.predefined
\ No newline at end of file
+jdbc.schemaPath=classpath:db.sqlite, db.insert, db.predefined
\ No newline at end of file