From 36ea1e1a353ec78a61a257176566e8a2b6b703ba Mon Sep 17 00:00:00 2001 From: chin Date: Fri, 11 Mar 2022 21:24:21 +0800 Subject: [PATCH] feat: change validator storepath;add empty profile - support validate with empty profile (base validation) - add new code `invalid` in operation outcome - change validator storepath to relative path --- api/FHIRApiService/$validate.js | 45 +++++++++++++++---- models/FHIR/fhir-validator.js | 7 +-- models/FHIR/httpMessage.js | 3 +- .../FHIR/schedule-update-validation-files.js | 5 ++- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/api/FHIRApiService/$validate.js b/api/FHIRApiService/$validate.js index d8f1f337..edd99196 100644 --- a/api/FHIRApiService/$validate.js +++ b/api/FHIRApiService/$validate.js @@ -1,6 +1,7 @@ const _ = require('lodash'); const FHIR = require('fhir').Fhir; -const { handleError } = require('../../models/FHIR/httpMessage'); +const mongodb = require('../../models/mongodb'); +const { handleError, OperationOutcome, issue} = require('../../models/FHIR/httpMessage'); const { validateByProfile, validateByMetaProfile } = require('../../models/FHIR/fhir-validator'); const { logger } = require('../../utils/log'); const path = require('path'); @@ -23,13 +24,7 @@ module.exports = async function (req, res, resourceType) { return res.status(code).send(item); }; try { - let operationOutcomeMessage; - let profileUrl = _.get(req.query, "profile"); - if (profileUrl) { - operationOutcomeMessage = await validateByProfile(profileUrl, req.body); - } else { - operationOutcomeMessage = await validateByMetaProfile(req.body); - } + let operationOutcomeMessage = await getValidateResult(req, resourceType); let haveError = (_.get(operationOutcomeMessage, "issue")) ? operationOutcomeMessage.issue.find(v=> v.severity === "error") : false; if (haveError) { return doRes(412, operationOutcomeMessage); @@ -41,4 +36,36 @@ module.exports = async function (req, res, resourceType) { let operationOutcomeError = handleError.exception(errorStr); return doRes(500, operationOutcomeError); } -}; \ No newline at end of file +}; + +/** + * + * @param {import('express').Request} req + * @param {string} resourceType + */ +async function getValidateResult(req, resourceType) { + try { + let profileUrl = _.get(req.query, "profile"); + let metaProfiles = _.get(req.body, "meta.profile", false); + if (profileUrl) { + return await validateByProfile(profileUrl, req.body); + } else if (metaProfiles) { + return await validateByMetaProfile(req.body); + } + let validation = await mongodb[resourceType].validate(req.body); + } catch(e) { + let name = _.get(e, "name"); + if (name === "ValidationError") { + let operationOutcomeError = new OperationOutcome([]); + for (let errorKey in e.errors) { + let error = e.errors[errorKey]; + let message = _.get(error, "message", `${error} invalid`); + let errorIssue = new issue("error", "invalid", message); + _.set(errorIssue, "Location", [errorKey]); + operationOutcomeError.issue.push(errorIssue); + } + return operationOutcomeError; + } + throw e; + } +} \ No newline at end of file diff --git a/models/FHIR/fhir-validator.js b/models/FHIR/fhir-validator.js index 0e8c7db7..72a19b70 100644 --- a/models/FHIR/fhir-validator.js +++ b/models/FHIR/fhir-validator.js @@ -74,12 +74,13 @@ async function validateByMetaProfile(resourceContent) { await fetchCodeSystem(resJson); } let contentHash = hash(resJson); - let storePath = path.join(process.env.VALIDATION_FILES_ROOT_PATH, hash({url:url}) + ".json"); + let urlHash = hash({url:url}); + let storePath = path.join(process.env.VALIDATION_FILES_ROOT_PATH, urlHash + ".json"); fs.writeFile(path.resolve(storePath), JSON.stringify(resJson), ()=> {}); let validationFileObj = { url: url, hash: contentHash, - path: storePath, + path: `${urlHash}.json`, id: resJson.id }; await mongodb.FHIRValidationFiles.findOneAndUpdate({ @@ -148,7 +149,7 @@ async function refreshResourceResolver() { * Call C# API server to validate with profiles. * @param {Array} profile The string array of profiles URL. * @param {JSON} resourceContent The FHIR resource JSON object. - * @return {JSON} + * @return {Promise} */ async function validate(profile, resourceContent) { try { diff --git a/models/FHIR/httpMessage.js b/models/FHIR/httpMessage.js index 8ba7ff27..cbcfb52e 100644 --- a/models/FHIR/httpMessage.js +++ b/models/FHIR/httpMessage.js @@ -54,7 +54,8 @@ const handleError = { "not-supported" : (err) => getOperationOutCome(err,"not-supported"), "security": (err) => getOperationOutCome(err, "security"), "expired": (err) => getOperationOutCome(err, "expired"), - "forbidden": (err) => getOperationOutCome(err, "forbidden") + "forbidden": (err) => getOperationOutCome(err, "forbidden"), + "invalid": (err) => getOperationOutCome(err, "invalid") }; diff --git a/models/FHIR/schedule-update-validation-files.js b/models/FHIR/schedule-update-validation-files.js index c764af34..d1c44340 100644 --- a/models/FHIR/schedule-update-validation-files.js +++ b/models/FHIR/schedule-update-validation-files.js @@ -23,12 +23,13 @@ const schedule = require('node-schedule'); } else if (resJson.resourceType === "ValueSet") { await fetchCodeSystem(resJson); } - let storePath = path.join(process.env.VALIDATION_FILES_ROOT_PATH, hash({url:url}) + ".json"); + let urlHash = hash({url:url}); + let storePath = path.join(process.env.VALIDATION_FILES_ROOT_PATH, urlHash + ".json"); fs.writeFile(path.resolve(storePath), JSON.stringify(resJson), ()=> {}); let validationFileObj = { url: url, hash: contentHash, - path: storePath, + path: `${urlHash}.json`, id: resJson.id }; await mongodb.FHIRValidationFiles.findOneAndUpdate({