From 0f4594e201d71571f7b27c1bd2fbf752bff3fc00 Mon Sep 17 00:00:00 2001 From: Anne Marsan Date: Wed, 27 Nov 2024 09:39:31 -0500 Subject: [PATCH] Have the Clear Server Cache button clear the cdm_cache and achilles_cache tables (#2980) Fixes #2847 --- .editorconfig | 13 ++ js/pages/configuration/configuration.js | 269 +++++++++++++++++------- js/services/CacheAPI.js | 35 +-- js/services/SourceAPI.js | 9 +- 4 files changed, 229 insertions(+), 97 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..5bafefd75 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false +quote_type = single \ No newline at end of file diff --git a/js/pages/configuration/configuration.js b/js/pages/configuration/configuration.js index a13723d96..5d5aadbb4 100644 --- a/js/pages/configuration/configuration.js +++ b/js/pages/configuration/configuration.js @@ -14,7 +14,7 @@ define([ 'services/job/jobDetail', 'services/CacheAPI', 'less!./configuration.less', - 'components/heading' + 'components/heading', ], function ( ko, view, @@ -27,11 +27,11 @@ define([ sharedState, constants, jobDetailsService, - {PollService}, + { PollService }, jobDetail, - cacheApi, + cacheApi ) { - class Configuration extends AutoBind(Page) { + class Configuration extends AutoBind(Page) { constructor(params) { super(params); this.config = config; @@ -44,16 +44,38 @@ define([ this.sources = sharedState.sources; this.priorityOptions = [ - {id: 'session', name: ko.i18n('configuration.priorityOptions.session', 'Current Session')}, - {id: 'application', name: ko.i18n('configuration.priorityOptions.application', 'Whole Application')}, + { + id: 'session', + name: ko.i18n( + 'configuration.priorityOptions.session', + 'Current Session' + ), + }, + { + id: 'application', + name: ko.i18n( + 'configuration.priorityOptions.application', + 'Whole Application' + ), + }, ]; this.isAuthenticated = authApi.isAuthenticated; - this.initializationCompleted = ko.pureComputed(() => sharedState.appInitializationStatus() === constants.applicationStatuses.running || - sharedState.appInitializationStatus() === constants.applicationStatuses.noSourcesAvailable); + this.initializationCompleted = ko.pureComputed( + () => + sharedState.appInitializationStatus() === + constants.applicationStatuses.running || + sharedState.appInitializationStatus() === + constants.applicationStatuses.noSourcesAvailable + ); this.hasSourceAccess = authApi.hasSourceAccess; this.hasPageAccess = ko.pureComputed(() => { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedEditConfiguration()) || !config.userAuthenticationEnabled; + return ( + (config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedEditConfiguration()) || + !config.userAuthenticationEnabled + ); }); this.canReadRoles = ko.pureComputed(() => { return this.isAuthenticated() && authApi.isPermittedReadRoles(); @@ -62,26 +84,42 @@ define([ if (!config.userAuthenticationEnabled) { return false; } else { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedCreateSource()); + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedCreateSource() + ); } }); this.canChangePriority = ko.pureComputed(() => { if (!config.userAuthenticationEnabled) { return false; } else { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedEditSourcePriority()) + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedEditSourcePriority() + ); } }); - this.canImport = ko.pureComputed(() => this.isAuthenticated() && authApi.isPermittedImportUsers()); - this.canManageTags = ko.pureComputed(() => this.isAuthenticated() && authApi.isPermittedTagsManagement()); + this.canImport = ko.pureComputed( + () => this.isAuthenticated() && authApi.isPermittedImportUsers() + ); + this.canManageTags = ko.pureComputed( + () => this.isAuthenticated() && authApi.isPermittedTagsManagement() + ); this.canClearServerCache = ko.pureComputed(() => { - return config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedClearServerCache() + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedClearServerCache() + ); }); this.intervalId = PollService.add({ callback: () => this.checkJobs(), - interval: config.pollInterval + interval: config.pollInterval, }); } @@ -95,18 +133,22 @@ define([ async checkJobs() { const notifications = await jobDetailsService.listRefreshCacheJobs(); - const jobs = notifications.data.map(n => { - const job = new jobDetail(); - job.status(n.status); - job.executionId = n.executionId; - return job; + const jobs = notifications.data.map((n) => { + const job = new jobDetail(); + job.status(n.status); + job.executionId = n.executionId; + return job; }); - jobs.forEach(job => { + jobs.forEach((job) => { let source = this.getSource(job); if (source && (job.isComplete() || job.isFailed())) { this.sourceJobs.delete(job.executionId); - source.refreshState(job.isComplete() ? sourceApi.buttonCheckState.success : sourceApi.buttonCheckState.failed); + source.refreshState( + job.isComplete() + ? sourceApi.buttonCheckState.success + : sourceApi.buttonCheckState.failed + ); } }); } @@ -119,52 +161,99 @@ define([ } canReadSource(source) { - if (!config.userAuthenticationEnabled) { - return false; - } else { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedReadSource(source.sourceKey)); - } + if (!config.userAuthenticationEnabled) { + return false; + } else { + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedReadSource(source.sourceKey) + ); + } } - canCheckConnection(source) { - if (!config.userAuthenticationEnabled) { - return false; - } else { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.isPermittedCheckSourceConnection(source.sourceKey)); - } + canCheckConnection(source) { + if (!config.userAuthenticationEnabled) { + return false; + } else { + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.isPermittedCheckSourceConnection(source.sourceKey) + ); + } } canRefreshSourceCache(source) { if (!config.userAuthenticationEnabled) { return false; } else { - return (config.userAuthenticationEnabled && this.isAuthenticated() && authApi.hasSourceAccess(source.sourceKey) && source.hasResults - && (source.hasVocabulary || source.hasCDM)); + return ( + config.userAuthenticationEnabled && + this.isAuthenticated() && + authApi.hasSourceAccess(source.sourceKey) && + source.hasResults && + (source.hasVocabulary || source.hasCDM) + ); } } - clearLocalStorageCache() { - localStorage.clear(); - - alert(ko.unwrap(ko.i18n('configuration.alerts.clearLocalCache', 'Local Storage has been cleared. Please refresh the page to reload configuration information.'))) - }; - - clearServerCache() { - if (confirm(ko.unwrap(ko.i18n('configuration.confirms.clearServerCache', 'Are you sure you want to clear the server cache?')))) { - cacheApi.clearCache().then(() => { + clearLocalStorageCache() { + localStorage.clear(); + + alert( + ko.unwrap( + ko.i18n( + 'configuration.alerts.clearLocalCache', + 'Local Storage has been cleared. Please refresh the page to reload configuration information.' + ) + ) + ); + } - alert(ko.unwrap(ko.i18n('configuration.alerts.clearServerCache', 'Server cache has been cleared.'))); - }); + clearServerCache() { + if ( + confirm( + ko.unwrap( + ko.i18n( + 'configuration.confirms.clearServerCache', + 'Are you sure you want to clear the server cache?' + ) + ) + ) + ) { + cacheApi.clearCache().then( + () => { + alert( + ko.unwrap( + ko.i18n( + 'configuration.alerts.clearServerCache', + 'Server cache has been cleared.' + ) + ) + ); + }, + (error) => { + alert( + ko.unwrap( + ko.i18n( + 'configuration.alerts.clearServerCacheError', + 'There was an error! The server cache has NOT been cleared.' + ) + ) + ); + } + ); } - }; + } - newSource() { + newSource() { commonUtils.routeTo('/source/0'); - }; + } - selectSource(source) { - document.location = "#/source/" + source.sourceId; - }; + selectSource(source) { + document.location = '#/source/' + source.sourceId; + } async updateSourceDaimonPriority(sourceKey, daimonType) { if (sharedState.priorityScope() !== 'application') { @@ -174,51 +263,73 @@ define([ try { await sourceApi.updateSourceDaimonPriority(sourceKey, daimonType); await sourceApi.initSourcesConfig(); - } catch(err) { - alert(ko.unwrap(ko.i18n('configuration.alerts.failUpdatePrioritySourceDaimon', 'Failed to update priority source daimon'))); - + } catch (err) { + alert( + ko.unwrap( + ko.i18n( + 'configuration.alerts.failUpdatePrioritySourceDaimon', + 'Failed to update priority source daimon' + ) + ) + ); } this.isInProgress(false); } updateVocabPriority() { var newVocabUrl = sharedState.vocabularyUrl(); - var selectedSource = sharedState.sources().find((item) => { return item.vocabularyUrl === newVocabUrl; }); - sharedState.priorityScope() === 'application' && sharedState.defaultVocabularyUrl(newVocabUrl); + var selectedSource = sharedState.sources().find((item) => { + return item.vocabularyUrl === newVocabUrl; + }); + sharedState.priorityScope() === 'application' && + sharedState.defaultVocabularyUrl(newVocabUrl); this.updateSourceDaimonPriority(selectedSource.sourceKey, 'Vocabulary'); return true; - }; + } updateEvidencePriority() { var newEvidenceUrl = sharedState.evidenceUrl(); - var selectedSource = sharedState.sources().find((item) => { return item.evidenceUrl === newEvidenceUrl; }); - sharedState.priorityScope() === 'application' && sharedState.defaultEvidenceUrl(newEvidenceUrl); + var selectedSource = sharedState.sources().find((item) => { + return item.evidenceUrl === newEvidenceUrl; + }); + sharedState.priorityScope() === 'application' && + sharedState.defaultEvidenceUrl(newEvidenceUrl); this.updateSourceDaimonPriority(selectedSource.sourceKey, 'CEM'); return true; - }; + } updateResultsPriority() { var newResultsUrl = sharedState.resultsUrl(); - var selectedSource = sharedState.sources().find((item) => { return item.resultsUrl === newResultsUrl; }); - sharedState.priorityScope() === 'application' && sharedState.defaultResultsUrl(newResultsUrl); + var selectedSource = sharedState.sources().find((item) => { + return item.resultsUrl === newResultsUrl; + }); + sharedState.priorityScope() === 'application' && + sharedState.defaultResultsUrl(newResultsUrl); this.updateSourceDaimonPriority(selectedSource.sourceKey, 'Results'); return true; - }; + } checkSourceConnection(source) { - sourceApi.checkSourceConnection(source.sourceKey) - .then( ({ data }) => - source.connectionCheck(data.sourceId === undefined ? - sourceApi.buttonCheckState.failed : sourceApi.buttonCheckState.success)) - .catch(() => {source.connectionCheck(sourceApi.buttonCheckState.failed);}); + sourceApi + .checkSourceConnection(source.sourceKey) + .then(({ data }) => + source.connectionCheck( + data.sourceId === undefined + ? sourceApi.buttonCheckState.failed + : sourceApi.buttonCheckState.success + ) + ) + .catch(() => { + source.connectionCheck(sourceApi.buttonCheckState.failed); + }); source.connectionCheck(sourceApi.buttonCheckState.checking); - }; + } async refreshSourceCache(source) { try { source.refreshState(sourceApi.buttonCheckState.checking); const { data } = await sourceApi.refreshSourceCache(source.sourceKey); - if(data.executionId === undefined) { + if (data.executionId === undefined) { source.refreshState(sourceApi.buttonCheckState.failed); } else { jobDetailsService.createJob(data); @@ -231,8 +342,8 @@ define([ } getRefreshCacheButtonStyles(source) { - return this.getButtonStyles(source.refreshState()) - }; + return this.getButtonStyles(source.refreshState()); + } getCheckButtonStyles(source) { return this.getButtonStyles(source.connectionCheck()); @@ -241,7 +352,7 @@ define([ getButtonStyles(sourceState) { let iconClass = 'fa-caret-right'; let buttonClass = 'btn-primary'; - switch(sourceState) { + switch (sourceState) { case sourceApi.buttonCheckState.success: buttonClass = 'btn-success'; iconClass = 'fa-check-square'; @@ -258,16 +369,19 @@ define([ return { iconClass, buttonClass, - } + }; } runDiagnostics() { - const startTime = performance.now(); // get the list of isPermitted functions, except the literal isPermitted for (const key in authApi) { - if (typeof authApi[key] === 'function' && key.startsWith('isPermitted') && key != 'isPermitted') { + if ( + typeof authApi[key] === 'function' && + key.startsWith('isPermitted') && + key != 'isPermitted' + ) { authApi[key](); // Invoke the function } } @@ -276,7 +390,6 @@ define([ const elapsedTime = endTime - startTime; console.log(`Script execution time: ${elapsedTime} milliseconds`); - } } diff --git a/js/services/CacheAPI.js b/js/services/CacheAPI.js index 7f03b6273..3e42aafeb 100644 --- a/js/services/CacheAPI.js +++ b/js/services/CacheAPI.js @@ -1,19 +1,20 @@ -define(function(require, exports) { +define(function (require, exports) { + const config = require('appConfig'); + const authApi = require('services/AuthAPI'); + const httpService = require('services/http'); - const config = require('appConfig'); - const authApi = require('services/AuthAPI'); - const httpService = require('services/http'); + function clearCache() { + return httpService + .doPost(config.webAPIRoot + 'cdmresults/clearCache') + .then((res) => res.data) + .catch((error) => { + console.log('Error: ' + error); + authApi.handleAccessDenied(error); + return Promise.reject(error); + }); + } - function clearCache() { - return httpService.doGet(config.webAPIRoot + 'cache/clear') - .then(res => res.data) - .catch((error) => { - console.log("Error: " + error); - authApi.handleAccessDenied(error); - }); - } - - return { - clearCache, - }; -}); \ No newline at end of file + return { + clearCache, + }; +}); diff --git a/js/services/SourceAPI.js b/js/services/SourceAPI.js index 8aa5dbe4c..6290fa504 100644 --- a/js/services/SourceAPI.js +++ b/js/services/SourceAPI.js @@ -185,8 +185,13 @@ define(function (require, exports) { return httpService.doGet(config.webAPIRoot + 'source/connection/' + sourceKey) } - function refreshSourceCache(sourceKey) { - return httpService.doGet(config.webAPIRoot + 'cdmresults/' + sourceKey + '/refreshCache'); + async function refreshSourceCache(sourceKey) { + await httpService.doPost( + config.webAPIRoot + 'cdmresults/' + sourceKey + '/clearCache' + ); + return await httpService.doGet( + config.webAPIRoot + 'cdmresults/' + sourceKey + '/refreshCache' + ); } function updateSourceDaimonPriority(sourceKey, daimonType) {