blob: 5f20e1d17e1e0661670db17174657506bf69b066 [file] [log] [blame]
/**
* 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.
*/
const PORT = process.env.FUSEKI_PORT || 3030
const data = {}
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router(data)
const middlewares = jsonServer.defaults()
server.use(middlewares)
// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser)
const DATASETS = {}
// const builtTime = new Date()
const startTime = new Date()
// Add custom routes before JSON Server router
server.get('/index.html', (req, res) => res.jsonp(''))
// GET SERVER INFO
server.get('/\\$/server', (req, res) => {
res.jsonp({
version: '5.x.y',
startDateTime: startTime.toISOString(),
uptime: parseInt(`${(new Date() - startTime) / 1000}`),
datasets: Object.values(DATASETS)
})
})
// GET TASKS
server.get('/\\$/tasks', (req, res) => {
res.jsonp([])
})
// CREATE DATASET
server.post('/\\$/datasets', (req, res) => {
const datasetName = req.body.dbName
if (DATASETS[datasetName]) {
res.status(409).send('Error 409: Name already registered /a')
return
}
DATASETS[datasetName] = {
'ds.name': `/${datasetName}`,
'ds.state': true,
'ds.services': [
{
'srv.type': 'gsp-rw',
'srv.description': 'Graph Store Protocol',
'srv.endpoints': ['data']
},
{
'srv.type': 'query',
'srv.description': 'SPARQL Query',
'srv.endpoints': [
'sparql',
'',
'query'
]
},
{
'srv.type': 'gsp-r',
'srv.description': 'Graph Store Protocol (Read)',
'srv.endpoints': ['get']
},
{
'srv.type': 'update',
'srv.description': 'SPARQL Update',
'srv.endpoints': [
'update',
''
]
},
{
'srv.type': 'upload',
'srv.description': 'File Upload',
'srv.endpoints': ['upload']
}
]
}
res.sendStatus(200)
})
// GET DATASET DATA
server.get('/\\$/stats/:datasetName', (req, res) => {
const datasetName = req.params.datasetName
res
.status(200)
.jsonp({
datasets: {
[`/${datasetName}`]: {
Requests: 2,
RequestsGood: 1,
RequestsBad: 1,
endpoints: {
data: {
RequestsBad: 1,
Requests: 1,
RequestsGood: 0,
operation: 'gsp-rw',
description: 'Graph Store Protocol'
},
sparql: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'query',
description: 'SPARQL Query'
},
query: {
RequestsBad: 0,
Requests: 1,
RequestsGood: 1,
operation: 'query',
description: 'SPARQL Query'
},
_1: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'query',
description: 'SPARQL Query'
},
get: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'gsp-r',
description: 'Graph Store Protocol (Read)'
},
_2: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'update',
description: 'SPARQL Update'
},
update: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'update',
description: 'SPARQL Update'
},
upload: {
RequestsBad: 0,
Requests: 0,
RequestsGood: 0,
operation: 'upload',
description: 'File Upload'
}
}
}
}
})
})
// SPARQL QUERY
const sparqlCallback = (req, res) => {
const count = 42
const bindings = []
const vars = []
const query = req.query.query
// If a query was provided in the URL as ?query=..., then it's either
// counting the triples (Info), or listing existing graphs (Edit).
if (query) {
if (query.startsWith('select ?g')) {
vars.push('count', 'g')
} else {
vars.push('count')
bindings.push({
count: {
type: 'literal',
datatype: 'http://www.w3.org/2001/XMLSchema#integer',
value: count
}
})
}
} else {
vars.push('subject', 'predicate', 'object')
bindings.push({
subject: {
type: 'uri',
value: 'https://jena.apache.org/#/tests/id/1'
},
predicate: {
type: 'uri',
value: 'https://jena.apache.org/#/Topic'
},
object: {
type: 'literal',
'xml:lang': 'en',
value: 'Semantic Web'
}
},
{
subject: {
type: 'uri',
value: 'https://jena.apache.org/#/tests/id/2'
},
predicate: {
type: 'uri',
value: 'https://jena.apache.org/#/Topic'
},
object: {
type: 'literal',
'xml:lang': 'en',
value: 'Knowledge Graph'
}
})
}
res
.status(200)
.jsonp({
head: {
vars
},
results: {
bindings
}
})
}
server.get('/:datasetName/sparql', sparqlCallback)
server.post('/:datasetName/sparql', sparqlCallback)
// GRAPH
const dataContent = `@prefix : <https://example.org/book/> .
@prefix dc: <https://purl.org/dc/elements/1.1/> .
@prefix ns: <https://example.org/ns#> .
@prefix vcard: <https://www.w3.org/2001/vcard-rdf/3.0#> .
:book4 dc:title "Harry Potter and the Goblet of Fire" .`
// This gets called when you count the graphs
server.get('/:datasetName/data', (req, res) => {
res
.status(200)
.set('Content-Type', 'text/turtle')
.send(dataContent)
})
let failUpload = false
// Upload data.
server.post('/:datasetName/data', (req, res) => {
res
.status(200)
.send()
})
// PING
// GET PING STATUS
server.get('/\\$/ping', (req, res) => {
res
.status(200)
.jsonp({
body: new Date().toISOString()
})
})
// RESET TEST DATA
server.get('/tests/reset', (req, res) => {
// Just delete the datasets to clean up for other tests to have a
// brand new environment.
for (const dataset in DATASETS) {
delete DATASETS[dataset]
}
res.sendStatus(200)
})
server.use(router)
server.listen(PORT, () => {
console.log('JSON Server is running')
})