You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2024/04/09 16:59:22 UTC

(jena) 01/06: GH-2393: Remove unused system database

This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git

commit b92063d212f85f934dc034a2fac83a2c80fe36e2
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Fri Apr 5 20:47:00 2024 +0100

    GH-2393: Remove unused system database
---
 .../org/apache/jena/fuseki/build/FusekiConfig.java |  46 ---
 .../org/apache/jena/fuseki/mgt/ActionDatasets.java | 308 +++++++--------------
 .../apache/jena/fuseki/webapp/FusekiWebapp.java    |   3 -
 .../org/apache/jena/fuseki/webapp/SystemState.java |  96 -------
 .../java/org/apache/jena/fuseki/ServerCtl.java     |   5 -
 .../java/org/apache/jena/fuseki/TestAdmin.java     |  64 ++---
 .../java/org/apache/jena/fuseki/TestAdminAPI.java  |  18 --
 7 files changed, 136 insertions(+), 404 deletions(-)

diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
index af3b0b8eef..cf1e0f16c1 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/build/FusekiConfig.java
@@ -39,7 +39,6 @@ import org.apache.jena.assembler.Assembler;
 import org.apache.jena.assembler.JA;
 import org.apache.jena.atlas.lib.IRILib;
 import org.apache.jena.atlas.lib.Pair;
-import org.apache.jena.atlas.lib.StrUtils;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
 import org.apache.jena.fuseki.Fuseki;
 import org.apache.jena.fuseki.FusekiConfigException;
@@ -52,7 +51,6 @@ import org.apache.jena.fuseki.servlets.ActionService;
 import org.apache.jena.graph.Node;
 import org.apache.jena.query.Dataset;
 import org.apache.jena.query.QuerySolution;
-import org.apache.jena.query.ReadWrite;
 import org.apache.jena.query.ResultSet;
 import org.apache.jena.rdf.model.*;
 import org.apache.jena.rdf.model.impl.Util;
@@ -655,48 +653,4 @@ public class FusekiConfig {
         dsDescMap.register(datasetDesc, ds);
         return ds;
     }
-
-    // ---- System database
-    /** Read the system database */
-    public static List<DataAccessPoint> readSystemDatabase(Dataset ds) {
-        // Webapp only.
-        DatasetDescriptionMap dsDescMap = new DatasetDescriptionMap();
-        String qs = StrUtils.strjoinNL
-            (FusekiPrefixes.PREFIXES ,
-             "SELECT * {" ,
-             "  GRAPH ?g {",
-             "     ?s fu:name ?name;" ,
-             "        fu:status ?status ." ,
-             "  }",
-             "}"
-             );
-
-        List<DataAccessPoint> refs = new ArrayList<>();
-
-        ds.begin(ReadWrite.WRITE);
-        try {
-            ResultSet rs = BuildLib.query(qs, ds);
-
-            for (; rs.hasNext(); ) {
-                QuerySolution row = rs.next();
-                Resource s = row.getResource("s");
-                Resource g = row.getResource("g");
-                Resource rStatus = row.getResource("status");
-                //String name = row.getLiteral("name").getLexicalForm();
-                DataServiceStatus status = DataServiceStatus.status(rStatus);
-
-                Model m = ds.getNamedModel(g.getURI());
-                // Rebase the resource of the service description to the containing graph.
-                Resource svc = m.wrapAsResource(s.asNode());
-                DataAccessPoint ref = buildDataAccessPoint(svc, dsDescMap);
-                if ( ref != null )
-                    refs.add(ref);
-            }
-            ds.commit();
-            return refs;
-        } catch (Throwable th) {
-            th.printStackTrace();
-            return refs;
-        } finally { ds.end(); }
-    }
 }
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
index a4a0c23c25..beb93845dc 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/mgt/ActionDatasets.java
@@ -20,7 +20,6 @@ package org.apache.jena.fuseki.mgt;
 
 import static java.lang.String.format;
 import static org.apache.jena.atlas.lib.Lib.lowercase;
-import static org.apache.jena.fuseki.build.FusekiPrefixes.PREFIXES;
 
 import java.io.IOException;
 import java.io.OutputStream;
@@ -30,7 +29,6 @@ import java.nio.file.Path;
 import java.util.*;
 
 import jakarta.servlet.http.HttpServletRequest;
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.jena.atlas.RuntimeIOException;
 import org.apache.jena.atlas.io.IO;
@@ -38,11 +36,9 @@ import org.apache.jena.atlas.json.JsonBuilder;
 import org.apache.jena.atlas.json.JsonValue;
 import org.apache.jena.atlas.lib.FileOps;
 import org.apache.jena.atlas.lib.InternalErrorException;
-import org.apache.jena.atlas.lib.StrUtils;
 import org.apache.jena.atlas.logging.FmtLog;
 import org.apache.jena.atlas.web.ContentType;
 import org.apache.jena.datatypes.xsd.XSDDatatype;
-import org.apache.jena.dboe.transaction.txn.TransactionException;
 import org.apache.jena.fuseki.build.DatasetDescriptionMap;
 import org.apache.jena.fuseki.build.FusekiConfig;
 import org.apache.jena.fuseki.ctl.ActionContainerItem;
@@ -57,11 +53,7 @@ import org.apache.jena.fuseki.servlets.ServletOps;
 import org.apache.jena.fuseki.system.DataUploader;
 import org.apache.jena.fuseki.system.FusekiNetLib;
 import org.apache.jena.fuseki.webapp.FusekiWebapp;
-import org.apache.jena.fuseki.webapp.SystemState;
 import org.apache.jena.graph.Node;
-import org.apache.jena.graph.NodeFactory;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.query.ReadWrite;
 import org.apache.jena.rdf.model.*;
 import org.apache.jena.riot.*;
 import org.apache.jena.riot.system.StreamRDF;
@@ -70,18 +62,11 @@ import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.core.assembler.AssemblerUtils;
 import org.apache.jena.sparql.util.FmtUtils;
-import org.apache.jena.tdb1.transaction.DatasetGraphTransaction;
-import org.apache.jena.update.UpdateAction;
-import org.apache.jena.update.UpdateFactory;
-import org.apache.jena.update.UpdateRequest;
 import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.web.HttpSC;
 
 public class ActionDatasets extends ActionContainerItem {
 
-    private static Dataset system = SystemState.getDataset();
-    private static DatasetGraphTransaction systemDSG = SystemState.getDatasetGraph();
-
     static private Property pServiceName = FusekiVocab.pServiceName;
     //static private Property pStatus = FusekiVocab.pStatus;
 
@@ -91,6 +76,9 @@ public class ActionDatasets extends ActionContainerItem {
     private static final String tDatabaseTDB2       = "tdb2";
     private static final String tDatabaseMem        = "mem";
 
+    // Sync lock.
+    private static final Object lock = new Object();
+
     public ActionDatasets() { super(); }
 
     @Override
@@ -136,110 +124,111 @@ public class ActionDatasets extends ActionContainerItem {
 
         boolean committed = false;
         // Also acts as a concurrency lock
-        system.begin(ReadWrite.WRITE);
-        String systemFileCopy = null;
-        String configFile = null;
-
-        try {
-            // Where to build the templated service/database.
-            Model modelData = ModelFactory.createDefaultModel();
-            StreamRDF dest = StreamRDFLib.graph(modelData.getGraph());
-
-            if ( hasParams || WebContent.isHtmlForm(ct) )
-                assemblerFromForm(action, dest);
-            else if ( WebContent.isMultiPartForm(ct) )
-                assemblerFromUpload(action, dest);
-            else
-                assemblerFromBody(action, dest);
-
-            Model model = ModelFactory.createDefaultModel();
-            model.add(modelData);
-            AssemblerUtils.addRegistered(model);
-
-            // ----
-            // Keep a persistent copy immediately.  This is not used for
-            // anything other than being "for the record".
-            systemFileCopy = FusekiWebapp.dirSystemFileArea.resolve(uuid.toString()).toString();
-            try ( OutputStream outCopy = IO.openOutputFile(systemFileCopy) ) {
-                RDFDataMgr.write(outCopy, modelData, Lang.TURTLE);
-            }
-            // ----
-            // Process configuration.
-
-            // Returns the "service fu:name NAME" statement
-            Statement stmt = findService(model);
-
-            Resource subject = stmt.getSubject();
-            Literal object = stmt.getObject().asLiteral();
-
-            if ( object.getDatatype() != null && ! object.getDatatype().equals(XSDDatatype.XSDstring) )
-                action.log.warn(format("[%d] Service name '%s' is not a string", action.id, FmtUtils.stringForRDFNode(object)));
-
-            String datasetPath;
-            {   // Check the name provided.
-                String datasetName = object.getLexicalForm();
-                // This duplicates the code FusekiBuilder.buildDataAccessPoint to give better error messages and HTTP status code."
-
-                // ---- Check and canonicalize name.
-                if ( datasetName.isEmpty() )
-                    ServletOps.error(HttpSC.BAD_REQUEST_400, "Empty dataset name");
-                if ( StringUtils.isBlank(datasetName) )
-                    ServletOps.error(HttpSC.BAD_REQUEST_400, format("Whitespace dataset name: '%s'", datasetName));
-                if ( datasetName.contains(" ") )
-                    ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name (contains spaces) '%s'",datasetName));
-                if ( datasetName.equals("/") )
-                    ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name '%s'",datasetName));
-                datasetPath = DataAccessPoint.canonical(datasetName);
-                // ---- Check whether it already exists
-                if ( action.getDataAccessPointRegistry().isRegistered(datasetPath) )
-                    // And abort.
-                    ServletOps.error(HttpSC.CONFLICT_409, "Name already registered "+datasetPath);
-            }
+        synchronized(lock) {
+            String systemFileCopy = null;
+            String configFile = null;
 
-            action.log.info(format("[%d] Create database : name = %s", action.id, datasetPath));
+            try {
+                // Where to build the templated service/database.
+                Model modelData = ModelFactory.createDefaultModel();
+                StreamRDF dest = StreamRDFLib.graph(modelData.getGraph());
+
+                if ( hasParams || WebContent.isHtmlForm(ct) )
+                    assemblerFromForm(action, dest);
+                else if ( WebContent.isMultiPartForm(ct) )
+                    assemblerFromUpload(action, dest);
+                else
+                    assemblerFromBody(action, dest);
+
+                Model model = ModelFactory.createDefaultModel();
+                model.add(modelData);
+                AssemblerUtils.addRegistered(model);
+
+                // ----
+                // Keep a persistent copy immediately.  This is not used for
+                // anything other than being "for the record".
+                systemFileCopy = FusekiWebapp.dirSystemFileArea.resolve(uuid.toString()).toString();
+                try ( OutputStream outCopy = IO.openOutputFile(systemFileCopy) ) {
+                    RDFDataMgr.write(outCopy, modelData, Lang.TURTLE);
+                }
+                // ----
+                // Process configuration.
+
+                // Returns the "service fu:name NAME" statement
+                Statement stmt = findService(model);
+
+                Resource subject = stmt.getSubject();
+                Literal object = stmt.getObject().asLiteral();
+
+                if ( object.getDatatype() != null && ! object.getDatatype().equals(XSDDatatype.XSDstring) )
+                    action.log.warn(format("[%d] Service name '%s' is not a string", action.id, FmtUtils.stringForRDFNode(object)));
+
+                String datasetPath;
+                {   // Check the name provided.
+                    String datasetName = object.getLexicalForm();
+                    // This duplicates the code FusekiBuilder.buildDataAccessPoint to give better error messages and HTTP status code."
+
+                    // ---- Check and canonicalize name.
+                    if ( datasetName.isEmpty() )
+                        ServletOps.error(HttpSC.BAD_REQUEST_400, "Empty dataset name");
+                    if ( StringUtils.isBlank(datasetName) )
+                        ServletOps.error(HttpSC.BAD_REQUEST_400, format("Whitespace dataset name: '%s'", datasetName));
+                    if ( datasetName.contains(" ") )
+                        ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name (contains spaces) '%s'",datasetName));
+                    if ( datasetName.equals("/") )
+                        ServletOps.error(HttpSC.BAD_REQUEST_400, format("Bad dataset name '%s'",datasetName));
+                    datasetPath = DataAccessPoint.canonical(datasetName);
+                    // ---- Check whether it already exists
+                    if ( action.getDataAccessPointRegistry().isRegistered(datasetPath) )
+                        // And abort.
+                        ServletOps.error(HttpSC.CONFLICT_409, "Name already registered "+datasetPath);
+                }
 
-            configFile = FusekiWebapp.generateConfigurationFilename(datasetPath);
-            List<String> existing = FusekiWebapp.existingConfigurationFile(datasetPath);
-            if ( ! existing.isEmpty() )
-                ServletOps.error(HttpSC.CONFLICT_409, "Configuration file for '"+datasetPath+"' already exists");
+                action.log.info(format("[%d] Create database : name = %s", action.id, datasetPath));
 
-            // Write to configuration directory.
-            try ( OutputStream outCopy = IO.openOutputFile(configFile) ) {
-                RDFDataMgr.write(outCopy, modelData, Lang.TURTLE);
-            }
+                configFile = FusekiWebapp.generateConfigurationFilename(datasetPath);
+                List<String> existing = FusekiWebapp.existingConfigurationFile(datasetPath);
+                if ( ! existing.isEmpty() )
+                    ServletOps.error(HttpSC.CONFLICT_409, "Configuration file for '"+datasetPath+"' already exists");
+
+                // Write to configuration directory.
+                try ( OutputStream outCopy = IO.openOutputFile(configFile) ) {
+                    RDFDataMgr.write(outCopy, modelData, Lang.TURTLE);
+                }
 
-            // Currently do nothing with the system database.
-            // In the future ... maybe ...
+                // Currently do nothing with the system database.
+                // In the future ... maybe ...
 //            Model modelSys = system.getNamedModel(gn.getURI());
 //            modelSys.removeAll(null, pStatus, null);
 //            modelSys.add(subject, pStatus, FusekiVocab.stateActive);
 
-            // Need to be in Resource space at this point.
-            DataAccessPoint dataAccessPoint = FusekiConfig.buildDataAccessPoint(subject, registry);
-            if ( dataAccessPoint == null ) {
-                FmtLog.error(action.log, "Failed to build DataAccessPoint: datasetPath = %s; DataAccessPoint name = %s", datasetPath, dataAccessPoint);
-                ServletOps.errorBadRequest("Failed to build DataAccessPoint");
-                return null;
-            }
-            dataAccessPoint.getDataService().setEndpointProcessors(action.getOperationRegistry());
-            dataAccessPoint.getDataService().goActive();
-            if ( ! datasetPath.equals(dataAccessPoint.getName()) )
-                FmtLog.warn(action.log, "Inconsistent names: datasetPath = %s; DataAccessPoint name = %s", datasetPath, dataAccessPoint);
+                // Need to be in Resource space at this point.
+                DataAccessPoint dataAccessPoint = FusekiConfig.buildDataAccessPoint(subject, registry);
+                if ( dataAccessPoint == null ) {
+                    FmtLog.error(action.log, "Failed to build DataAccessPoint: datasetPath = %s; DataAccessPoint name = %s", datasetPath, dataAccessPoint);
+                    ServletOps.errorBadRequest("Failed to build DataAccessPoint");
+                    return null;
+                }
+                dataAccessPoint.getDataService().setEndpointProcessors(action.getOperationRegistry());
+                dataAccessPoint.getDataService().goActive();
+                if ( ! datasetPath.equals(dataAccessPoint.getName()) )
+                    FmtLog.warn(action.log, "Inconsistent names: datasetPath = %s; DataAccessPoint name = %s", datasetPath, dataAccessPoint);
+
+                action.getDataAccessPointRegistry().register(dataAccessPoint);
+                action.setResponseContentType(WebContent.contentTypeTextPlain);
+                ServletOps.success(action);
+
+                committed = true;
+
+            } catch (IOException ex) { IO.exception(ex); }
+            finally {
+                if ( ! committed ) {
+                    if ( systemFileCopy != null ) FileOps.deleteSilent(systemFileCopy);
+                    if ( configFile != null ) FileOps.deleteSilent(configFile);
+
+                }
 
-            action.getDataAccessPointRegistry().register(dataAccessPoint);
-            action.setResponseContentType(WebContent.contentTypeTextPlain);
-            ServletOps.success(action);
-            system.commit();
-            committed = true;
-
-        } catch (IOException ex) { IO.exception(ex); }
-        finally {
-            if ( ! committed ) {
-                if ( systemFileCopy != null ) FileOps.deleteSilent(systemFileCopy);
-                if ( configFile != null ) FileOps.deleteSilent(configFile);
-                system.abort();
             }
-            system.end();
         }
         return null;
     }
@@ -285,6 +274,8 @@ public class ActionDatasets extends ActionContainerItem {
 
     @Override
     protected JsonValue execPostItem(HttpAction action) {
+        // This used to be the state change function -- active/inactive.
+        // Leave the core of the operation - tests used it to ping for a database.
         String name = getItemDatasetName(action);
         if ( name == null )
             name = "''";
@@ -295,40 +286,6 @@ public class ActionDatasets extends ActionContainerItem {
 
         if ( dap == null )
             ServletOps.errorNotFound("Not found: dataset "+name);
-
-        DataService dSrv = dap.getDataService();
-        if ( dSrv == null )
-            // If not set explicitly, take from DataAccessPoint
-            dSrv = action.getDataAccessPoint().getDataService();
-
-        String s = action.getRequestParameter("state");
-        if ( s == null || s.isEmpty() )
-            ServletOps.errorBadRequest("No state change given");
-
-        // setDatasetState is a transaction on the persistent state of the server.
-        if ( s.equalsIgnoreCase("active") ) {
-            action.log.info(format("[%d] REBUILD DATASET %s", action.id, name));
-            setDatasetState(name, FusekiVocab.stateActive);
-            dSrv.goActive();
-            // DatasetGraph dsg = ????;
-            //dSrv.activate(dsg);
-            //dSrv.activate();
-        } else if ( s.equalsIgnoreCase("offline") ) {
-            action.log.info(format("[%d] OFFLINE DATASET %s", action.id, name));
-            //DataAccessPoint access = action.getDataAccessPoint();
-            //access.goOffline();
-            dSrv.goOffline();  // Affects the target of the name.
-            setDatasetState(name, FusekiVocab.stateOffline);
-            //dSrv.offline();
-        } else if ( s.equalsIgnoreCase("unlink") ) {
-            action.log.info(format("[%d] UNLINK ACCESS NAME %s", action.id, name));
-            //DataAccessPoint access = action.getDataAccessPoint();
-            ServletOps.errorNotImplemented("unlink: dataset"+name);
-            //access.goOffline();
-            // Registry?
-        }
-        else
-            ServletOps.errorBadRequest("State change operation '"+s+"' not recognized");
         return null;
     }
 
@@ -345,15 +302,8 @@ public class ActionDatasets extends ActionContainerItem {
         if ( ! action.getDataAccessPointRegistry().isRegistered(name) )
             ServletOps.errorNotFound("No such dataset registered: "+name);
 
-        // This acts as a lock.
-        systemDSG.begin(ReadWrite.WRITE);
         boolean committed = false;
-
-        try {
-            // Here, go offline.
-            // Need to reference count operations when they drop to zero
-            // or a timer goes off, we delete the dataset.
-
+        synchronized(lock) {
             // Redo check inside transaction.
             DataAccessPoint ref = action.getDataAccessPointRegistry().get(name);
             if ( ref == null )
@@ -372,7 +322,6 @@ public class ActionDatasets extends ActionContainerItem {
                 // ---- Unmanaged
                 action.log.warn(format("[%d] Can't delete database configuration - not a managed database; dataset=%s", action.id, name));
 //                ServletOps.errorOccurred(format("Can't delete database - not a managed configuration", name));
-                systemDSG.commit();
                 committed = true;
                 ServletOps.success(action);
                 return;
@@ -381,10 +330,8 @@ public class ActionDatasets extends ActionContainerItem {
             if  ( configurationFiles.size() > 1 ) {
                 // -- This should not happen.
                 action.log.warn(format("[%d] There are %d configuration files, not one.", action.id, configurationFiles.size()));
-                ServletOps.errorOccurred(
-                    format(
-                        "There are %d configuration files, not one. Delete not performed; clearup of the filesystem needed.",
-                        configurationFiles.size()));
+                ServletOps.errorOccurred(format("There are %d configuration files, not one. Delete not performed; clearup of the filesystem needed.",
+                                                configurationFiles.size()));
                 return;
             }
 
@@ -407,7 +354,7 @@ public class ActionDatasets extends ActionContainerItem {
             // Unclear what's holding the transaction (maybe another test clearing up slowly).
             try {
                 dataService.shutdown();
-            } catch (/*DBOE*/ TransactionException ex) { }
+            } catch (/*DBOE*/ Exception ex) { }
             // JENA-1481: Really delete files.
             if ( ( isTDB1 || isTDB2 ) ) {
                 // Delete databases created by the UI, or the admin operation, which are
@@ -428,25 +375,7 @@ public class ActionDatasets extends ActionContainerItem {
                     }
                 }
             }
-
-            // -- System database
-            // Find graph associated with this dataset name.
-            // (Statically configured databases aren't in the system database.)
-            Node n = NodeFactory.createLiteralString(DataAccessPoint.canonical(name));
-            Quad q = getOne(systemDSG, null, null, pServiceName.asNode(), n);
-//            if ( q == null )
-//                ServletOps.errorBadRequest("Failed to find dataset for '"+name+"'");
-            if ( q != null ) {
-                Node gn = q.getGraph();
-                //action.log.info("SHUTDOWN NEEDED"); // To ensure it goes away?
-                systemDSG.deleteAny(gn, null, null, null);
-            }
-            systemDSG.commit();
-            committed = true;
             ServletOps.success(action);
-        } finally {
-            if ( ! committed ) systemDSG.abort();
-            systemDSG.end();
         }
     }
 
@@ -490,35 +419,6 @@ public class ActionDatasets extends ActionContainerItem {
         DataUploader.incomingData(action, dest);
     }
 
-    // Persistent state change.
-    private static void setDatasetState(String name, Resource newState) {
-        boolean committed = false;
-        system.begin(ReadWrite.WRITE);
-        try {
-            String dbName = name;
-            if ( dbName.startsWith("/") )
-                dbName = dbName.substring(1);
-
-            String update =  StrUtils.strjoinNL
-                (PREFIXES,
-                 "DELETE { GRAPH ?g { ?s fu:status ?state } }",
-                 "INSERT { GRAPH ?g { ?s fu:status "+FmtUtils.stringForRDFNode(newState)+" } }",
-                 "WHERE {",
-                 "   GRAPH ?g { ?s fu:name '"+dbName+"'; ",
-                 "                 fu:status ?state .",
-                 "   }",
-                 "}"
-                 );
-            UpdateRequest req =  UpdateFactory.create(update);
-            UpdateAction.execute(req, system);
-            system.commit();
-            committed = true;
-        } finally {
-            if ( ! committed ) system.abort();
-            system.end();
-        }
-    }
-
     // ---- Auxiliary functions
 
     private static Quad getOne(DatasetGraph dsg, Node g, Node s, Node p, Node o) {
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
index 2be3a35dd6..19ae12803b 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/FusekiWebapp.java
@@ -219,12 +219,9 @@ public class FusekiWebapp
     public static void initializeDataAccessPoints(DataAccessPointRegistry registry, FusekiArgs initialSetup, String configDir) {
         List<DataAccessPoint> configFileDBs = initServerConfiguration(initialSetup);
         List<DataAccessPoint> directoryDBs =  FusekiConfig.readConfigurationDirectory(configDir);
-        List<DataAccessPoint> systemDBs =     FusekiConfig.readSystemDatabase(SystemState.getDataset());
-
         List<DataAccessPoint> datapoints = new ArrayList<>();
         datapoints.addAll(configFileDBs);
         datapoints.addAll(directoryDBs);
-        datapoints.addAll(systemDBs);
 
         datapoints.forEach(registry::register);
     }
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java b/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
deleted file mode 100644
index bf7becccb2..0000000000
--- a/jena-fuseki2/jena-fuseki-webapp/src/main/java/org/apache/jena/fuseki/webapp/SystemState.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.fuseki.webapp;
-
-import org.apache.jena.atlas.lib.FileOps;
-import org.apache.jena.fuseki.Fuseki;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.tdb1.TDB1;
-import org.apache.jena.tdb1.TDB1Factory;
-import org.apache.jena.tdb1.base.block.FileMode;
-import org.apache.jena.tdb1.base.file.Location;
-import org.apache.jena.tdb1.setup.StoreParams;
-import org.apache.jena.tdb1.sys.StoreConnection;
-import org.apache.jena.tdb1.transaction.DatasetGraphTransaction;
-
-/**
- * Small database to record the system state.
- * Used in the Full Fuseki server.
- */
-public class SystemState {
-    private static String SystemDatabaseLocation;
-    // Testing may reset this.
-    public static Location location;
-
-    private  static Dataset                 dataset   = null;
-    private  static DatasetGraphTransaction dsg       = null;
-
-    public static Dataset getDataset() {
-        init();
-        return dataset;
-    }
-
-    public static DatasetGraphTransaction getDatasetGraph() {
-        init();
-        return dsg;
-    }
-
-    private static boolean initialized = false;
-    private static void init() {
-        init$();
-    }
-
-    /** Small footprint database.  The system database records the server state.
-     * It should not be performance critical, mainly being used for system admin
-     * functions.
-     * <p>Direct mode so that it is not competing for OS file cache space.
-     * <p>Small caches -
-     */
-    private static final StoreParams systemDatabaseParams = StoreParams.builder()
-        .fileMode(FileMode.direct)
-        .blockSize(1024)
-        .blockReadCacheSize(50)
-        .blockWriteCacheSize(20)
-        .node2NodeIdCacheSize(500)
-        .nodeId2NodeCacheSize(500)
-        .nodeMissCacheSize(100)
-        .build();
-
-    public /* for testing */ static void init$() {
-        if ( initialized )
-            return;
-        initialized = true;
-
-        if ( location == null )
-            location = Location.create(FusekiWebapp.dirSystemDatabase.toString());
-
-        if ( ! location.isMem() )
-            FileOps.ensureDir(location.getDirectoryPath());
-
-        // Force it into the store connection as a low footprint
-        if ( StoreConnection.getExisting(location) != null )
-            Fuseki.serverLog.warn("System database already in the StoreConnection cache");
-        StoreConnection.make(location, systemDatabaseParams);
-
-        dataset = TDB1Factory.createDataset(location);
-        dsg     = (DatasetGraphTransaction)(dataset.asDatasetGraph());
-        dsg.getContext().set(TDB1.symUnionDefaultGraph, false);
-    }
-}
-
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
index 9641099d60..39838f9ed8 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/ServerCtl.java
@@ -33,13 +33,11 @@ import org.apache.jena.fuseki.cmd.JettyServerConfig;
 import org.apache.jena.fuseki.webapp.FusekiEnv;
 import org.apache.jena.fuseki.webapp.FusekiServerListener;
 import org.apache.jena.fuseki.webapp.FusekiWebapp;
-import org.apache.jena.fuseki.webapp.SystemState;
 import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.DatasetGraphFactory;
 import org.apache.jena.sparql.modify.request.Target;
 import org.apache.jena.sparql.modify.request.UpdateDrop;
 import org.apache.jena.system.Txn;
-import org.apache.jena.tdb1.base.file.Location;
 import org.apache.jena.update.Update;
 import org.apache.jena.update.UpdateExecutionFactory;
 import org.apache.jena.update.UpdateProcessor;
@@ -230,9 +228,6 @@ public class ServerCtl {
     }
 
     public static void setupServer(int port, String authConfigFile, String datasetPath, boolean updateable) {
-        SystemState.location = Location.mem();
-        SystemState.init$();
-
         FusekiArgs params = new FusekiArgs();
         dsgTesting = DatasetGraphFactory.createTxnMem();
         params.dsg = dsgTesting;
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
index d0866ca525..7a89107326 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdmin.java
@@ -254,38 +254,38 @@ public class TestAdmin extends AbstractFusekiWebappTest {
         HttpTest.expect404( ()-> httpDelete(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+name) );
     }
 
-    // ---- Active/Offline.
-
-    @Test public void state_1() {
-        // Add one
-        addTestDataset();
-        try {
-            checkExists(dsTest);
-
-            httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=offline");
-
-            checkExistsNotActive(dsTest);
-
-            httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=active");
-
-            checkExists(dsTest);
-        } finally {
-            deleteDataset(dsTest);
-        }
-    }
-
-    @Test public void state_2() {
-        addTestDataset();
-        httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=offline");
-        deleteDataset(dsTest);
-        checkNotThere(dsTest);
-    }
-
-    @Test public void state_3() {
-        addTestDataset();
-        HttpTest.expect404(()->httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/DoesNotExist?state=offline"));
-        deleteDataset(dsTest);
-    }
+//    // ---- Active/Offline.
+//
+//    @Test public void state_1() {
+//        // Add one
+//        addTestDataset();
+//        try {
+//            checkExists(dsTest);
+//
+//            httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=offline");
+//
+//            checkExistsNotActive(dsTest);
+//
+//            httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=active");
+//
+//            checkExists(dsTest);
+//        } finally {
+//            deleteDataset(dsTest);
+//        }
+//    }
+//
+//    @Test public void state_2() {
+//        addTestDataset();
+//        httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/"+dsTest+"?state=offline");
+//        deleteDataset(dsTest);
+//        checkNotThere(dsTest);
+//    }
+//
+//    @Test public void state_3() {
+//        addTestDataset();
+//        HttpTest.expect404(()->httpPost(ServerCtl.urlRoot()+"$/"+opDatasets+"/DoesNotExist?state=offline"));
+//        deleteDataset(dsTest);
+//    }
 
     // ---- Backup
 
diff --git a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
index 84d6be179f..729ff40ac5 100644
--- a/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
+++ b/jena-fuseki2/jena-fuseki-webapp/src/test/java/org/apache/jena/fuseki/TestAdminAPI.java
@@ -46,24 +46,6 @@ public class TestAdminAPI extends AbstractFusekiWebappTest {
         testAddDelete("db_mem", "mem", false);
     }
 
-    // These aren't stable on github-actions.
-    // Outstanding transactions infer with cleanup.
-    // See ActionDataset.execDeleteItem.
-
-//    @Test public void add_delete_api_2() throws Exception {
-//        // Deleted mmap files on Windows does not go away until the JVM exits.
-//        if ( org.apache.jena.tdb.sys.SystemTDB.isWindows )
-//            return;
-//        testAddDelete("db_tdb", "tdb", true);
-//    }
-//
-//    @Test public void add_delete_api_3() throws Exception {
-//        // Deleted mmap files on Windows does not go away until the JVM exits.
-//        if ( org.apache.jena.tdb.sys.SystemTDB.isWindows )
-//            return;
-//        testAddDelete("db_tdb2", "tdb2", true);
-//    }
-
     private static void testAddDelete(String dbName, String dbType, boolean hasFiles) {
         String datasetURL = ServerCtl.urlRoot()+dbName;
         String admin = ServerCtl.urlRoot()+"$/";