@innotrade/enapso-graphdb-admin
Version:
ENAPSO Graph Database Admin Tools for Node.js
804 lines (752 loc) • 28 kB
JavaScript
// Innotrade ENAPSO - Graph Database Admin Example
// (C) Copyright 2021-2022 Innotrade GmbH, Herzogenrath, NRW, Germany
// Author(s): Alexander Schulze and Muhammad Yasir
// require the ENAPSO Graph Database Admin Demo module
require('@innotrade/enapso-config');
const fsPromises = require('fs').promises,
{ EnapsoGraphDBClient } = requireEx('@innotrade/enapso-graphdb-client'),
{ EnapsoGraphDBAdmin } = require('../index'),
{ EnapsoLogger, EnapsoLoggerFactory } = require('@innotrade/enapso-logger');
EnapsoLoggerFactory.createGlobalLogger('enLogger');
enLogger.setLevel(EnapsoLogger.ALL);
// // connection data to the running Graph Database instance
const GRAPHDB_BASE_URL = encfg.getConfig(
'enapsoDefaultGraphDB.baseUrl',
'http://localhost:7200'
),
GRAPHDB_REPOSITORY = encfg.getConfig(
'enapsoDefaultGraphDB.repository',
'Test'
),
GRAPHDB_USERNAME = encfg.getConfig(
'enapsoDefaultGraphDB.userName',
'admin'
),
GRAPHDB_PASSWORD = encfg.getConfig('enapsoDefaultGraphDB.password', 'root'),
GRAPHDB_CONTEXT_TEST = encfg.getConfig(
'enapsoDefaultGraphDB.ContextTest',
'http://ont.enapso.com/test'
),
GRAPHDB_CONTEXT_SHACL = encfg.getConfig(
'enapsoDefaultGraphDB.ContextShacl',
'http://rdf4j.org/schema/rdf4j#SHACLShapeGraph'
),
GRAPHDB_API_TYPE = 'RDF4J',
GRAPHDB_VERSION = 10.2,
triplestore = 'graphdb';
// triplestore = 'graphdb';
// // the default prefixes for all SPARQL queries
const GRAPHDB_DEFAULT_PREFIXES = [
EnapsoGraphDBClient.PREFIX_OWL,
EnapsoGraphDBClient.PREFIX_RDF,
EnapsoGraphDBClient.PREFIX_RDFS
];
enLogger.info(
'ENAPSO Graph Database Admin Demo\n(C) Copyright 2021-2022 Innotrade GmbH, Herzogenrath, NRW, Germany'
);
const EnapsoGraphDBAdminDemo = {
graphDBEndpoint: null,
authentication: null,
createEndpoint() {
try {
// instantiate a new Graph Database endpoint
return new EnapsoGraphDBClient.Endpoint({
baseURL: GRAPHDB_BASE_URL,
repository: GRAPHDB_REPOSITORY,
prefixes: GRAPHDB_DEFAULT_PREFIXES,
apiType: GRAPHDB_API_TYPE,
triplestore: triplestore,
version: GRAPHDB_VERSION
});
} catch (err) {
console.log(err);
}
},
// login: async function () {
async login() {
try {
// login into Graph Database using JWT
let lRes = await this.graphDBEndpoint.login(
GRAPHDB_USERNAME,
GRAPHDB_PASSWORD
);
return lRes;
} catch (err) {
console.log(err);
}
},
async demoCreateRepository() {
try {
let resp = await this.graphDBEndpoint.createRepository({
id: 'AutomatedTest',
title: 'enapso Automated Test Repository',
location: '',
isShacl: true
});
enLogger.info('Create Repository:' + JSON.stringify(resp, null, 2));
} catch (err) {
console.log(err);
}
},
async demoCreateUser() {
try {
let lRes = await this.graphDBEndpoint.login(
GRAPHDB_USERNAME,
GRAPHDB_PASSWORD
);
// todo: interpret lRes here, it does not makes sense to continue if login does not work!
let resp = await this.graphDBEndpoint.createUser({
// authorities: [
// 'WRITE_REPO_Test', // Writing excess wrote WRITE_ and in last name of Repository which excess provided like REPO_Test
// 'READ_REPO_Test', // Reading excess wrote READ_ and in last name of Repository which excess provided like REPO_Test
// 'READ_REPO_Vaccine',
// 'ROLE_USER' // Role of the user
// ],
authorities: [
{
action: 'CREATE',
resource_type: 'db',
resource: ['Test']
}
],
username: 'TestUser', // Username
password: 'TestUser' // Password for the user
});
enLogger.info('Create New User:' + JSON.stringify(resp, null, 2));
} catch (err) {
console.log(err);
}
},
async demoUpdateUser() {
try {
let lRes = await this.graphDBEndpoint.login('admin', 'root');
// todo: interpret lRes here, it does not makes sense to continue if login does not work!
let resp = await this.graphDBEndpoint.updateUser({
authorities: [
// Writing excess wrote WRITE_ and in last name of Repository which excess provided like REPO_Test
'READ_REPO_Test', // Reading excess wrote READ_ and in last name of Repository which excess provided like REPO_Test
'WRITE_REPO_Vaccine',
'READ_REPO_Vaccine',
'ROLE_USER' // Role of the user
],
username: 'TestUser' // Username
});
enLogger.info(
'Update Inserted User:' + JSON.stringify(resp, null, 2)
);
} catch (err) {
console.log(err);
}
},
async demoAssignRoles(args) {
try {
let resp = await this.graphDBEndpoint.assignRoles(args);
enLogger.log(
'Assign Role to User:' + JSON.stringify(resp, null, 2)
);
} catch (err) {
console.log(err);
return err;
}
},
async demoRemoveRoles(args) {
try {
let resp = await this.graphDBEndpoint.removeRoles(args);
enLogger.log(
'Remove Role from User:' + JSON.stringify(resp, null, 2)
);
} catch (err) {
console.log(err);
return err;
}
},
async demoDeleteUser() {
try {
let lRes = await this.graphDBEndpoint.login(
GRAPHDB_USERNAME,
GRAPHDB_PASSWORD
);
// todo: interpret lRes here, it does not makes sense to continue if login does not work!
let resp = await this.graphDBEndpoint.deleteUser({
user: 'TestUser' // username which you want to delete
});
enLogger.info(
'Delete Exisiting User:' + JSON.stringify(resp, null, 2)
);
} catch (err) {
console.log(err);
}
},
async demoDeleteRepository() {
try {
let resp = await this.graphDBEndpoint.deleteRepository({
id: 'AutomatedTest'
});
enLogger.info('Delete Repository:' + JSON.stringify(resp, null, 2));
} catch (err) {
console.log(err);
}
},
async demoGetRepositories() {
try {
// lists all repositories
resp = await this.graphDBEndpoint.getRepositories();
enLogger.info('\nRepositories:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoClearRepository() {
try {
// clear entire repository
// CAUTION! This operation empties the entire repository
// and cannot be undone!
let resp = await this.graphDBEndpoint.clearRepository();
enLogger.info(
'\nClearRepository :\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoDropShaclGraph() {
try {
// clear entire repository
// CAUTION! This operation empties the entire repository
// and cannot be undone!
let resp = await this.graphDBEndpoint.dropShaclGraph();
enLogger.info(
'\nDropShaclGraph :\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoGetUsers() {
try {
// lists all users (requires admin role)
let resp = await this.graphDBEndpoint.getUsers();
enLogger.info('\nUsers:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoGetLocations() {
try {
// lists all locations, requires repository manager role!
let resp = await this.graphDBEndpoint.getLocations();
enLogger.info('\nLocations:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoGetContexts() {
try {
// lists all contexts (named graph) in the repository
let resp = await this.graphDBEndpoint.getContexts();
enLogger.info('\nContexts:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoClearContext() {
try {
// clear context (named graph)
// CAUTION! This operation empties the named graph
// of the repository and cannot be undone!
let resp =
await this.graphDBEndpoint.clearContext(GRAPHDB_CONTEXT_TEST);
enLogger.info('\nClearContext :\n' + JSON.stringify(resp, null, 2));
return;
} catch (err) {
console.log(err);
}
},
async demoGetSavedQueries() {
// clear context (named graph)
// CAUTION! This operation empties the named graph
// of the repository and cannot be undone!
try {
let resp = await this.graphDBEndpoint.getSavedQueries();
enLogger.info(
'\nGetSavedQueries :\n' + JSON.stringify(resp, null, 2)
);
return;
} catch (err) {
console.log(err);
}
},
async demoUploadFromFile() {
// upload a file
try {
let resp = await this.graphDBEndpoint.uploadFromFile({
filename: 'ontologies/dotnetpro_demo_ontology_2.owl',
format: 'application/rdf+xml'
});
enLogger.info(
'\nUploadFromFile:\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoImportServerFile() {
// upload a file
try {
let resp = await this.graphDBEndpoint.importServerFile({
filename: 'Test.ttl'
});
enLogger.info(
'\nUploadFromFile:\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoUploadFromData() {
try {
// upload a file
// todo: we upload from data here but pass a file name???
let data = await fsPromises.readFile(
'../ontologies/EnapsoTest.owl',
'utf-8'
);
let resp = await this.graphDBEndpoint.uploadFromData({
data: data,
context: 'http://ont.enapso.com/test',
// format: EnapsoGraphDBClient.FORMAT_TURTLE.type
format: 'application/rdf+xml'
});
enLogger.info(
'\nUploadFromData:\n' + JSON.stringify(resp.success, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoDownloadToFile() {
try {
// download a repository or named graph to file
let lFormat = EnapsoGraphDBClient.FORMAT_TURTLE;
let resp = await this.graphDBEndpoint.downloadToFile({
format: lFormat.type,
context:["http://ont.enapso.com/enapso-sparql-templates"],
filename:
'ontologies'
});
enLogger.info(
'\nDownload (file):\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoDownloadToText() {
try {
// download a repository or named graph to memory
resp = await this.graphDBEndpoint.downloadToText({
format: EnapsoGraphDBClient.FORMAT_TURTLE.type
});
enLogger.info(
'\nDownload (text):\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoQuery() {
try {
// perform a query
let query = `
select *
from <${GRAPHDB_CONTEXT_TEST}>
where {
?s ?p ?o
} `;
let binding = await this.graphDBEndpoint.query(query);
// if a result was successfully returned
if (binding.success) {
// transform the bindings into a more convenient result format (optional)
let resp = EnapsoGraphDBClient.transformBindingsToResultSet(
binding,
{
// drop the prefixes for easier resultset readability (optional)
dropPrefixes: false
}
);
enLogger.info(
'Query succeeded:\n' + JSON.stringify(resp, null, 2)
);
} else {
enLogger.info(
'Query failed:\n' + JSON.stringify(binding, null, 2)
);
}
} catch (err) {
console.log(err);
}
},
async demoInsert() {
try {
// perform an update (insert operation)
let update = `
prefix et: <http://ont.enapso.com/test#>
insert data {
graph <${GRAPHDB_CONTEXT_TEST}> {
et:TestClass rdf:type owl:Class
}
}
`;
let resp = await this.graphDBEndpoint.update(update);
// if a result was successfully returned
if (resp.success) {
enLogger.info(
'Update succeeded:\n' + JSON.stringify(resp, null, 2)
);
} else {
enLogger.info(
'Update failed:\n' + JSON.stringify(resp, null, 2)
);
}
} catch (err) {
console.log(err);
}
},
async demoUpdate() {
try {
// perform an update (update operation)
let update = `
prefix et: <http://ont.enapso.com/test#>
with <${GRAPHDB_CONTEXT_TEST}>
delete {
et:TestClass rdf:type owl:Class
}
insert {
et:TestClassUpdated rdf:type owl:Class
}
where {
et:TestClass rdf:type owl:Class
}
`;
let resp = await this.graphDBEndpoint.update(update);
// if a result was successfully returned
if (resp.success) {
enLogger.info(
'Update succeeded:\n' + JSON.stringify(resp, null, 2)
);
} else {
enLogger.info(
'Update failed:\n' + JSON.stringify(resp, null, 2)
);
}
} catch (err) {
console.log(err);
}
},
async demoDelete() {
try {
// perform an update (delete operation)
let update = `
prefix et: <http://ont.enapso.com/test#>
with <http://ont.enapso.com/test>
delete {
et:TestClassUpdated rdf:type owl:Class
}
where {
et:TestClassUpdated rdf:type owl:Class
}
`;
let resp = await this.graphDBEndpoint.update(update);
// if a result was successfully returned
if (resp.success) {
enLogger.info(
'Update succeeded:\n' + JSON.stringify(resp, null, 2)
);
} else {
enLogger.info(
'Update failed:\n' + JSON.stringify(resp, null, 2)
);
}
} catch (err) {
console.log(err);
}
},
async demoPerformGarbageCollection() {
try {
// lists all contexts (named graph) in the repository
let resp = await this.graphDBEndpoint.performGarbageCollection();
enLogger.info(
'\nGarbage Collection:\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoGetResources() {
try {
// lists all contexts (named graph) in the repository
let resp = await this.graphDBEndpoint.getResources();
enLogger.info('\nResources:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoWaitForGraphDB() {
try {
// lists all contexts (named graph) in the repository
enLogger.info('\nWaiting for GraphDB...');
let resp = await this.graphDBEndpoint.waitForGraphDB({
timeout: 10000, // wait at most 10 seconds
interval: 2000, // check resources all 2 seconds
cpuWatermark: 0.8,
memoryWatermark: 0.7,
performGarbageCollection: true,
callback: function (aEvent) {
enLogger.info(JSON.stringify(aEvent));
}
});
enLogger.info(
'Wait for GraphDB:\n' + JSON.stringify(resp, null, 2)
);
return resp;
} catch (err) {
console.log(err);
}
},
async demoGetQuery() {
try {
// lists all contexts (named graph) in the repository
let resp = await this.graphDBEndpoint.getQuery();
enLogger.info('\nGet Query:\n' + JSON.stringify(resp, null, 2));
return resp;
} catch (err) {
console.log(err);
}
},
async demoShacl() {
try {
let resp;
// read sparqls
let validSparql = await fsPromises.readFile(
'../test/validUpdate.sparql',
'utf-8'
);
let invalidSparql = await fsPromises.readFile(
'../test/invalidUpdate.sparql',
'utf-8'
);
let getPersonsSparql = await fsPromises.readFile(
'../test/selectAllPersons.sparql',
'utf-8'
);
// read the shacl turtle
let shaclTtl = await fsPromises.readFile(
'../ontologies/EnapsoTestShacl.ttl',
'utf-8'
);
// read the shacl json-ld
let shaclJsonLd = await fsPromises.readFile(
'../ontologies/EnapsoTestShacl.jsonld',
'utf-8'
);
// first drop the shacl graph if exists, if it does not exist, this will not be a problem
enLogger.info('\nDropping SHACL Graph...');
resp = await this.graphDBEndpoint.dropShaclGraph();
enLogger.info(
'\nDrop SHACL Graph:\n' + JSON.stringify(resp, null, 2)
);
// now clear the current repository to ensure that there is no old data inside that could disturb the tests
enLogger.info('\nClearing repository...');
resp = await this.graphDBEndpoint.clearRepository();
enLogger.info(
'\nCleared repository:\n' + JSON.stringify(resp, null, 2)
);
// now upload ontology directly from test ontology file into test graph into the test repository
enLogger.info('\nUploading ontology from file...');
resp = await this.graphDBEndpoint.uploadFromFile({
filename: '../ontologies/EnapsoTest.owl',
context: GRAPHDB_CONTEXT_TEST,
format: EnapsoGraphDBClient.FORMAT_RDF_XML.type
});
enLogger.info(
'\nUploaded ontology from file:\n' +
JSON.stringify(resp, null, 2)
);
resp = await this.graphDBEndpoint.query(getPersonsSparql);
enLogger.info(
'\nGet Persons after upload (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
// first try all actions w/o a shacl being applied
resp = await this.graphDBEndpoint.update(validSparql);
enLogger.info(
'\nValid SPARQL w/o SHACL (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
resp = await this.graphDBEndpoint.update(invalidSparql);
enLogger.info(
'Invalid SPARQL w/o SHACL (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
resp = await this.graphDBEndpoint.query(getPersonsSparql);
enLogger.info(
'\nGet Persons w/o SHACL (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
// now clear the repository again, it contains invalid data from the tests w/o shacl support
enLogger.info('\nClearing repository...');
resp = await this.graphDBEndpoint.clearRepository();
enLogger.info(
'\nCleared repository:\n' + JSON.stringify(resp, null, 2)
);
// and upload ontology again to have the same initital status for shacl tests as w/o the shacl tests
enLogger.info('\nUploading ontology from file...');
resp = await this.graphDBEndpoint.uploadFromFile({
filename: '../ontologies/EnapsoTest.owl',
context: GRAPHDB_CONTEXT_TEST,
format: EnapsoGraphDBClient.FORMAT_RDF_XML.type
});
enLogger.info(
'\nUploaded ontology from file:\n' +
JSON.stringify(resp, null, 2)
);
// now load the shacl on top of the correct ontology
enLogger.info('\nUploading SHACL from Data...');
// now upload the shacl file, using correct context (graph name) and format!
resp = await this.graphDBEndpoint.uploadFromData({
// data: shaclTtl,
data: shaclJsonLd,
context: GRAPHDB_CONTEXT_SHACL,
// format: EnapsoGraphDBClient.FORMAT_TURTLE.type
format: EnapsoGraphDBClient.FORMAT_JSON_LD.type
});
enLogger.info(
'\nUploaded SHACL from Data:\n' + JSON.stringify(resp, null, 2)
);
// next try all actions w/o a shacl being applied
resp = await this.graphDBEndpoint.update(validSparql);
enLogger.info(
'\nValid SPARQL with SHACL support (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
resp = await this.graphDBEndpoint.update(invalidSparql);
enLogger.info(
'\nInvalid SPARQL with SHACL support (NOT supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
resp = await this.graphDBEndpoint.query(getPersonsSparql);
enLogger.info(
'\nGet Persons with SHACL support (supposed to work):\n' +
JSON.stringify(resp, null, 2)
);
enLogger.info('\nDone');
} catch (err) {
console.log(err);
}
},
async demo() {
this.graphDBEndpoint = await this.createEndpoint();
// this.authentication = await this.login();
// // verify authentication
// if (!this.authentication.success) {
// enLogger.info(
// '\nLogin failed:\n' +
// JSON.stringify(this.authentication, null, 2)
// );
// return;
// }
// enLogger.info('\nLogin successful');
// await this.demoAssignRoles({
// userName: 'ashesh',
// authorities: [
// {
// action: 'READ',
// resource_type: 'db',
// resource: ['Test']
// },
// {
// action: 'WRITE',
// resource_type: 'db',
// resource: ['Test']
// }
// ]
// });
// await this.demoRemoveRoles({
// userName: 'ashesh',
// authorities: [
// {
// action: 'CREATE',
// resource_type: 'db',
// resource: ['Test']
// },
// {
// action: 'WRITE',
// resource_type: 'db',
// resource: ['Test']
// }
// ]
// });
// clear entire repository
// CAUTION! This operation empties the entire repository and cannot be undone!
// this.demoClearRepository();
// this.demoUploadFromData();
// // clear entire context (named graph)
// // CAUTION! This operation empties the entire context (named graph) and cannot be undone!
// this.demoClearContext();
// this.demoGetRepositories();
// // getLocations requires repository manager role!
// this.demoGetLocations();
// getUsers requires admin role!
// this.demoGetUsers();
// this.demoGetContexts();
// this.demoGetSavedQueries();
// this.demoImportServerFile();
// this.demoUploadFromFile();
this.demoDownloadToFile();
// this.demoDownloadToText();
// this.demoShacl();
// await this.demoDropShaclGraph();
// enLogger.info('--- Inserting new triple --- ');
// await this.demoInsert();
//enLogger.info("--- Graph should contain TestClass now --- ")
// await this.demoQuery();
/*
await this.demoDownloadToFile();
enLogger.info("--- Updating existing triple --- ")
await this.demoUpdate();
enLogger.info("--- Graph should contain TestClassUpdated now --- ")
await this.demoQuery();
enLogger.info("--- Deleting existing triple --- ")
await this.demoDelete();
enLogger.info("--- Graph should not contain TestClassUpdated anymore --- ")
await this.demoQuery();
*/
// await this.demoGetResources();
// await this.demoPerformGarbageCollection();
// await this.demoGetResources();
// await this.demoCreateRepository();
// await this.demoDeleteRepository();
// await this.demoCreateUser();
// await this.demoUpdateUser();
// await this.demoDeleteUser();
// await this.demoClearRepository();
// enLogger.info('Start: ' + new Date().toISOString());
// await this.demoWaitForGraphDB();
// enLogger.info('Finish: ' + new Date().toISOString());
// await this.demoGetQuery();
}
};
EnapsoGraphDBAdminDemo.demo();