diff --git a/qqq-middleware-javalin/pom.xml b/qqq-middleware-javalin/pom.xml index 3cfe058d..1099db78 100644 --- a/qqq-middleware-javalin/pom.xml +++ b/qqq-middleware-javalin/pom.xml @@ -122,6 +122,18 @@ src/main/java + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.3 + + + + ${project.basedir}/src/test/resources/static-site.jar + + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/routeproviders/SimpleFileSystemDirectoryRouter.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/routeproviders/SimpleFileSystemDirectoryRouter.java index c6504be1..e30c94a9 100644 --- a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/routeproviders/SimpleFileSystemDirectoryRouter.java +++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/routeproviders/SimpleFileSystemDirectoryRouter.java @@ -49,16 +49,14 @@ import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; public class SimpleFileSystemDirectoryRouter implements QJavalinRouteProviderInterface { private static final QLogger LOG = QLogger.getLogger(SimpleFileSystemDirectoryRouter.class); + public static boolean loadStaticFilesFromJar = false; + private final String hostedPath; private final String fileSystemPath; - private QCodeReference routeAuthenticator; - private QInstance qInstance; - - /******************************************************************************* ** Constructor ** @@ -67,6 +65,24 @@ public class SimpleFileSystemDirectoryRouter implements QJavalinRouteProviderInt { this.hostedPath = hostedPath; this.fileSystemPath = fileSystemPath; + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + // read the property to see if we should load static files from the jar file or from the file system // + // Javan only supports loading via one method per path, so its a choice of one or the other... // + /////////////////////////////////////////////////////////////////////////////////////////////////////// + try + { + String propertyName = "qqq.javalin.enableStaticFilesFromJar"; // TODO: make a more general way to handle properties like this system-wide via a central config class + String propertyValue = System.getProperty(propertyName, ""); + if(propertyValue.equals("true")) + { + loadStaticFilesFromJar = true; + } + } + catch(Exception e) + { + e.printStackTrace(); + } } @@ -98,25 +114,41 @@ public class SimpleFileSystemDirectoryRouter implements QJavalinRouteProviderInt ***************************************************************************/ private void handleJavalinStaticFileConfig(StaticFileConfig staticFileConfig) { - URL resource = getClass().getClassLoader().getResource(fileSystemPath); - if(resource == null) - { - String message = "Could not find file system path: " + fileSystemPath; - if(fileSystemPath.startsWith("/") && getClass().getClassLoader().getResource(fileSystemPath.replaceFirst("^/+", "")) != null) - { - message += ". For non-absolute paths, do not prefix with a leading slash."; - } - throw new RuntimeException(message); - } if(!hostedPath.startsWith("/")) { LOG.warn("hostedPath [" + hostedPath + "] should probably start with a leading slash..."); } - staticFileConfig.directory = resource.getFile(); - staticFileConfig.hostedPath = hostedPath; - staticFileConfig.location = Location.EXTERNAL; + /// ///////////////////////////////////////////////////////////////////////////////////// + // Handle loading static files from the jar OR the filesystem based on system property // + /// ///////////////////////////////////////////////////////////////////////////////////// + if(SimpleFileSystemDirectoryRouter.loadStaticFilesFromJar) + { + staticFileConfig.directory = fileSystemPath; + staticFileConfig.hostedPath = hostedPath; + staticFileConfig.location = Location.CLASSPATH; + LOG.info("Static File Config : hostedPath [" + hostedPath + "] : directory [" + staticFileConfig.directory + "] : location [CLASSPATH]"); + } + else + { + URL resource = getClass().getClassLoader().getResource(fileSystemPath); + if(resource == null) + { + String message = "Could not find file system path: " + fileSystemPath; + if(fileSystemPath.startsWith("/") && getClass().getClassLoader().getResource(fileSystemPath.replaceFirst("^/+", "")) != null) + { + message += ". For non-absolute paths, do not prefix with a leading slash."; + } + throw new RuntimeException(message); + } + + staticFileConfig.directory = resource.getFile(); + staticFileConfig.hostedPath = hostedPath; + staticFileConfig.location = Location.EXTERNAL; + LOG.info("Static File Config : hostedPath [" + hostedPath + "] : directory [" + staticFileConfig.directory + "] : location [EXTERNAL]"); + } + } diff --git a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QApplicationJavalinServerTest.java b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QApplicationJavalinServerTest.java index a6bf4085..a9524022 100644 --- a/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QApplicationJavalinServerTest.java +++ b/qqq-middleware-javalin/src/test/java/com/kingsrook/qqq/middleware/javalin/QApplicationJavalinServerTest.java @@ -29,6 +29,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.instances.AbstractQQQApplication; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.javalin.TestUtils; +import com.kingsrook.qqq.middleware.javalin.routeproviders.SimpleFileSystemDirectoryRouter; import com.kingsrook.qqq.middleware.javalin.specs.v1.MiddlewareVersionV1; import io.javalin.http.HttpStatus; import kong.unirest.HttpResponse; @@ -52,6 +53,16 @@ class QApplicationJavalinServerTest + /*************************************************************************** + ** + ***************************************************************************/ + private static AbstractQQQApplication getQqqApplication() + { + return new TestApplication(); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -60,6 +71,7 @@ class QApplicationJavalinServerTest { javalinServer.stop(); TestApplication.callCount = 0; + System.clearProperty("qqq.javalin.enableStaticFilesFromJar"); } @@ -196,6 +208,48 @@ class QApplicationJavalinServerTest + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testStaticRouterFilesFromExternal() throws Exception + { + System.setProperty("qqq.javalin.enableStaticFilesFromJar", "false"); + + javalinServer = new QApplicationJavalinServer(getQqqApplication()) + .withServeFrontendMaterialDashboard(false) + .withPort(PORT); + javalinServer.start(); + + Unirest.config().setDefaultResponseEncoding("UTF-8"); + HttpResponse response = Unirest.get("http://localhost:" + PORT + "/statically-served/foo.html").asString(); + assertEquals("Foo? Bar!", response.getBody()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testStaticRouterFilesFromClasspath() throws Exception + { + System.setProperty("qqq.javalin.enableStaticFilesFromJar", "true"); + + javalinServer = new QApplicationJavalinServer(new QApplicationJavalinServerTest.TestApplication()) + .withServeFrontendMaterialDashboard(false) + .withPort(PORT) + .withAdditionalRouteProvider(new SimpleFileSystemDirectoryRouter("/statically-served-from-jar", "static-site-from-jar/")); + + javalinServer.start(); + + Unirest.config().setDefaultResponseEncoding("UTF-8"); + HttpResponse response = Unirest.get("http://localhost:" + PORT + "/statically-served-from-jar/foo-in-jar.html").asString(); + assertEquals("Foo in a Jar!\n", response.getBody()); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -296,16 +350,6 @@ class QApplicationJavalinServerTest - /*************************************************************************** - ** - ***************************************************************************/ - private static AbstractQQQApplication getQqqApplication() - { - return new TestApplication(); - } - - - /*************************************************************************** ** ***************************************************************************/ diff --git a/qqq-middleware-javalin/src/test/resources/static-site.jar b/qqq-middleware-javalin/src/test/resources/static-site.jar new file mode 100644 index 00000000..f5e203e4 Binary files /dev/null and b/qqq-middleware-javalin/src/test/resources/static-site.jar differ