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 <[email protected]> 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()+"$/";
