1
0

knowledgeBase - Working.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. //© 2019 Dublin City University, Trinity College Dublin. All rights reserved. This material may not be reproduced, displayed, modified or distributed without the express prior written permission of the copyright holder.
  2. var path = require('path');
  3. var fs = require('fs');
  4. var cache = require('memory-cache');
  5. const knowledgeBaseFile = __dirname + '/output';
  6. const statusFile = __dirname + '/status/statusStore.json';
  7. const axios = require('axios');
  8. const queryString = require('query-string');
  9. const knowledgeBaseModel = require(__dirname + '/model/knowledgeBaseModel.js');
  10. var Promise = require('promise');
  11. const headers = { 'Accept': 'application/sparql-results+json', 'Content-Type': 'application/x-www-form-urlencoded' };
  12. const UndefinedClassesAndPropertiesMetricQuery = require(__dirname + '/sparql/UndefinedClassesAndPropertiesMetric');
  13. const HumanReadableLabellingMetricQuery = require(__dirname + '/sparql/HumanReadableLabellingMetric');
  14. const CompatibleDatatypeQuery = require(__dirname + '/sparql/CompatibleDatatype');
  15. const EntitiesAsMembersOfDisjointClassesMetricQuery = require(__dirname + '/sparql/EntitiesAsMembersOfDisjointClassesMetric');
  16. const MisplacedClassesOrPropertiesMetricQuery = require(__dirname + '/sparql/MisplacedClassesOrPropertiesMetric');
  17. const MisusedOwlDatatypeOrObjectPropertiesMetricQuery = require(__dirname + '/sparql/MisusedOwlDatatypeOrObjectPropertiesMetric');
  18. const UsageOfIncorrectDomainOrRangeDatatypesMetricQuery = require(__dirname + '/sparql/UsageOfIncorrectDomainOrRangeDatatypesMetric');
  19. const ExtensionalConcisenessMetricQuery_FetchProblem = require(__dirname + '/sparql/ExtensionalConcisenessMetric_FetchProblem');
  20. const ExtensionalConcisenessMetricQuery_FetchAllTriples = require(__dirname + '/sparql/ExtensionalConcisenessMetric_FetchAllTriples');
  21. const ExtensionalConcisenessMetricQuery_FindRelated = require(__dirname + '/sparql/ExtensionalConcisenessMetric_FindRelated');
  22. class knowledgeBases {
  23. getKnowledgeBase(req, res) {
  24. const knowledgeBaseID = parseInt(req.query.knowledgeBaseID, 10);
  25. let knowledgeBase=cache.get(knowledgeBaseID);
  26. if(knowledgeBase===null)
  27. {
  28. return res.status(404).send({
  29. status: 'false',
  30. message: 'Knowledge Base not Created',
  31. });
  32. }
  33. else
  34. {
  35. if(knowledgeBase.lenght===0)
  36. {
  37. return res.status(404).send({
  38. status: 'false',
  39. message: 'Knowledge Base not Created',
  40. });
  41. }
  42. else
  43. {
  44. return res.status(200).send(
  45. {knowledgeBase}
  46. );
  47. }
  48. }
  49. }
  50. getKnowledgeBaseStatus(req, res) {
  51. const knowledgeBaseID = parseInt(req.query.knowledgeBaseID, 10);
  52. let knowledgeBase=cache.get(knowledgeBaseID);
  53. if(knowledgeBase===null)
  54. {
  55. console.log(knowledgeBaseID + ": Is Null");
  56. return res.status(404).send({
  57. status: 'false',
  58. message: 'Knowledge Base Not Found'
  59. });
  60. }
  61. else
  62. {
  63. console.log(knowledgeBaseID + ":"+ knowledgeBase.length);
  64. if(knowledgeBase.length===0)
  65. {
  66. return res.status(200).send({
  67. knowledgeBaseID: knowledgeBaseID,
  68. status: 'INPROGRESS'
  69. });
  70. }
  71. else
  72. {
  73. return res.status(200).send({
  74. knowledgeBaseID: knowledgeBaseID,
  75. status : 'COMPLETED'
  76. });
  77. }
  78. }
  79. }
  80. generateKnowledgeBase(req, res) {
  81. const metrics = req.body.metrics;
  82. //const metrics = JSON.parse(req.body.metrics);
  83. const qualityGraph = req.body.qualityGraph;
  84. const dataGraph = req.body.dataGraph;
  85. const tripleStoreEndPoint = req.body.tripleStoreEndPoint;
  86. const isSparqlEndPoint = req.body.isSparqlEndPoint;
  87. const lastAssessmentDate = req.body.lastAssessmentDate;
  88. const knowledgeBaseMapping = req.body.knowledgeBaseMapping;
  89. let queryResults = [];
  90. let datasetSource = 'GRAPH';
  91. if(isSparqlEndPoint==='true')
  92. {
  93. console.log("IS SPARQL ENDPOINT");
  94. datasetSource='SERVICE';
  95. }
  96. let knowledgeBaseID = Math.floor(Date.now());
  97. cache.put(knowledgeBaseID,queryResults);
  98. const knowledgeBaseNew = {
  99. knowledgeBaseID: knowledgeBaseID
  100. };
  101. function setImmediatePromise() {
  102. return new Promise((resolve) => {
  103. setImmediate(() => resolve());
  104. });
  105. }
  106. console.log("Metrics : "+metrics.length);
  107. var buildResultArray = function (query) {
  108. return new Promise(function (resolve, reject) {
  109. axios.post(tripleStoreEndPoint, queryString.stringify({ query: query }), headers)
  110. .then(response => {
  111. if (response) {
  112. if (response.status === 200) {
  113. console.log("buildResultArray : "+response.data.results.bindings.length);
  114. response.data.results.bindings.forEach(function (binding) {
  115. let ProblematicThing = "";
  116. let Subject = "";
  117. let Predicate = "";
  118. let Object = "";
  119. let FailedMertic = "";
  120. let Exception = "";
  121. if (binding.Subject !== undefined) {
  122. Subject = "<"+binding.Subject.value+">";
  123. }
  124. if (binding.Predicate !== undefined) {
  125. Predicate = "<"+binding.Predicate.value+">";
  126. }
  127. if (binding.Object !== undefined) {
  128. if(binding.Object.type==="uri")
  129. {
  130. Object +="<"+binding.Object.value+">";
  131. }
  132. else
  133. {
  134. if(binding.Object["xml:lang"]!==undefined)
  135. {
  136. Object +="\"\"\""+binding.Object.value+"\"\"\"@" +binding.Object["xml:lang"];
  137. }
  138. else if(binding.Object["datatype"]!==undefined)
  139. {
  140. let value = binding.Object.value.replace(/(\"|\')/g, '\\$1');
  141. Object +="\"\"\""+value+"\"\"\""+"^^<" +binding.Object["datatype"]+">" ;
  142. }
  143. else{
  144. Object +="\"\"\""+binding.Object.value+"\"\"\"";
  145. }
  146. }
  147. }
  148. if (binding.FailedMertic !== undefined) {
  149. //FailedMertic = binding.FailedMertic.value;
  150. FailedMertic = binding.FailedMertic.value.split("#")[1];
  151. }
  152. if (binding.Exception !== undefined) {
  153. //Exception = binding.Exception.value;
  154. Exception = binding.Exception.value.split("#")[1];
  155. }
  156. ProblematicThing = knowledgeBaseMapping[FailedMertic][Exception];
  157. let temp = {
  158. "ProblematicThing": ProblematicThing,
  159. "Subject": Subject,
  160. "Predicate": Predicate,
  161. "Object": Object,
  162. "FailedMertic": FailedMertic,
  163. "Exception": Exception
  164. }
  165. queryResults.push(temp);
  166. });
  167. }
  168. }
  169. resolve();
  170. })
  171. .catch(error => {
  172. reject(error);
  173. });
  174. });
  175. }
  176. var buildextensionalConcisenessMetricProblems = function (query) {
  177. return new Promise(function (resolve, reject) {
  178. let queryResultsTemp=[];
  179. axios.post(tripleStoreEndPoint, queryString.stringify({ query: query }), headers)
  180. .then(response => {
  181. if (response) {
  182. if (response.status === 200) {
  183. console.log("buildextensionalConcisenessMetricProblems : "+response.data.results.bindings.length);
  184. response.data.results.bindings.forEach(function (binding) {
  185. let ProblematicThing = "";
  186. let Subject = "";
  187. let Predicate = "";
  188. let Object = "";
  189. let FailedMertic = "";
  190. let Exception = "";
  191. if (binding.Subject !== undefined) {
  192. Subject = "<"+binding.Subject.value+">";
  193. }
  194. if (binding.Predicate !== undefined) {
  195. Predicate = "<"+binding.Predicate.value+">";
  196. }
  197. if (binding.FailedMertic !== undefined) {
  198. //FailedMertic = binding.FailedMertic.value;
  199. //FailedMertic = binding.FailedMertic.value.split("#")[1];
  200. FailedMertic = "ExtensionalConcisenessMetric";
  201. }
  202. if (binding.Exception !== undefined) {
  203. //Exception = binding.Exception.value;
  204. Exception = binding.Exception.value.split("#")[1];
  205. }
  206. //ProblematicThing = knowledgeBaseMapping[FailedMertic][Exception];
  207. ProblematicThing = knowledgeBaseMapping["ExtensionalConcisenessMetric"]["ResourceReplica"];
  208. let temp = {
  209. "ProblematicThing": ProblematicThing,
  210. "Subject": Subject,
  211. "Predicate": Predicate,
  212. "Object": Object,
  213. "FailedMertic": FailedMertic,
  214. "Exception": Exception
  215. }
  216. queryResultsTemp.push(temp);
  217. });
  218. }
  219. }
  220. resolve(queryResultsTemp);
  221. })
  222. .catch(error => {
  223. //reject(queryResultsTemp);
  224. resolve(queryResultsTemp);
  225. });
  226. });
  227. }
  228. var buildextensionalConcisenessAllTripleQuery = function (query) {
  229. return new Promise(function (resolve, reject) {
  230. let triples="";
  231. axios.post(tripleStoreEndPoint, queryString.stringify({ query: query }), headers)
  232. .then(response => {
  233. if (response) {
  234. if (response.status === 200) {
  235. console.log("buildextensionalConcisenessAllTripleQuery : "+response.data.results.bindings.length);
  236. let length=response.data.results.bindings.length;
  237. response.data.results.bindings.forEach(function (binding,index)
  238. {
  239. if(index===0)
  240. {
  241. triples="?Resource ";
  242. }
  243. triples +="<"+binding.Predicate.value+"> ";
  244. if(binding.Object.type==="uri")
  245. {
  246. triples +="<"+binding.Object.value+"> ";
  247. }
  248. else
  249. {
  250. if(binding.Object["xml:lang"]!==undefined)
  251. {
  252. triples +="\"\"\""+binding.Object.value+"\"\"\"@" +binding.Object["xml:lang"]+" " ;
  253. }
  254. else if(binding.Object["datatype"]!==undefined)
  255. {
  256. let value = binding.Object.value.replace(/(\"|\')/g, '\\$1');
  257. //triples += "\"s\" ";
  258. triples +="\"\"\""+value+"\"\"\""+"^^<" +binding.Object["datatype"]+"> " ;
  259. }
  260. else{
  261. triples +="\"\"\""+binding.Object.value+"\"\"\" ";
  262. }
  263. }
  264. if(!(index===length-1))
  265. {
  266. triples += "; ";
  267. }
  268. });
  269. }
  270. }
  271. resolve(triples);
  272. })
  273. .catch(error => {
  274. //reject(triples);
  275. resolve(triples);
  276. });
  277. });
  278. }
  279. var buildextensionalConcisenessResultArray = function (query) {
  280. return new Promise(function (resolve, reject) {
  281. let related=[];
  282. axios.post(tripleStoreEndPoint, queryString.stringify({ query: query }), headers)
  283. .then(response => {
  284. if (response) {
  285. if (response.status === 200) {
  286. console.log("buildextensionalConcisenessResultArray : "+response.data.results.bindings.length);
  287. let length=response.data.results.bindings.length;
  288. response.data.results.bindings.forEach(function (binding,index)
  289. {
  290. related.push(binding.Resource.value);
  291. });
  292. }
  293. }
  294. resolve(related);
  295. })
  296. .catch(error => {
  297. //reject(related);
  298. resolve(related);
  299. });
  300. });
  301. }
  302. var triggerActivity = async function () {
  303. for (const metric of metrics) {
  304. let query = "";
  305. switch (metric.metric) {
  306. case 'UndefinedClassesAndPropertiesMetric':
  307. console.log("UndefinedClassesAndPropertiesMetric:"+datasetSource);
  308. query = UndefinedClassesAndPropertiesMetricQuery.UndefinedClassesAndPropertiesMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  309. await buildResultArray(query);
  310. break;
  311. case 'HumanReadableLabellingMetric':
  312. console.log("HumanReadableLabellingMetric:"+datasetSource);
  313. query = HumanReadableLabellingMetricQuery.HumanReadableLabellingMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  314. await buildResultArray(query);
  315. break;
  316. case 'CompatibleDatatype':
  317. console.log("CompatibleDatatype:"+datasetSource);
  318. query = CompatibleDatatypeQuery.CompatibleDatatype(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  319. await buildResultArray(query);
  320. break;
  321. case 'EntitiesAsMembersOfDisjointClassesMetric':
  322. console.log("EntitiesAsMembersOfDisjointClassesMetric:"+datasetSource);
  323. query = EntitiesAsMembersOfDisjointClassesMetricQuery.EntitiesAsMembersOfDisjointClassesMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  324. await buildResultArray(query);
  325. break;
  326. case 'MisplacedClassesOrPropertiesMetric':
  327. console.log("MisplacedClassesOrPropertiesMetric:"+datasetSource);
  328. query = MisplacedClassesOrPropertiesMetricQuery.MisplacedClassesOrPropertiesMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  329. await buildResultArray(query);
  330. break;
  331. case 'MisusedOwlDatatypeOrObjectPropertiesMetric':
  332. console.log("MisusedOwlDatatypeOrObjectPropertiesMetric:"+datasetSource);
  333. query = MisusedOwlDatatypeOrObjectPropertiesMetricQuery.MisusedOwlDatatypeOrObjectPropertiesMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  334. await buildResultArray(query);
  335. break;
  336. case 'UsageOfIncorrectDomainOrRangeDatatypesMetric':
  337. console.log("UsageOfIncorrectDomainOrRangeDatatypesMetric:"+datasetSource);
  338. query = UsageOfIncorrectDomainOrRangeDatatypesMetricQuery.UsageOfIncorrectDomainOrRangeDatatypesMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  339. await buildResultArray(query);
  340. break;
  341. case 'ExtensionalConcisenessMetric':
  342. console.log("ExtensionalConcisenessMetric:"+datasetSource);
  343. query = ExtensionalConcisenessMetricQuery_FetchProblem.ExtensionalConcisenessMetric(qualityGraph, dataGraph, metric.observationURI,datasetSource);
  344. let queryResultsTemp = await buildextensionalConcisenessMetricProblems(query);
  345. //console.log(queryResultsTemp);
  346. let alreadyFoundList = [];
  347. let alreadFoundBoolean = false;
  348. for(const problem of queryResultsTemp)
  349. {
  350. alreadFoundBoolean=false;
  351. //console.log("PROBLEM : "+problem.Subject);
  352. let subject = problem.Subject;
  353. for(const inList of alreadyFoundList)
  354. {
  355. if(inList===subject)
  356. {
  357. alreadFoundBoolean=true;
  358. }
  359. }
  360. if(!alreadFoundBoolean)
  361. {
  362. query = ExtensionalConcisenessMetricQuery_FetchAllTriples.ExtensionalConcisenessMetric(qualityGraph, dataGraph, subject,datasetSource);
  363. let triples = await buildextensionalConcisenessAllTripleQuery(query);
  364. //console.log(triples);
  365. let relatedResourcesQuery=ExtensionalConcisenessMetricQuery_FindRelated.ExtensionalConcisenessMetric(triples, dataGraph, subject,datasetSource);
  366. let relatedResources=await buildextensionalConcisenessResultArray(relatedResourcesQuery);
  367. //console.log(relatedResources);
  368. for(const related of relatedResources)
  369. {
  370. let tempProblem = null;
  371. tempProblem=JSON.parse(JSON.stringify(problem));
  372. tempProblem["Object"]="<"+related+">"
  373. queryResults.push(tempProblem);
  374. alreadyFoundList.push("<"+related+">");
  375. }
  376. }
  377. }
  378. break;
  379. default:
  380. console.log("default:"+datasetSource);
  381. query = "";
  382. break;
  383. }
  384. }
  385. }
  386. triggerActivity().then(async function () {
  387. //Loop through each array object
  388. for (const [outerIndex, outerResult] of queryResults.entries()) {
  389. let resourceRelatedExceptions = [];
  390. let problematicThingRelatedExceptions = [];
  391. let tempArray = [];
  392. /*
  393. let SubjectRelatedExceptions = [];
  394. let PredicateRelatedExceptions = [];
  395. let ObjectRelatedExceptions = [];
  396. let SameTripleSameProblematicThingRelatedExceptions = [];
  397. let SameTripleDifferentProblematicThingRelatedExceptions = [];
  398. */
  399. //console.log(outerIndex);
  400. //Add Await call to setImmediate to prevent thread blocking
  401. await setImmediatePromise()
  402. //Find SubjectRelatedExceptions
  403. /*
  404. tempArray = [];
  405. for (const [innerIndex, innerResult] of queryResults.entries()) {
  406. //Ignore same entry
  407. if (innerIndex !== outerIndex) {
  408. if (innerResult.ProblematicThing === "Subject" & outerResult.Subject === innerResult.Subject) {
  409. tempArray.push(innerResult.Exception);
  410. }
  411. }
  412. }
  413. SubjectRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  414. queryResults[outerIndex].SubjectRelatedExceptions = [...SubjectRelatedExceptions];
  415. //Find PredicateRelatedExceptions
  416. tempArray = [];
  417. for (const [innerIndex, innerResult] of queryResults.entries()) {
  418. //Ignore same entry
  419. if (innerIndex !== outerIndex) {
  420. if (innerResult.ProblematicThing === "Predicate" & outerResult.Predicate === innerResult.Predicate) {
  421. tempArray.push(innerResult.Exception);
  422. }
  423. }
  424. }
  425. PredicateRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  426. queryResults[outerIndex].PredicateRelatedExceptions = [...PredicateRelatedExceptions];
  427. //Find ObjectRelatedExceptions
  428. tempArray = [];
  429. for (const [innerIndex, innerResult] of queryResults.entries()) {
  430. //Ignore same entry
  431. if (innerIndex !== outerIndex) {
  432. if (innerResult.ProblematicThing === "Object" & outerResult.Object === innerResult.Object) {
  433. tempArray.push(innerResult.Exception);
  434. }
  435. }
  436. }
  437. ObjectRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  438. queryResults[outerIndex].ObjectRelatedExceptions = [...ObjectRelatedExceptions];
  439. //Find SameTripleSameProblematicThingRelatedExceptions
  440. tempArray = [];
  441. for (const [innerIndex, innerResult] of queryResults.entries()) {
  442. //Ignore same entry
  443. if (innerIndex !== outerIndex) {
  444. if (innerResult.ProblematicThing === outerResult.ProblematicThing & outerResult.Subject === innerResult.Subject & outerResult.Precicate === innerResult.Precicate & outerResult.Object === innerResult.Object) {
  445. tempArray.push(innerResult.Exception);
  446. }
  447. }
  448. }
  449. SameTripleSameProblematicThingRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  450. queryResults[outerIndex].SameTripleSameProblematicThingRelatedExceptions = [...SameTripleSameProblematicThingRelatedExceptions];
  451. //Find SameTripleDifferentProblematicThingRelatedExceptions
  452. tempArray = [];
  453. for (const [innerIndex, innerResult] of queryResults.entries()) {
  454. //Ignore same entry
  455. if (innerIndex !== outerIndex) {
  456. if (innerResult.ProblematicThing !== outerResult.ProblematicThing & outerResult.Subject === innerResult.Subject & outerResult.Precicate === innerResult.Precicate & outerResult.Object === innerResult.Object) {
  457. tempArray.push(innerResult.Exception);
  458. }
  459. }
  460. }
  461. SameTripleDifferentProblematicThingRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  462. queryResults[outerIndex].SameTripleDifferentProblematicThingRelatedExceptions = [...SameTripleDifferentProblematicThingRelatedExceptions];
  463. //queryResults[outerIndex].knowledgeBaseID = knowledgeBaseID;
  464. */
  465. //Find Resource related Exceptions
  466. tempArray = [];
  467. for (const [innerIndex, innerResult] of queryResults.entries()) {
  468. if (outerResult.Subject === innerResult.Subject & outerResult.Exception !== innerResult.Exception) {
  469. tempArray.push(innerResult.Exception);
  470. }
  471. }
  472. resourceRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  473. queryResults[outerIndex].resourceRelatedExceptions = [...resourceRelatedExceptions];
  474. //Find Problematic Thing Related Exceptions
  475. tempArray = [];
  476. for(const outerResultProblematicThing of outerResult.ProblematicThing)
  477. {
  478. for (const [innerIndex, innerResult] of queryResults.entries()) {
  479. if (outerResult[outerResultProblematicThing] === innerResult[outerResultProblematicThing] & outerResult.Exception !== innerResult.Exception) {
  480. tempArray.push(innerResult.Exception);
  481. }
  482. }
  483. }
  484. problematicThingRelatedExceptions = [...new Set(tempArray.map((exception) => (exception)))];
  485. queryResults[outerIndex].problematicThingRelatedExceptions = [...problematicThingRelatedExceptions];
  486. }
  487. //Update Status as Completed
  488. //console.log(queryResults)
  489. cache.del(knowledgeBaseID);
  490. cache.put(knowledgeBaseID,queryResults,60000);
  491. console.log("Generated");
  492. }
  493. ).catch(function(error){
  494. cache.del(knowledgeBaseID);
  495. });
  496. return res.status(201).send(knowledgeBaseNew);
  497. }
  498. }
  499. const knowledgeBase = new knowledgeBases();
  500. export default knowledgeBase;