diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java index 15d84eb7dd4..0e771185021 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java @@ -65,6 +65,7 @@ public static void delete(File f, boolean reportExistsAfter) { /** * Delete all files in a directory. + * Does not recurse in the direction. * Does nothing if the path name does not exist or is not a directory. * * @param dir @@ -84,7 +85,7 @@ public static void clearAll(String d) { clearAll(new File(d)) ; } - /** Delete all files and directories (recursively) in a directory */ + /** Delete all files and directories (recursively) in a directory; does not delete the directory argument. */ public static void clearAll(File d) { if ( ! d.exists() ) return ; diff --git a/jena-fuseki2/jena-fuseki-main/pom.xml b/jena-fuseki2/jena-fuseki-main/pom.xml index b72e8613279..97afefa87c6 100644 --- a/jena-fuseki2/jena-fuseki-main/pom.xml +++ b/jena-fuseki2/jena-fuseki-main/pom.xml @@ -59,8 +59,24 @@ org.apache.jena jena-cmds + ${project.version} + + + + + org.apache.jena + jena-fuseki-ui 5.3.0-SNAPSHOT + test + + + org.eclipse.jetty.ee10 diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiMainInfo.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiInfo.java similarity index 93% rename from jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiMainInfo.java rename to jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiInfo.java index bcdf758ddb6..d565e5fba45 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiMainInfo.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiInfo.java @@ -22,7 +22,7 @@ import org.apache.jena.fuseki.server.FusekiCoreInfo; import org.slf4j.Logger; -public class FusekiMainInfo { +public class FusekiInfo { /** Details of the code version. */ public static void logCode(Logger log) { @@ -31,8 +31,8 @@ public static void logCode(Logger log) { /** Log server details. */ public static void logServer(Logger log, FusekiServer server, boolean verbose) { - FusekiMainInfo.logServerConnections(log, server); - FusekiMainInfo.logServerDatasets(log, server, verbose); + FusekiInfo.logServerConnections(log, server); + FusekiInfo.logServerDatasets(log, server, verbose); if ( server.getStaticContentDir() != null ) FmtLog.info(log, "Static files: %s", server.getStaticContentDir()); } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java index d902c9ce100..96fd41c758e 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiMain.java @@ -36,7 +36,7 @@ import org.apache.jena.cmd.*; import org.apache.jena.fuseki.Fuseki; import org.apache.jena.fuseki.FusekiException; -import org.apache.jena.fuseki.main.FusekiMainInfo; +import org.apache.jena.fuseki.main.FusekiInfo; import org.apache.jena.fuseki.main.FusekiServer; import org.apache.jena.fuseki.main.sys.FusekiModules; import org.apache.jena.fuseki.main.sys.FusekiServerArgsCustomiser; @@ -56,6 +56,17 @@ import org.slf4j.Logger; public class FusekiMain extends CmdARQ { + + // Need to pass to mods? + // Add "setup" call. + public enum Mode { + // Command setup, no admin + PLAIN, + // + Admin + Validators + metrics + ... + GENERAL + } + + /** Default HTTP port when running from the command line. */ public static int defaultPort = 3030; /** Default HTTPS port when running from the command line. */ @@ -97,8 +108,8 @@ public class FusekiMain extends CmdARQ { private static ArgDecl argWithMetrics = new ArgDecl(ArgDecl.NoValue, "withMetrics", "metrics"); private static ArgDecl argWithCompact = new ArgDecl(ArgDecl.NoValue, "withCompact", "compact"); -// // Use modules found by the ServiceLoader. -// private static ArgDecl argEnableModules = new ArgDecl(ArgDecl.HasValue, "modules", "fuseki-modules"); + // Use modules found by the ServiceLoader. Currently, no-op. + private static ArgDecl argEnableModules = new ArgDecl(ArgDecl.HasValue, "modules", "fuseki-modules"); private static ArgDecl argAuth = new ArgDecl(ArgDecl.HasValue, "auth"); @@ -196,6 +207,20 @@ public static void addCustomiser(FusekiServerArgsCustomiser customiser) { ArgCustomizers.addCustomiser(customiser); } + /** + * Registers CLI customisers. + *

+ * CLI customisers can add one/more custom arguments into the Fuseki Server CLI arguments and then can apply those + * to the Fuseki server being built during the processing of {@link #processModulesAndArgs()}. This allows for + * custom arguments that directly affect how the Fuseki server is built to be created. + *

+ * @see #addCustomiser(FusekiServerArgsCustomiser) + */ + public static void addCustomisers(FusekiModules customiserSet) { + Objects.requireNonNull(customiserSet); + customiserSet.forEach(customiser->ArgCustomizers.addCustomiser(customiser)); + } + /** * Resets any previously registered CLI customisers */ @@ -306,7 +331,7 @@ private void argumentsSetup() { add(argWithMetrics, "--metrics", "Enable /$/metrics"); add(argWithCompact, "--compact", "Enable /$/compact/*"); - //add(argEnableModules, "--modules=true|false", "Enable Fuseki modules"); + add(argEnableModules, "--modules=true|false", "Enable Fuseki autoloaded modules"); super.modVersion.addClass("Fuseki", Fuseki.class); @@ -578,9 +603,9 @@ private void processStdArguments(Logger log) { // Allows for external setting of serverArgs.fusekiModules if ( serverArgs.fusekiModules == null ) { // Get modules from system-wide setup. - // This (Fuseki 5.3.0- defaults to an empty set of modules. -// boolean withModules = hasValueOfTrue(argEnableModules); - serverArgs.fusekiModules = FusekiModules.getSystemModules(); + boolean withModules = hasValueOfTrue(argEnableModules); + if ( withModules ) + serverArgs.fusekiModules = FusekiModules.getSystemModules(); } if ( contains(argCORS) ) { @@ -630,7 +655,7 @@ protected void exec() { // Check for command line or config setup. try { Logger log = Fuseki.serverLog; - FusekiMainInfo.logServerCode(log); + FusekiInfo.logServerCode(log); FusekiServer server = makeServer(serverArgs); infoCmd(server, log); try { diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiServerCmd.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiServerCmd.java index 72c121a1c36..fc875dfba23 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiServerCmd.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/FusekiServerCmd.java @@ -18,7 +18,7 @@ package org.apache.jena.fuseki.main.cmds; -import org.apache.jena.fuseki.mod.FusekiModServer; +import org.apache.jena.fuseki.mod.FusekiServerRunner; import org.apache.jena.fuseki.system.FusekiLogging; /** Fuseki command that runs a Fuseki server with the admin UI. @@ -45,7 +45,7 @@ public class FusekiServerCmd { * syntax but not start it. */ static public void main(String... args) { - FusekiModServer.runAsync(args).join(); + FusekiServerRunner.runAsync(args).join(); } } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/ServerArgs.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/ServerArgs.java index d627adddc95..cad50c97f32 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/ServerArgs.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/cmds/ServerArgs.java @@ -52,7 +52,7 @@ public class ServerArgs { public boolean verboseLogging = false; /** - * FusekiModules to use during the server build * + * FusekiModules to use during the server build * Command line customisers are handled separately by FusekiMain. */ public FusekiModules fusekiModules = null; @@ -75,7 +75,7 @@ public class ServerArgs { public String serverConfigFile = null; public Model serverConfigModel = null; - /** Allow no datasets without it being an error. This is not an argument. */ + /** Allow no datasets without it being an error. This is not a command argument. */ public boolean allowEmpty = false; public SetupType setup = SetupType.UNSET; /** Start without a dataset or configuration (this is {@code --empty}) */ diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/FusekiServerCtl.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/FusekiServerCtl.java index 37101571224..e5b7e37a8f7 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/FusekiServerCtl.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mgt/FusekiServerCtl.java @@ -41,6 +41,7 @@ import org.apache.jena.fuseki.FusekiConfigException; import org.apache.jena.fuseki.build.DatasetDescriptionMap; import org.apache.jena.fuseki.build.FusekiConfig; +import org.apache.jena.fuseki.main.cmds.FusekiMain; import org.apache.jena.fuseki.server.DataAccessPoint; import org.apache.jena.fuseki.server.DataService; import org.apache.jena.fuseki.server.FusekiVocabG; @@ -391,6 +392,13 @@ private static Path writeableDirectory(Path root , String relName ) { return p; } + /** Running a full-features server set some global state. Clear this up. (mainly for tests.)*/ + public static void clearUpSystemState() { + System.getProperties().remove(FusekiServerCtl.envFusekiShiro); + System.getProperties().remove(FusekiServerCtl.envFusekiBase); + FusekiMain.resetCustomisers(); + } + private static Path makePath(Path root , String relName ) { Path path = root.resolve(relName); // Must exist diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiModServer.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java similarity index 51% rename from jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiModServer.java rename to jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java index 84f0fb72f68..b8574bf2cb7 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiModServer.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/FusekiServerRunner.java @@ -18,21 +18,22 @@ package org.apache.jena.fuseki.mod; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.apache.jena.atlas.lib.FileOps; +import org.apache.jena.atlas.lib.Lib; +import org.apache.jena.cmd.CmdGeneral; import org.apache.jena.fuseki.main.FusekiServer; import org.apache.jena.fuseki.main.cmds.FusekiMain; +import org.apache.jena.fuseki.main.cmds.ServerArgs; import org.apache.jena.fuseki.main.sys.FusekiModule; import org.apache.jena.fuseki.main.sys.FusekiModules; +import org.apache.jena.fuseki.main.sys.FusekiServerArgsCustomiser; +import org.apache.jena.fuseki.mgt.FusekiServerCtl; import org.apache.jena.fuseki.mod.admin.FMod_Admin; import org.apache.jena.fuseki.mod.prometheus.FMod_Prometheus; import org.apache.jena.fuseki.mod.shiro.FMod_Shiro; import org.apache.jena.fuseki.mod.ui.FMod_UI; -public class FusekiModServer { +public class FusekiServerRunner { public static void main(String... args) { runAsync(args).join(); @@ -43,49 +44,41 @@ public static FusekiServer runAsync(String... args) { } public static FusekiServer construct(String... args) { - // Order: FMod_Admin before FMod_Shiro - // These modules may have state that is carried across the build steps. - FusekiModule fmodShiro = FMod_Shiro.create(); - FusekiModule fmodAdmin = FMod_Admin.create(); - - FusekiModules serverModules = FusekiModules.create( fmodAdmin - , FMod_UI.get() - , fmodShiro - , FMod_Prometheus.get() ); - serverModules.forEach(FusekiMain::addCustomiser); + FusekiModules serverModules = serverModules(); - System.setProperty("FUSEKI_BASE", "run"); - FileOps.ensureDir("run"); + String fusekiBase = Lib.getenv(FusekiServerCtl.envFusekiBase); + if ( fusekiBase == null ) + fusekiBase = FusekiServerCtl.dftFusekiBase; + FileOps.ensureDir(fusekiBase); - // Adjust args. - List argList = Arrays.asList(args); - // Ensure "--empty", "--modules=true" - // Better?: moded startup - i.e. setting defaults. + // They can also modify the argument processing. + serverModules.forEach(FusekiMain::addCustomiser); - if ( args.length == 0 ) { - String [] defaultArgs = { "--port=3030", "--empty" }; - args = defaultArgs; - } else { - List argsList = new ArrayList(Arrays.asList(args)); - if ( ! containsArg(argList, "--?empty") ) - argsList.add(0, "--empty"); // addFirst in java21 - if ( ! containsArg(argList, "--?modules") ) - argsList.add(0, "--modules=true"); - args = argsList.toArray(args); - } + // Adjust the default settings of ServerArgs + FusekiServerArgsCustomiser initializeServerArgs = new FusekiServerArgsCustomiser() { + @Override + public void serverArgsModify(CmdGeneral fusekiCmd, ServerArgs serverArgs) { + serverArgs.allowEmpty = true; + serverArgs.fusekiModules = serverModules; + } + }; - FusekiModules modules = serverModules; - // Set system modules - these are picked up in FusekiMain - FusekiModules.setSystemDefault(modules); + FusekiMain.resetCustomisers(); + FusekiMain.addCustomiser(initializeServerArgs); + // Make server FusekiServer server = FusekiServer.construct(args); return server; } - private static boolean containsArg(List argList, String argRegex) { - //Pattern pattern = Pattern.compile(argRegex); + /** A use-once {@link FusekiModules} for the fill-featured Fuseki server. */ + public static FusekiModules serverModules() { + // Modules may have state that is carried across the build steps or used for reload. + FusekiModule fmodShiro = FMod_Shiro.create(); + FusekiModule fmodAdmin = FMod_Admin.create(); + FusekiModule fmodUI = FMod_UI.create(); + FusekiModule fmodPrometheus = FMod_Prometheus.create(); - return argList.stream().anyMatch(arg->{ - return arg.matches(argRegex); - }); + FusekiModules serverModules = FusekiModules.create(fmodAdmin, fmodUI, fmodShiro, fmodPrometheus ); + return serverModules; } } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java index d4ea62e6612..7a873932db7 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/admin/FMod_Admin.java @@ -69,8 +69,12 @@ public FMod_Admin() {} private static Logger LOG = Fuseki.configLog; - private ArgDecl argAdmin = new ArgDecl(true, "admin"); - private ArgDecl argAdminArea = new ArgDecl(true, "adminArea", "adminBase"); + private static ArgDecl argAdmin = new ArgDecl(true, "admin"); + private static ArgDecl argAdminArea = new ArgDecl(true, "adminArea", "adminBase"); + + // Module state. + private String admin = null; + private Path directory = null; @Override public void serverArgsModify(CmdGeneral fusekiCmd, ServerArgs serverArgs) { @@ -96,7 +100,6 @@ public void serverArgsPrepare(CmdGeneral fusekiCmd, ServerArgs serverArgs) { return; } - Path directory = null; String dirStr = fusekiCmd.getValue(argAdminArea); if ( dirStr != null ) directory = Path.of(dirStr); @@ -114,6 +117,7 @@ public void serverArgsPrepare(CmdGeneral fusekiCmd, ServerArgs serverArgs) { if ( ! Files.isWritable(directory) ) throw new FusekiConfigException("Not writable: "+dirStr); } + // Record in a global - for the case of one server in a JVM FusekiServerCtl.FUSEKI_BASE = directory; } @@ -130,6 +134,7 @@ public void prepare(FusekiServer.Builder builder, Set datasetNames, Mode Path path; synchronized(FusekiServerCtl.class) { // Temporary - one at a time because FUSEKI_BASE is static. + // XXX FusekiServerCtl app = new FusekiServerCtl(null); path = app.setup(); } @@ -147,9 +152,10 @@ public void prepare(FusekiServer.Builder builder, Set datasetNames, Mode String configDir = FusekiServerCtl.dirConfiguration.toString(); List directoryDatabases = FusekiConfig.readConfigurationDirectory(configDir); - if ( directoryDatabases.isEmpty() ) + if ( directoryDatabases.isEmpty() && datasetNames.isEmpty() ) FmtLog.info(LOG, "No databases: dir=%s", configDir); else { + datasetNames.forEach(n->FmtLog.info(Fuseki.configLog, "Database: %s", n)); directoryDatabases.forEach(dap -> FmtLog.info(Fuseki.configLog, "Database: %s", dap.getName())); } @@ -182,4 +188,9 @@ public void prepare(FusekiServer.Builder builder, Set datasetNames, Mode .enableCompact(true) ; } + + // Currently, the server admin area does not move during the run of a server. + /** {@inheritDoc} */ + @Override + public void serverReload(FusekiServer server) { } } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/prometheus/FMod_Prometheus.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/prometheus/FMod_Prometheus.java index c61a45fc054..6aa7eb6c7b6 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/prometheus/FMod_Prometheus.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/prometheus/FMod_Prometheus.java @@ -34,11 +34,12 @@ */ public class FMod_Prometheus implements FusekiModule { - private static FusekiModule singleton = new FMod_Prometheus(); - public static FusekiModule get() { - return singleton; + public static FusekiModule create() { + return new FMod_Prometheus(); } + private MetricsProvider metricsProvider = null; + public FMod_Prometheus() {} // @Override @@ -50,7 +51,7 @@ public FMod_Prometheus() {} public String name() { return "FMod Prometheus Metrics"; } @Override public void prepare(FusekiServer.Builder serverBuilder, Set datasetNames, Model configModel) { - MetricsProvider metricsProvider = new PrometheusMetricsProvider(); + metricsProvider = new PrometheusMetricsProvider(); serverBuilder.addServletAttribute(Fuseki.attrMetricsProvider, metricsProvider); serverBuilder.addServlet("/$/metrics", new ActionMetrics()); } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java index ff0acf2fc49..1b0b698b4a1 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FMod_Shiro.java @@ -80,6 +80,7 @@ public static FMod_Shiro create() { private static ArgDecl argShiroIni = new ArgDecl(true, "shiro", "shiro-ini"); + // Module state (for reload). private String shiroFile = null; public FMod_Shiro() { @@ -181,8 +182,10 @@ public void serverBeforeStarting(FusekiServer server) { } } - @Override - public void serverAfterStarting(FusekiServer server) {} - -// @Override public void serverStopped(FusekiServer server) { } + // Later: + // Reload shirio.ini file and reset. +// // Currently, no actual - the server admin area does not move during the run of a server. +// /** {@inheritDoc} */ +// @Override +// public void serverReload(FusekiServer server) { } } diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java index c963771efcb..a04b42589ae 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/FusekiShiroLib.java @@ -23,6 +23,7 @@ import java.util.List; import jakarta.servlet.ServletContext; +import org.apache.jena.atlas.lib.IRILib; import org.apache.jena.fuseki.FusekiConfigException; import org.apache.jena.rfc3986.URIScheme; import org.apache.shiro.lang.io.ResourceUtils; @@ -47,7 +48,9 @@ static String huntForShiroIni(List locations) { for ( String loc : locations ) { // If file:, look for that file. if ( loc.startsWith(fileSchemePrefix) ) { - Path p = Path.of(loc.substring(fileSchemePrefix.length())); + // Convert (back) to a filesystem path. + String fn = IRILib.IRIToFilename(loc); + Path p = Path.of(fn); if ( Files.exists(p) ) return loc; // Ignore. diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/ShiroEnvironmentLoaderListener.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/ShiroEnvironmentLoaderListener.java index c99f47aee71..7c5269415d1 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/ShiroEnvironmentLoaderListener.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/shiro/ShiroEnvironmentLoaderListener.java @@ -74,4 +74,4 @@ protected void customizeEnvironment(WebEnvironment environment) { env.setConfigLocations(configLocationsHere); } } -} \ No newline at end of file +} diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/ui/FMod_UI.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/ui/FMod_UI.java index 51ad0fa32da..4cdc15b33e0 100644 --- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/ui/FMod_UI.java +++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/mod/ui/FMod_UI.java @@ -46,10 +46,9 @@ public class FMod_UI implements FusekiModule { - // Only one module needed - it is stateless. private static FusekiModule singleton = new FMod_UI(); - public static FusekiModule get() { - return singleton; + public static FusekiModule create() { + return new FMod_UI(); } public FMod_UI() {} @@ -63,12 +62,15 @@ public FMod_UI() {} // } private static ArgDecl argUIFiles = new ArgDecl(true, "ui"); - private String uiAppLocation = null; + /** Java resource name used to find the UI files. */ private static String resourceNameUI = "webapp"; /** Directory name of the root of UI files with {@code FUSEKI_BASE} */ private static String directoryNameUI = "webapp"; + // UI resources location. + private String uiAppLocation = null; + @Override public String name() { return "FMod UI"; @@ -114,6 +116,11 @@ public void prepare(FusekiServer.Builder builder, Set datasetNames, Mode // LOG.info("Fuseki UI loaded"); } + // Currently, fixed location during the run of a server. + /** {@inheritDoc} */ + @Override + public void serverReload(FusekiServer server) { } + /** * Locate the UI files. *
    diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TS_FusekiMods.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TS_FusekiMods.java index f4f261e0e97..982da56e2f7 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TS_FusekiMods.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TS_FusekiMods.java @@ -38,7 +38,8 @@ // Prometheus TestModPrometheus.class, // Apache Shiro - TestModShiro.class + TestModShiro.class, + TestFusekiServer.class }) public class TS_FusekiMods { public TS_FusekiMods() {} diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TestFusekiServer.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TestFusekiServer.java index c9d11ed6919..cd29934cc25 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TestFusekiServer.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/TestFusekiServer.java @@ -20,19 +20,73 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.apache.jena.atlas.lib.FileOps; import org.apache.jena.fuseki.main.FusekiServer; +import org.apache.jena.fuseki.main.cmds.FusekiMain; +import org.apache.jena.fuseki.main.sys.FusekiModules; +import org.apache.jena.fuseki.mgt.FusekiServerCtl; /** * Test for the whole Fuseki server, not components. */ public class TestFusekiServer { - @Test public void run() { - // Setup - FusekiServer server = FusekiModServer.runAsync("--port=0", "--empty"); - int port = server.getPort(); - assertNotEquals(0, port, "Port is zero after async start"); + private static String serverBase = "target/runBase"; + + @BeforeAll static void beforeAll() { + FusekiModules.restoreSystemDefault(); + FusekiServerCtl.clearUpSystemState(); + + } + + @AfterEach void afterEach() { + FusekiModules.restoreSystemDefault(); + FusekiServerCtl.clearUpSystemState(); + } + + @Test + public void runCmdLine() { + String runBase = serverBase+"1"; + setup(runBase); + // Build-run command line + FusekiServer server = FusekiServerRunner.runAsync("--port=0", "--empty"); + try { + int port = server.getPort(); + assertNotEquals(0, port, "Port is zero after async start"); + } finally { + FusekiMain.resetCustomisers(); + server.stop(); + tearDown(runBase); + } + } + + @Test + public void buildRun() { + String runBase = serverBase+"2"; + setup(runBase); + // Build-run programmatically. + FusekiModules serverModules = FusekiServerRunner.serverModules(); + FusekiServer server = FusekiServer.create().port(0).fusekiModules(serverModules).build(); + server.start(); + try { + int port = server.getPort(); + assertNotEquals(0, port, "Port is zero after async start"); + } finally { + server.stop(); + tearDown(runBase); + } + } + + private void setup(String runBase) { + System.setProperty(FusekiServerCtl.envFusekiBase, runBase); + FileOps.clearAll(runBase); + } + + private void tearDown(String runBase) { + FileOps.clearAll(runBase); } } diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdmin.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdmin.java index 396b14b2890..647fb9ca20d 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdmin.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestAdmin.java @@ -120,8 +120,7 @@ private FusekiServer createServerForTest() { if ( server != null ) server.stop(); serverURL = null; - // Clearup FMod_Shiro. - System.getProperties().remove(FusekiServerCtl.envFusekiShiro); + FusekiServerCtl.clearUpSystemState(); } protected String urlRoot() { @@ -226,18 +225,17 @@ protected String datasetPath() { try { Path f = Path.of(fileBase+"config-ds-plain-1.ttl"); - { - httpPost(urlRoot()+"$/"+opDatasets, - WebContent.contentTypeTurtle+"; charset="+WebContent.charsetUTF8, - BodyPublishers.ofFile(f)); - } + httpPost(urlRoot()+"$/"+opDatasets, + WebContent.contentTypeTurtle+"; charset="+WebContent.charsetUTF8, + BodyPublishers.ofFile(f)); // Check exists. checkExists(dsTest); + // Try again. try { - } catch (HttpException ex) { httpPost(urlRoot()+"$/"+opDatasets, WebContent.contentTypeTurtle+"; charset="+WebContent.charsetUTF8, BodyPublishers.ofFile(f)); + } catch (HttpException ex) { assertEquals(HttpSC.CONFLICT_409, ex.getStatusCode()); } } catch (IOException ex) { IO.exception(ex); return; } diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestTemplateAddDataset.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestTemplateAddDataset.java index 9743802dcfa..2035ae581ca 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestTemplateAddDataset.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/admin/TestTemplateAddDataset.java @@ -85,7 +85,7 @@ private static FusekiServer createServerForTest() { server.stop(); serverURL = null; // Clearup FMod_Shiro. - System.getProperties().remove(FusekiServerCtl.envFusekiShiro); + FusekiServerCtl.clearUpSystemState(); } protected String urlRoot() { diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/metrics/TestModPrometheus.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/metrics/TestModPrometheus.java index dbb475b002d..16bc61c017f 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/metrics/TestModPrometheus.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/metrics/TestModPrometheus.java @@ -48,7 +48,7 @@ public class TestModPrometheus { @BeforeEach void setupServer() { DatasetGraph dsg = DatasetGraphFactory.createTxnMem(); - FusekiModules fusekiModules = FusekiModules.create(FMod_Prometheus.get()); + FusekiModules fusekiModules = FusekiModules.create(FMod_Prometheus.create()); testServer = FusekiServer.create() .add("/ds", dsg) .enableMetrics(false) // N.B. false. Instead, use module to setup. diff --git a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java index 48f064f6a74..3a740012a2c 100644 --- a/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java +++ b/jena-fuseki2/jena-fuseki-main/src/test/java/org/apache/jena/fuseki/mod/shiro/TestModShiro.java @@ -26,7 +26,6 @@ import java.net.http.HttpClient; import java.util.regex.Pattern; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -55,23 +54,20 @@ public class TestModShiro { static { FusekiLogging.setLogging(); - // Incase it is finding file:log4j.properties first. + // In case it is finding file:log4j.properties first. // LogCtl.disable(Fuseki.serverLog); // LogCtl.disable(Fuseki.actionLog); // LogCtl.disable(FMod_Shiro.shiroConfigLog); } @BeforeEach void before() { - System.getProperties().remove(FusekiServerCtl.envFusekiShiro); + FusekiServerCtl.clearUpSystemState(); AuthEnv.get().clearAuthEnv(); } @AfterEach void after() { AuthEnv.get().clearAuthEnv(); - } - - @AfterAll static void afterAll() { - System.getProperties().remove(FusekiServerCtl.envFusekiShiro); + FusekiServerCtl.clearUpSystemState(); } private String unlocalhost(FusekiServer server, String dataset) { @@ -108,7 +104,6 @@ private FusekiServer.Builder serverBuilderWithShiro(String filename) { attemptByLocalhost(server, dsLocal); } finally { server.stop(); - AuthEnv.get().clearAuthEnv(); } } @@ -164,7 +159,6 @@ private FusekiServer.Builder serverBuilderWithShiro(String filename) { } finally { server.stop(); - AuthEnv.get().clearAuthEnv(); } } diff --git a/jena-fuseki2/pom.xml b/jena-fuseki2/pom.xml index 18844744cf8..8e2c5d75d41 100644 --- a/jena-fuseki2/pom.xml +++ b/jena-fuseki2/pom.xml @@ -57,8 +57,7 @@ jena-fuseki-main - - + jena-fuseki-server