🚀 Overview • 📦 Installation • ⚙️ Usage • 🛠️ Developer Guide • 📊 Evaluation
Table of Contents
- Overview
- Installation
- Usage
- Developer API (Java / SDK)
- REST / Server Usage
- Configuration
- Authorization
- POST
/auth/register - POST
/auth/token - GET
/auth/me - POST
/auth/logout - GET
/config - GET
/config/{name} - GET
/sparql - POST
/sparql - POST
/update - GET
/graph - POST
/graph - DELETE
/graph/{uri} - POST
/graph/share - DELETE
/graph/share - GET
/graph/access - POST
/resource/share - DELETE
/resource/share - GET
/resource/access - POST
/upload - GET
/principal
- Developer Guide
- Evaluation
Corporate Memories are computer systems in organizations that continuously collect, update and structure knowledge for various tasks. The Resource Description Framework (RDF) is commonly used to represent such knowledge, which is stored in quadstores as subject–predicate–object–graph quadruples. Since typical RDF stores lack crucial features for enterprise scenarios, we propose an initial version of a tailored quadstore as part of a larger system called ATIC. Our implementation in this demo paper comprises RDF management with an SQLite backend, Discretionary Access Control on graphs and resources, confidence-attributed triples, change tracking with RDF patches and a virtual graph for accessing a file hosting service via RDF. This is accompanied with a server component providing endpoints and corresponding frontends. Results of a preliminary evaluation verify the correct operation of our prototype and indicate moderate performance.
Our demo page contains a link to a deployed instance for testing and also presents a video showing the main aspects in action.
To build and install all projects, run:
mvn install
If you would like to skip the JUnit test cases, run:
mvn install -DskipTests
If you would like to get the executable atic.jar which contains the server component, run:
mvn install -DskipTests -Pdeploy -pl atic-server -am
You will find the file under atic-server/target/atic.jar.
Include this project in your pom.xml as a dependency:
<dependency>
<groupId>de.dfki.sds</groupId>
<artifactId>atic-sqlite</artifactId>
<version>1.0.0</version>
</dependency>Use its factory, to create an instance (similar to TDB2):
Dataset dataset = AticFactory.connectDataset("path/to/folder");For testing purposes, you can create a DatasetGraph backed by a temporary storage location.
DatasetGraph datasetGraph = AticFactory.createTxn();Use this for accessing the DatasetGraph as admin user.
DatasetGraph datasetGraph = AticFactory.createTxnAdminDataset();Use it as a Jena Dataset.
To switch the user who invokes the calls:
User user = server.getDatasetGraph().calculateRead(() -> {
return server.getDatasetGraph().getUser(username, InvocationContext.EMPTY);
});
InvocationContext ictx = new InvocationContext.Builder().fromUser(user).build();
ictx.transferContext(dataset.getContext());Cast to our specific implementation to access the methods.
DatasetGraph datasetGraph;
SqliteAticDatasetGraph aticDatasetGraph = (SqliteAticDatasetGraph) datasetGraph;Each method is extended with an InvocationContext which mainly states what user is requesting the operation.
You can build an InvocationContext from a User in the following way:
User user = server.getDatasetGraph().calculateRead(() -> {
return server.getDatasetGraph().getUser(username, InvocationContext.EMPTY);
});
InvocationContext ictx = new InvocationContext.Builder().fromUser(user).build();Users with different permissions may receive different results for the same operations and arguments.
InvocationContext user1ctx;
InvocationContext user2ctx;
datasetGraph.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY, user1ctx);
datasetGraph.find(Node.ANY, Node.ANY, Node.ANY, Node.ANY, user2ctx);To pass no InvocationContext use InvocationContext.EMPTY constant.
String addUser(String firstname, String lastname, String email, String username, InvocationContext ctx)void addGroup(String groupname, InvocationContext ctx)User getUser(String username, InvocationContext ctx)User getUser(int userId, InvocationContext ctx)Group getGroup(String groupname, InvocationContext ctx)void assignUserToGroup(String username, String groupname, InvocationContext ctx)void unassignUserFromGroup(String username, String groupname, InvocationContext ctx)List<User> searchUsers(String query, InvocationContext ctx)List<Group> searchGroups(String query, InvocationContext ctx)List<Principal> searchPrincipals(String query, InvocationContext ctx)
void shareGraphs(Set<String> graphUris, Set<String> groupUris, Permission permission, InvocationContext ctx)void unshareGraphs(Set<String> graphUris, Set<String> groupUris, InvocationContext ctx)void shareResources(Set<String> resourceUris, Set<String> groupUris, Permission permission, InvocationContext ctx)void unshareResources(Set<String> resourceUris, Set<String> groupUris, InvocationContext ctx)Map<String, Permission> listResourcePermissions(Set<String> resourceUris, InvocationContext ctx)Map<String, Permission> listGraphPermissions(Set<String> graphUris, InvocationContext ctx)Map<String, List<PrincipalPermission>> listPrincipalPermissions( Set<String> uris, boolean forGraphs, InvocationContext ctx)
void addVirtualGraph(Node graphName, String factoryMethodPath, JSONObject config, InvocationContext ctx)
void apply(RDFPatch rdfPatch, InvocationContext ctx)void addListener(RDFPatchListener listener)void removeListener(RDFPatchListener listener)
void generateLUBMftGraph(Node graphName, int univNum, int startIndex, int seed, boolean names, boolean docs, int bufferSize, int batchSize, InvocationContext ctx)
void enableQueryLogger(String dbFilePath)void disableQueryLogger()
Use the atic.jar built by the atic-server project (see Installation).
export JWT_SECRET="my-secret"
java -jar atic.jarBy default, the server runs at http://127.0.0.1:6583.
Use --help for possible CLI arguments.
java -jar atic.jar --help
You can also specify the options in a atic.toml file located in the working directory.
It is also possible to specify the options as environment variables.
In this case, an option, for example, instance.name has to be defined as ATIC_INSTANCE_NAME.
All endpoints except /auth/register and /auth/token require a bearer token:
-H "Authorization: Bearer <TOKEN>"Creates a new user account.
curl -X POST http://127.0.0.1:6583/auth/register \
-d "firstname=John" \
-d "lastname=Doe" \
-d "email=john@example.org" \
-d "username=jdoe"A generated password is returned.
Passwords are stored for lookup in a passwords.json.generated file.
Authenticates a user and returns a JWT access token.
curl -X POST http://127.0.0.1:6583/auth/token \
-d "username=jdoe" \
-d "password=secret"On success, the server returns a JSON response containing the access token (and a corresponding cookie):
{
"access_token": "<TOKEN>",
"successful": true,
"redirect": "/"
}Returns information about the currently authenticated user.
curl \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/auth/meLogs out the current user.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/auth/logoutReturns all visible configuration entries.
curl \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/configReturns a single configuration value.
curl \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/config/portExecutes a SPARQL query.
curl --get \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/sparql \
--data-urlencode "query=SELECT * WHERE { ?s ?p ?o } LIMIT 10"Executes a SPARQL query.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/sparql \
--data 'SELECT * WHERE { ?s ?p ?o } LIMIT 10'Executes a SPARQL Update request.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/update \
--data 'INSERT DATA { GRAPH <https://example.org/g> { <a> <b> <c> } }'Returns graphs accessible to the current user.
curl \
-H "Authorization: Bearer <TOKEN>" \
"http://127.0.0.1:6583/graph"curl \
-H "Authorization: Bearer <TOKEN>" \
"http://127.0.0.1:6583/graph?triples"curl \
-H "Authorization: Bearer <TOKEN>" \
"http://127.0.0.1:6583/graph?permissions"Creates a graph.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/graphcurl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
http://127.0.0.1:6583/graph \
-d '{"graph":"https://example.org/graph/my-graph"}'Deletes a graph.
curl -X DELETE \
-H "Authorization: Bearer <TOKEN>" \
"http://127.0.0.1:6583/graph/https%3A%2F%2Fexample.org%2Fgraph%2Fmy-graph"Shares graphs with groups.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
http://127.0.0.1:6583/graph/share \
-d '{
"graphs": ["https://example.org/graph/a"],
"groups": ["https://example.org/group/admins"],
"permission": "READ"
}'Removes a previously granted permission from groups.
curl -X DELETE \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
http://127.0.0.1:6583/graph/share \
-d '{
"graphs": ["https://example.org/graph/a"],
"groups": ["https://example.org/group/admins"],
"permission": "READ"
}'Returns the permissions assigned to one or more graphs.
The endpoint accepts one or more graph URIs via the uri query parameter.
curl --get \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/graph/access \
--data-urlencode "uri=https://example.org/graph/a"Response:
{
"https://example.org/graph/a": [
{
"principalName": "Administrators",
"principalUri": "https://example.org/group/admins",
"principalShareUri": "https://example.org/share/admins",
"permission": "ADMIN",
"type": "group"
},
{
"principalName": "John Doe",
"principalUri": "https://example.org/user/jdoe",
"principalShareUri": "https://example.org/share/jdoe",
"permission": "READ",
"type": "user"
}
]
}Shares resources with groups.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
http://127.0.0.1:6583/resource/share \
-d '{
"resources": ["https://example.org/resource/a"],
"groups": ["https://example.org/group/admins"],
"permission": "READ"
}'Removes a previously granted permission from groups.
curl -X DELETE \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
http://127.0.0.1:6583/resource/share \
-d '{
"resources": ["https://example.org/resource/a"],
"groups": ["https://example.org/group/admins"],
"permission": "READ"
}'Returns the permissions assigned to one or more resources.
The endpoint accepts one or more resource URIs via the uri query parameter.
curl --get \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/resource/access \
--data-urlencode "uri=https://example.org/resource/a"Response:
{
"https://example.org/resource/a": [
{
"principalName": "Researchers",
"principalUri": "https://example.org/group/researchers",
"principalShareUri": "https://example.org/share/researchers",
"permission": "READ",
"type": "group"
},
{
"principalName": "John Doe",
"principalUri": "https://example.org/user/jdoe",
"principalShareUri": "https://example.org/share/jdoe",
"permission": "EDIT",
"type": "user"
}
]
}Uploads RDF data or files.
Optionally, the imported data can be assigned to a graph and permissions can be granted to groups for resources contained in the imported dataset.
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-F "file=@data.ttl" \
http://127.0.0.1:6583/uploadUpload into a specific graph:
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-F "file=@data.ttl" \
-F "graph=https://example.org/graph/my-graph" \
http://127.0.0.1:6583/uploadUpload data and grant read access to a group for imported resources:
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-F "file=@data.ttl" \
-F "group=https://example.org/group/researchers" \
-F "permission=READ" \
http://127.0.0.1:6583/uploadUpload data with custom import settings:
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-F "file=@data.ttl" \
-F "buffer-size=1000" \
-F "batch-size=1000" \
http://127.0.0.1:6583/uploadSearches principals (users and groups) matching the provided search query.
curl --get \
-H "Authorization: Bearer <TOKEN>" \
http://127.0.0.1:6583/principal \
--data-urlencode "query=admin"The response contains a list of matching principals:
{
"principals": [
{
"uri": "https://example.org/group/admins",
"name": "Administrators"
}
]
}The following projects exist:
- atic-api - contains interfaces and data classes
- atic-sqlite - quadstore implementation for SQLite
- atic-server - server component and frontends
Additonal projects for evaluation:
- atic-sqlite-tdb2tests - JUnit test cases from TDB2
- atic-sqlite-jmh - uses Java Microbenchmark Harness (JMH) for benchmarking
The API project is separated into six packages: jenatic, ac (Access Control), api, conf, helper, and vocab.
jenatic is a blend word between Jena and ATIC to emphasise that Jena interfaces are extended for our prototype.
InvocationContext is a class to express the invocation of Jena methods from a certain context.
It is mainly used to state which user invokes the method by providing userId, primaryGroupId and groupIds.
AticDatasetGraph extends Jena's DatasetGraph class by adding for certain methods context-awareness in form of an additional InvocationContext method parameter.
In case a legacy Jena method is called, InvocationContext.EMPTY is passed.
Analogously, AticGraph extends Jena's Graph interface.
To pass more information in a triple, AticTriple extends Jena's Triple class.
Currently, an additional confidence value can be stored.
For virtual graphs, a separate AticVirtualGraph exists which extends the AticGraph with an additonal method:
Since virtual graphs are allowed to response to REST requests, a handleRequest method can be implemented.
The method returns AticVirtualGraphResponse.
The UserGroupManagement interface defines methods for adding or removing users and groups as well as user group assignments. The SharingManagement interface defines methods for giving permissions to graphs and resources to principals. A Principal (like User or Group) can receive a permission from the Permission enum. If a permission is denied a PermissionDeniedException is thrown.
The general api package contains data classes for two aspects: associating numeric id values with textual URI values (IdAndUri) and mapping between objects and URIs used in virtual graphs (UriMapper).
The package is used for configuration management.
Config is a field annotation used in ConfigLoader.
The loader class is able to read configurations passed with Config annotations from TOML file, CLI arguments or environment variables.
This project contains the Quadstore implementation.
SQL files defining the database schema are located here.
The schema is separated in four areas: Resource Description Framework (RDF), User & Group Management, Access Control and RDF-star.
Quadruples with literal objects are stored in splg table, while quadruples with resource objects are stored in spog table. Both store provenance information for creator (user) and created_at time as well as a confidence value.
A separate graph table manages graphs (fourth component of quadruple).
Aagin, provenance information for creator (user) and created_at time is saved.
Additionally, for virtual graphs corresponding meta-data is recorded.
Resources are stored in resource table and properties are stored in property table.
Aagin, provenance information for creator (user) and created_at time is saved.
Since a resource can be either a URI (including blank node) or triple term (RDF-star), there are additional tables resource_uri as well as resource_spo and resource_spl (see RDF-star).
For blank nodes, is_blank is set to 1 and uri is used for a skolemized blank node label.
Prefix mapping is recorded in prefixmap table.
Users are stored in a user table with username, firstname, lastname, email and hashed password metadata as well as uniquely generated uri.
Groups are stored in group table with groupname and uniquely generated uri.
Since each user has a primary group (same groupname as username), a primary group refers to its user with user_id.
Assignments of users to groups is recorded in user_group_assignment.
Access control is enforced on resources (resource_acl) and graphs (graph_acl).
In both cases, the group_id that receives the permission which was granted by a group (granted_by_group_id) is recorded.
The permission code is defined as follows: READ=1, REFER=2, EDIT=3, ADMIN=4.
If the target is a user, its primary group is used, otherwise a regular group is used.
Triple terms are stored in resource_spo table for triples with URI objects and resource_spl table for triples with literal objects.
They refer to resource and property table.
The Database interface class extends Jena's Transactional interface and provides methods for reading from and writing into a database.
DatabaseLongLivedConnection is an implementation that features long-lived connections as well as prepared and cached SQL statements for performance (PooledPreparedStatement).
Since it implements the Jena's Transactional interface, it also features transactions.
It can be configured through DatabaseOptions.
RDF management is implemented in SqliteAticDatasetGraph and SqliteAticGraph.
SqliteAticDatasetGraph uses a passed Database implementation to read and write database records.
It implements methods for database bootstrapping, user & group management, access control (sharing) and (virtual) graph management.
Reading and writing RDF is passed down to the SqliteAticGraph implementation.
The SqliteAticGraph class implements the main methods add, remove, find, contains and size.
For performance reasons, added triples are stored in a in-memory queue until a configured threshold is reached (SqliteAticGraph.setDefaultBufferSize).
This reduces communication with the database and allows to update the database in batches.
The find method requires additional helper classes: TransactionalResultSet is a database result set which is aware of the transaction is was created.
It is used by PagedTripleIterator that is aware of a limited (paged) triple iteration.
It uses a passed ResultSetTripleMapper implementation to map the database resultset to RDF triples.
SqlitePrefixMap implements the storage and retrieval of prefix mappings using the database.
RDFPatchEmitterTransactional is used by SqliteAticDatasetGraph to emit RDF patches for each transaction.
It informs a list of given RDFPatchListeners.
The AticFactory provides methods to create a SqliteAticDatasetGraph instance.
Two virtual graph implementations are available: LocalFilesystemVirtualGraph and WebdavVirtualGraph. The latter is used to access a Nextcloud instance via its WebDAV endpoint during the demo.
For performance reasons, we modified JDBC3Statement: The method getResultSet is extended with an argument boolean skipColsMeta to be able to skip the retrieval of column names.
This project contains the server implementation.
The Main class contains the main method which loads configuration and starts the server.
AticConfig contains all config options.
AticServer contains the Javalin-based server.
Here, all endpoints are defined.
It uses ConfigDrivenCrudEndpoints implementation.
An example YAML configuration file is person.yml.
AticServer uses also MoleculeEndpoint.
RDFPatchWriter is a RDFPatchListener and writes for each transaction into an SQLite database using rdfpatch-sqlite project.
In a preliminary evaluation, our quadstore is assessed with respect to two aspects: correctness and performance.
We added JUnit test cases in atic-sqlite.
Running de.dfki.sds.aticsqlite.LimitOffsetUnitTest
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.742 s -- in de.dfki.sds.aticsqlite.LimitOffsetUnitTest
Running de.dfki.sds.aticsqlite.SparqlBasedUnitTest
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.642 s -- in de.dfki.sds.aticsqlite.SparqlBasedUnitTest
Running de.dfki.sds.aticsqlite.QueryLoggerUnitTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.067 s -- in de.dfki.sds.aticsqlite.QueryLoggerUnitTest
Running de.dfki.sds.aticsqlite.BSBMUnitTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.105 s -- in de.dfki.sds.aticsqlite.BSBMUnitTest
Running de.dfki.sds.aticsqlite.BlankNodeUnitTest
Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.934 s -- in de.dfki.sds.aticsqlite.BlankNodeUnitTest
Running de.dfki.sds.aticsqlite.GraphUnitTest
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.554 s -- in de.dfki.sds.aticsqlite.GraphUnitTest
Running de.dfki.sds.aticsqlite.ResourceSharingUnitTest
Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.509 s -- in de.dfki.sds.aticsqlite.ResourceSharingUnitTest
Running de.dfki.sds.aticsqlite.VirtualGraphUnitTest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.280 s -- in de.dfki.sds.aticsqlite.VirtualGraphUnitTest
Running de.dfki.sds.aticsqlite.ComparisonUnitTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.290 s -- in de.dfki.sds.aticsqlite.ComparisonUnitTest
Running de.dfki.sds.aticsqlite.ConsistencyUnitTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.309 s -- in de.dfki.sds.aticsqlite.ConsistencyUnitTest
Running de.dfki.sds.aticsqlite.FactoryUnitTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.108 s -- in de.dfki.sds.aticsqlite.FactoryUnitTest
Running de.dfki.sds.aticsqlite.DatasetGraphUnitTest
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.463 s -- in de.dfki.sds.aticsqlite.DatasetGraphUnitTest
Running de.dfki.sds.aticsqlite.RdfStarUnitTest
Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.535 s -- in de.dfki.sds.aticsqlite.RdfStarUnitTest
Running de.dfki.sds.aticsqlite.GraphSharingUnitTest
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.468 s -- in de.dfki.sds.aticsqlite.GraphSharingUnitTest
Running de.dfki.sds.aticsqlite.DatabaseLongLivedConnectionUnitTest
Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.533 s -- in de.dfki.sds.aticsqlite.DatabaseLongLivedConnectionUnitTest
Running de.dfki.sds.aticsqlite.RDFPatchEmitterTransactionalUnitTest
Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.423 s -- in de.dfki.sds.aticsqlite.RDFPatchEmitterTransactionalUnitTest
Running de.dfki.sds.aticsqlite.DatabaseConnectionPerTransactionUnitTest
Tests run: 13, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.877 s -- in de.dfki.sds.aticsqlite.DatabaseConnectionPerTransactionUnitTest
Running de.dfki.sds.aticsqlite.BootstrapUnitTest
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.275 s -- in de.dfki.sds.aticsqlite.BootstrapUnitTest
Results:
Tests run: 145, Failures: 0, Errors: 0, Skipped: 0
In atic-sqlite-tdb2tests, we collected TDB2 JUnit tests.
The only modification made to the code was replacing TDB2 with our quadstore instance, mainly in the TL class and other places (look for AticFactory).
Running org.apache.jena.tdb2.solver.TestSolverTDB
Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.407 s -- in org.apache.jena.tdb2.solver.TestSolverTDB
Running org.apache.jena.tdb2.graph.TestDatasetGraphTDB2
Tests run: 32, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 1.843 s -- in org.apache.jena.tdb2.graph.TestDatasetGraphTDB2
Running org.apache.jena.tdb2.graph.TestPrefixMappingTDB2
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.441 s -- in org.apache.jena.tdb2.graph.TestPrefixMappingTDB2
Running org.apache.jena.tdb2.graph.TestGraphViewSwitchable
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.059 s -- in org.apache.jena.tdb2.graph.TestGraphViewSwitchable
Running org.apache.jena.tdb2.graph.TestGraphsTDB2_B
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.230 s -- in org.apache.jena.tdb2.graph.TestGraphsTDB2_B
Running org.apache.jena.tdb2.graph.TestGraphOverDatasetTDB2
Tests run: 11, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.611 s -- in org.apache.jena.tdb2.graph.TestGraphOverDatasetTDB2
Running org.apache.jena.tdb2.graph.TestPrefixMappingTDBExtra
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.891 s -- in org.apache.jena.tdb2.graph.TestPrefixMappingTDBExtra
Running org.apache.jena.tdb2.graph.TestGraphsTDB2_A
Tests run: 20, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.110 s -- in org.apache.jena.tdb2.graph.TestGraphsTDB2_A
Running org.apache.jena.tdb2.store.TestTransPromoteTDB
Tests run: 24, Failures: 0, Errors: 0, Skipped: 24, Time elapsed: 0 s -- in org.apache.jena.tdb2.store.TestTransPromoteTDB
Running org.apache.jena.tdb2.store.TestVisibilityOfChanges
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.246 s -- in org.apache.jena.tdb2.store.TestVisibilityOfChanges
Running org.apache.jena.tdb2.store.TestGraphTDB
Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.890 s -- in org.apache.jena.tdb2.store.TestGraphTDB
Running org.apache.jena.tdb2.store.TestQueryExecTDB
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.120 s -- in org.apache.jena.tdb2.store.TestQueryExecTDB
Running org.apache.jena.tdb2.store.TestGraphNamedTDB
Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.881 s -- in org.apache.jena.tdb2.store.TestGraphNamedTDB
Running org.apache.jena.tdb2.store.TestTransactionLifecycleTDB
Tests run: 51, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.798 s -- in org.apache.jena.tdb2.store.TestTransactionLifecycleTDB
Running org.apache.jena.tdb2.store.TestDynamicDatasetTDB
Tests run: 27, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.505 s -- in org.apache.jena.tdb2.store.TestDynamicDatasetTDB
Running org.apache.jena.tdb2.store.TestTransactions
Tests run: 7, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.336 s -- in org.apache.jena.tdb2.store.TestTransactions
Running org.apache.jena.tdb2.store.Test_SPARQL_TDB
Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.408 s -- in org.apache.jena.tdb2.store.Test_SPARQL_TDB
Running org.apache.jena.tdb2.store.TestDatasetTDB
Tests run: 12, Failures: 0, Errors: 0, Skipped: 2, Time elapsed: 0.558 s -- in org.apache.jena.tdb2.store.TestDatasetTDB
Results:
Tests run: 269, Failures: 0, Errors: 0, Skipped: 29
The Java Microbenchmark Harness (JMH) is used to get benchmark results.
- Java Class: AticTdbComparisonBsbmLoading.java
- Benchmark Result in JSON: AticTdbComparisonBsbmLoading.json
- Java Class: AticTdbComparisonBsbmQueryMix.java
- Benchmark Result in JSON: AticTdbComparisonBsbmQueryMix.json


