diff --git a/models/task.js b/models/task.js
index edf8018..b142ff1 100644
--- a/models/task.js
+++ b/models/task.js
@@ -7,6 +7,7 @@ import {
update,
uuid,
} from 'mu';
+import { prefixMap } from '../support/prefixes';
export const TASK_TYPE_SIGNING_DECISION_LIST = 'decisionListSignature';
export const TASK_TYPE_PUBLISHING_DECISION_LIST = 'decisionListPublication';
@@ -20,6 +21,20 @@ export const TASK_STATUS_SUCCESS =
'http://lblod.data.gift/besluit-publicatie-melding-statuses/success';
export const TASK_STATUS_RUNNING =
'http://lblod.data.gift/besluit-publicatie-melding-statuses/ongoing';
+export class TaskError {
+ constructor({ id, uri, message }) {
+ if (uri) {
+ // we don't want to generate a new id if we got a uri, even if it's null
+ this.id = id;
+ this.uri = uri;
+ } else {
+ this.id = id ?? uuid();
+ this.uri = `http://redpencil.data.gift/id/jobs/error/${this.id}`;
+ }
+
+ this.message = message;
+ }
+}
export default class Task {
static async create(meeting, type) {
@@ -58,12 +73,13 @@ export default class Task {
static async find(uuid) {
const result = await query(`
- PREFIX mu:
- PREFIX nuao:
- PREFIX task:
- PREFIX dct:
- PREFIX adms:
- SELECT ?uri ?uuid ?type ?involves ?status ?modified ?created WHERE {
+ ${prefixMap.get('mu').toSparqlString()}
+ ${prefixMap.get('nuao').toSparqlString()}
+ ${prefixMap.get('task').toSparqlString()}
+ ${prefixMap.get('dct').toSparqlString()}
+ ${prefixMap.get('adms').toSparqlString()}
+ ${prefixMap.get('oslc').toSparqlString()}
+ SELECT ?uri ?uuid ?type ?involves ?status ?modified ?created ?error ?errorId ?errorMessage WHERE {
BIND(${sparqlEscapeString(uuid)} AS ?uuid)
?uri a task:Task;
mu:uuid ?uuid;
@@ -73,6 +89,11 @@ export default class Task {
nuao:involves ?involves;
dct:creator ;
adms:status ?status.
+ OPTIONAL {
+ ?uri task:error ?error.
+ ?error mu:uuid ?errorId.
+ ?error oslc:message ?errorMessage.
+ }
}
`);
if (result.results.bindings.length) {
@@ -82,12 +103,13 @@ export default class Task {
static async query({ meetingUri, type, userUri = null }) {
const result = await query(`
- PREFIX mu:
- PREFIX nuao:
- PREFIX task:
- PREFIX dct:
- PREFIX adms:
- SELECT ?uri ?uuid ?type ?involves ?status ?modified ?created WHERE {
+ ${prefixMap.get('mu').toSparqlString()}
+ ${prefixMap.get('nuao').toSparqlString()}
+ ${prefixMap.get('task').toSparqlString()}
+ ${prefixMap.get('dct').toSparqlString()}
+ ${prefixMap.get('adms').toSparqlString()}
+ ${prefixMap.get('oslc').toSparqlString()}
+ SELECT ?uri ?uuid ?type ?involves ?status ?modified ?created ?error ?errorId ?errorMessage WHERE {
?uri a task:Task;
mu:uuid ?uuid;
dct:type ${sparqlEscapeString(type)};
@@ -96,6 +118,12 @@ export default class Task {
nuao:involves ${sparqlEscapeUri(meetingUri)};
dct:creator ;
adms:status ?status.
+
+ OPTIONAL {
+ ?uri task:error ?error.
+ ?error mu:uuid ?errorId.
+ ?error oslc:message ?errorMessage.
+ }
${userUri ? `?uri nuao:involves ${sparqlEscapeUri(userUri)}.` : ''}
}
`);
@@ -109,6 +137,15 @@ export default class Task {
}
static fromBinding(binding) {
+ let taskError = null;
+ if (binding.error?.value) {
+ taskError = new TaskError({
+ uri: binding.error.value,
+ id: binding.errorId?.value,
+ message: binding.errorMessage?.value,
+ });
+ }
+
return new Task({
id: binding.uuid.value,
uri: binding.uri.value,
@@ -117,10 +154,11 @@ export default class Task {
status: binding.status.value,
involves: binding.involves.value,
type: binding.type.value,
+ error: taskError,
});
}
- constructor({ id, uri, created, status, modified, type, involves }) {
+ constructor({ id, uri, created, status, modified, type, involves, error }) {
this.id = id;
this.type = type;
this.involves = involves;
@@ -128,29 +166,49 @@ export default class Task {
this.modified = modified;
this.status = status;
this.uri = uri;
+ this.error = error;
}
async updateStatus(status, reason) {
+ let taskError = null;
+ if (reason) {
+ taskError = new TaskError({ message: reason });
+ }
+ //prettier-ignore
const queryString = `
- PREFIX mu:
- PREFIX nuao:
- PREFIX task:
- PREFIX dct:
- PREFIX adms:
- PREFIX rdfs:
+ ${prefixMap.get("mu").toSparqlString()}
+ ${prefixMap.get("task").toSparqlString()}
+ ${prefixMap.get("adms").toSparqlString()}
+ ${prefixMap.get("oslc").toSparqlString()}
DELETE {
?uri adms:status ?status.
+ ?uri task:error ?error.
+ ?error ?errorP ?errorV.
}
INSERT {
?uri adms:status ${sparqlEscapeUri(status)}.
- ${reason ? `?uri rdfs:comment ${sparqlEscapeString(reason)}.` : ''}
+ ${
+ taskError
+ ? `?uri task:error ${sparqlEscapeUri(taskError.uri)}.
+ ${sparqlEscapeUri(taskError.uri)} a oslc:Error.
+ ${sparqlEscapeUri(taskError.uri)} mu:uuid ${sparqlEscapeString(taskError.id)}.
+ ${sparqlEscapeUri(taskError.uri)} oslc:message ${sparqlEscapeString(taskError.message)}.`
+ : ''
+ }
}
WHERE {
- ?uri a task:Task;
- mu:uuid ${sparqlEscapeString(this.id)};
- adms:status ?status.
+ ?uri a task:Task;
+ mu:uuid ${sparqlEscapeString(this.id)};
+ adms:status ?status.
+ OPTIONAL {
+ ?uri task:error ?error.
+ ?error ?errorP ?errorV.
+ }
}`;
await update(queryString);
+ this.status = status;
+
+ this.error = taskError;
}
}
diff --git a/models/versioned-notulen.js b/models/versioned-notulen.js
index 155a732..b447f09 100644
--- a/models/versioned-notulen.js
+++ b/models/versioned-notulen.js
@@ -30,7 +30,8 @@ export default class VersionedNotulen {
const bindings = r.results.bindings;
if (bindings.length > 0) {
const binding = bindings[0];
- const fileUri = bindings.fileUri?.value;
+
+ const fileUri = binding.fileUri?.value;
let html;
if (fileUri) {
html = await getFileContentForUri(fileUri);
diff --git a/routes/task.js b/routes/task.js
index 9cfdc66..d1cd392 100644
--- a/routes/task.js
+++ b/routes/task.js
@@ -10,9 +10,20 @@ router.get('/publication-tasks/:id', async function (req, res) {
res.status(200).send({
data: {
id: task.id,
+ uri: task.uri,
status: task.status,
type: task.type,
+ created: task.created,
+ modified: task.modified,
+ involves: task.involves,
taskType: task.type,
+ error: task.error
+ ? {
+ id: task.error.id,
+ message: task.error.message,
+ uri: task.error.uri,
+ }
+ : undefined,
},
});
} else {
diff --git a/support/pre-importer.js b/support/pre-importer.js
index 0672663..ae484a2 100644
--- a/support/pre-importer.js
+++ b/support/pre-importer.js
@@ -54,16 +54,24 @@ async function getVersionedContent(uri, contentPredicate) {
)} prov:generated/^nie:dataSource ?physicalFileUri. }
}`;
const result = await query(contentQuery);
- if (result.results.bindings.length == 1) {
- const binding = result.results.bindings[0];
- if (binding.content) {
- return binding.content.value;
- } else if (binding.physicalFileUri) {
+ const bindings = result.results.bindings;
+ if (bindings.length === 1) {
+ const binding = bindings[0];
+ if (binding.physicalFileUri) {
const content = await getFileContentForUri(binding.physicalFileUri.value);
return content;
+ } else if (binding.content) {
+ return binding.content.value;
}
+ } else if (bindings.length > 1) {
+ throw new Error(
+ `Found ${bindings.length} sources of content for versioned resource ${uri}. Only one is allowed. This means there is invalid data in the database.`
+ );
+ } else {
+ throw new Error(
+ `Found no sources of content for versioned resource ${uri}`
+ );
}
- throw new Error('could not retrieve content');
}
async function handleVersionedResource(
diff --git a/support/prefixes.js b/support/prefixes.js
index ec6617c..7a0fe02 100644
--- a/support/prefixes.js
+++ b/support/prefixes.js
@@ -68,8 +68,11 @@ const prefixMap = new Map([
["notulen", new Prefix("notulen", "http://lblod.data.gift/vocabularies/notulen/")],
["nfo", new Prefix("nfo", "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#")],
["nie", new Prefix("nie", "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#")],
+ ["gn", new Prefix("gn", "http://data.lblod.info/vocabularies/gelinktnotuleren/")],
["dbpedia", new Prefix("dbpedia", "http://dbpedia.org/ontology/")],
- ["gn", new Prefix("gn", "http://data.lblod.info/vocabularies/gelinktnotuleren/")]
+ ["oslc", new Prefix("oslc", "http://open-services.net/ns/core#")],
+ ["task", new Prefix("task", "http://redpencil.data.gift/vocabularies/tasks/")],
+ ["nuao", new Prefix("nuao", "http://www.semanticdesktop.org/ontologies/2010/01/25/nuao#")],
]);
export { prefixes, prefixMap };