diff --git a/adapter/adapter-service/src/main/sql/mssql.ddl b/adapter/adapter-service/src/main/sql/mssql.ddl index d61789116..badf8a64e 100644 --- a/adapter/adapter-service/src/main/sql/mssql.ddl +++ b/adapter/adapter-service/src/main/sql/mssql.ddl @@ -1,5 +1,5 @@ -create table "queriesReceived" ("shrineNodeId" TEXT NOT NULL,"userName" TEXT NOT NULL,"networkQueryId" BIGINT NOT NULL,"queryName" TEXT NOT NULL,"topicId" TEXT,"topicName" TEXT,"timeQuerySent" BIGINT NOT NULL,"timeReceived" BIGINT NOT NULL); -create table "executionsStarted" ("networkQueryId" BIGINT NOT NULL,"queryName" TEXT NOT NULL,"timeExecutionStarted" BIGINT NOT NULL); -create table "executionsCompleted" ("networkQueryId" BIGINT NOT NULL,"replyId" BIGINT NOT NULL,"queryName" TEXT NOT NULL,"timeExecutionCompleted" BIGINT NOT NULL); -create table "resultsSent" ("networkQueryId" BIGINT NOT NULL,"replyId" BIGINT NOT NULL,"queryName" TEXT NOT NULL,"timeResultsSent" BIGINT NOT NULL); -create table "problems" ("id" BIGINT NOT NULL, "codec" TEXT NOT NULL,"stampText" TEXT NOT NULL,"summary" TEXT NOT NULL,"description" TEXT NOT NULL,"detailsXml" TEXT NOT NULL,"epoch" BIGINT NOT NULL); \ No newline at end of file +create table "queriesReceived" ("shrineNodeId" VARCHAR(MAX) NOT NULL,"userName" VARCHAR(MAX) NOT NULL,"networkQueryId" BIGINT NOT NULL,"queryName" VARCHAR(MAX) NOT NULL,"topicId" VARCHAR(MAX),"topicName" VARCHAR(MAX),"timeQuerySent" BIGINT NOT NULL,"timeReceived" BIGINT NOT NULL); +create table "executionsStarted" ("networkQueryId" BIGINT NOT NULL,"queryName" VARCHAR(MAX) NOT NULL,"timeExecutionStarted" BIGINT NOT NULL); +create table "executionsCompleted" ("networkQueryId" BIGINT NOT NULL,"replyId" BIGINT NOT NULL,"queryName" VARCHAR(MAX) NOT NULL,"timeExecutionCompleted" BIGINT NOT NULL); +create table "resultsSent" ("networkQueryId" BIGINT NOT NULL,"replyId" BIGINT NOT NULL,"queryName" VARCHAR(MAX) NOT NULL,"timeResultsSent" BIGINT NOT NULL); +create table "problems" ("id" BIGINT NOT NULL, "codec" VARCHAR(MAX) NOT NULL,"stampText" VARCHAR(MAX) NOT NULL,"summary" VARCHAR(MAX) NOT NULL,"description" VARCHAR(MAX) NOT NULL,"detailsXml" VARCHAR(MAX) NOT NULL,"epoch" BIGINT NOT NULL); \ No newline at end of file diff --git a/adapter/adapter-service/src/main/sql/oracle.ddl b/adapter/adapter-service/src/main/sql/oracle.ddl index dece08037..dd7a43239 100644 --- a/adapter/adapter-service/src/main/sql/oracle.ddl +++ b/adapter/adapter-service/src/main/sql/oracle.ddl @@ -1,5 +1,5 @@ create table "queriesReceived" ("shrineNodeId" VARCHAR2(256) NOT NULL,"userName" VARCHAR2(256) NOT NULL,"networkQueryId" NUMBER NOT NULL,"queryName" VARCHAR2(256) NOT NULL,"topicId" VARCHAR2(256),"topicName" VARCHAR2(256),"timeQuerySent" NUMBER NOT NULL,"timeReceived" NUMBER NOT NULL); create table "executionsStarted" ("networkQueryId" NUMBER NOT NULL,"queryName" VARCHAR2(256) NOT NULL,"timeExecutionStarted" NUMBER NOT NULL); create table "executionsCompleted" ("networkQueryId" NUMBER NOT NULL,"replyId" NUMBER NOT NULL,"queryName" VARCHAR2(256) NOT NULL,"timeExecutionCompleted" NUMBER NOT NULL); create table "resultsSent" ("networkQueryId" NUMBER NOT NULL,"replyId" NUMBER NOT NULL,"queryName" VARCHAR2(256) NOT NULL,"timeResultsSent" NUMBER NOT NULL); -create table "problems" ("id" NUMBER NOT NULL, "codec" VARCHAR2(256) NOT NULL,"stampText" VARCHAR2(256) NOT NULL,"summary" VARCHAR2(256) NOT NULL,"description" VARCHAR2(256) NOT NULL,"detailsXml" VARCHAR2(256) NOT NULL,"epoch" NUMBER NOT NULL); \ No newline at end of file +create table "problems" ("id" NUMBER NOT NULL, "codec" VARCHAR2(256) NOT NULL,"stampText" VARCHAR2(256) NOT NULL,"summary" VARCHAR2(256) NOT NULL,"description" VARCHAR2(512) NOT NULL,"detailsXml" CLOB NOT NULL,"epoch" NUMBER NOT NULL); \ No newline at end of file diff --git a/apps/dashboard-app/src/main/resources/reference.conf b/apps/dashboard-app/src/main/resources/reference.conf index a80b388e1..b1dd0f233 100644 --- a/apps/dashboard-app/src/main/resources/reference.conf +++ b/apps/dashboard-app/src/main/resources/reference.conf @@ -1,82 +1,82 @@ shrine { dashboard { gruntWatch = false //false for production, true for mvn tomcat7:run . Allows the client javascript and html files to be loaded via gruntWatch . happyBaseUrl = "https://localhost:6443/shrine/rest/happy" statusBaseUrl = "https://localhost:6443/shrine/rest/internalstatus" remoteDashboard { protocol = "https://" port = ":6443" pathPrefix = "shrine-dashboard/fromDashboard" } database { dataSourceFrom = "JNDI" //Can be JNDI or testDataSource . Use testDataSource for tests, JNDI everywhere else - jndiDataSourceName = "java:comp/env/jdbc/adapterAuditsDB" //or leave out for tests + jndiDataSourceName = "java:comp/env/jdbc/adapterAuditDB" //or leave out for tests slickProfileClassName = "slick.driver.MySQLDriver$" // Can be // slick.driver.H2Driver$ // slick.driver.MySQLDriver$ // slick.driver.PostgresDriver$ // slick.driver.SQLServerDriver$ // slick.driver.JdbcDriver$ // freeslick.OracleProfile$ // freeslick.MSSQLServerProfile$ // // (Yes, with the $ on the end) // For testing without JNDI // testDataSource { //typical test settings for unit tests //driverClassName = "org.h2.Driver" //url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" //H2 embedded in-memory for unit tests //url = "jdbc:h2:~/stewardTest.h2" //H2 embedded on disk at ~/test // } createTablesOnStart = false //for testing with H2 in memory, when not running unit tests. Set to false normally } } pmEndpoint { url = "http://changeme.com/i2b2/services/PMService/getServices" //"http://services.i2b2.org/i2b2/services/PMService/getServices" acceptAllCerts = true timeout { seconds = 10 } } authenticate { realm = "SHRINE Steward API" usersource { type = "PmUserSource" //Must be ConfigUserSource (for isolated testing) or PmUserSource (for everything else) domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in dashboard.conf" //"i2b2demo" } } // If the pmEndpoint acceptAllCerts = false then you need to supply a keystore // Or if you would like dashboard-to-dashboard comms to work. // keystore { // file = "shrine.keystore" // password = "chiptesting" // privateKeyAlias = "test-cert" // keyStoreType = "JKS" // caCertAliases = [carra ca] // } } //todo typesafe config precedence seems to do the right thing, but I haven't found the rules that say this reference.conf should override others akka { loglevel = INFO // log-config-on-start = on loggers = ["akka.event.slf4j.Slf4jLogger"] // logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" // Toggles whether the threads created by this ActorSystem should be daemons or not daemonic = on } spray.servlet { boot-class = "net.shrine.dashboard.Boot" request-timeout = 30s } diff --git a/apps/steward-app/src/main/js/app/client/login/login.tpl.html b/apps/steward-app/src/main/js/app/client/login/login.tpl.html index a2a0b3fe5..65256b195 100644 --- a/apps/steward-app/src/main/js/app/client/login/login.tpl.html +++ b/apps/steward-app/src/main/js/app/client/login/login.tpl.html @@ -1,72 +1,72 @@

Username*
Password*
+ for="inputError">invalid login
diff --git a/apps/steward-app/src/main/js/app/client/steward.controller.js b/apps/steward-app/src/main/js/app/client/steward.controller.js index db3bf0204..8cad1df3f 100644 --- a/apps/steward-app/src/main/js/app/client/steward.controller.js +++ b/apps/steward-app/src/main/js/app/client/steward.controller.js @@ -1,26 +1,39 @@ (function () { angular.module('shrine.steward') .controller('StewardController', StewardController); StewardController.$inject = ['$location','StewardService']; function StewardController($location, StewardService) { var steward = this; steward.isUserLoggedIn = StewardService.isUserLoggedIn; steward.getUsername = StewardService.getUsername; steward.getRole = StewardService.getRole; steward.isSteward = StewardService.isSteward; steward.showStewardMenuOptions = false; - steward.layoutWidth = 12; - steward.logout = StewardService.logoutUser; + setLoggedOutLayout(); + steward.logout = logout; // -- set login callback. todo: investigate advantage of broadcaster instead. -- // StewardService.setLoginSubscriber(loginSubscriber); + function setLoggedInLayout() { + steward.layoutWidth = 10; + } + + function setLoggedOutLayout() { + steward.layoutWidth = 12; + } + + function logout() { + setLoggedOutLayout(); + StewardService.logoutUser(); + } + function loginSubscriber(appUser) { steward.showStewardMenuOptions = steward.isSteward(); - steward.layoutWidth = 10; + setLoggedInLayout(); } } })(); diff --git a/apps/steward-app/src/main/js/app/client/steward.runner.js b/apps/steward-app/src/main/js/app/client/steward.runner.js index ced2e6989..2ce829557 100644 --- a/apps/steward-app/src/main/js/app/client/steward.runner.js +++ b/apps/steward-app/src/main/js/app/client/steward.runner.js @@ -1,33 +1,30 @@ (function () { 'use strict'; angular .module('shrine.steward') .run(StewardRunner); /** * App Run Phase - Set up listener to verify user has access. */ StewardRunner.$inject = ['$rootScope', '$location', 'StewardService']; function StewardRunner($rootScope, $location, StewardService) { var defaultRoute = StewardService.constants.defaultRoute; var path = $location.path(); $rootScope.$on('$locationChangeStart', verifyIdentity); function verifyIdentity(event, next, current) { - if (isUserNotLoggedIn() && isRedirectNecessary()) { + if (isUserNotLoggedIn()) { $location.path(defaultRoute); } } - function isRedirectNecessary() { - return path !== defaultRoute; - } function isUserNotLoggedIn() { var currentUser = StewardService.getAppUser(); return (!currentUser || !currentUser.isLoggedIn); } } })(); diff --git a/apps/steward-app/src/main/js/index.html b/apps/steward-app/src/main/js/index.html index cdc8e7385..563e1d588 100644 --- a/apps/steward-app/src/main/js/index.html +++ b/apps/steward-app/src/main/js/index.html @@ -1,121 +1,121 @@ Shrine Data Steward



\ No newline at end of file diff --git a/shrine-webclient/src/main/html/js-i2b2/cells/SHRINE/EnhancedError.js b/shrine-webclient/src/main/html/js-i2b2/cells/SHRINE/EnhancedError.js index 8991f1a12..61b2caaa8 100644 --- a/shrine-webclient/src/main/html/js-i2b2/cells/SHRINE/EnhancedError.js +++ b/shrine-webclient/src/main/html/js-i2b2/cells/SHRINE/EnhancedError.js @@ -1,354 +1,354 @@ /** * Created by ben on 10/13/15. */ var $hrine = window.$hrine = {}; $hrine.EnhancedError = (function(){ var EnhancedError = {}, config = config || { //@TODO: }; /** * * @returns {{}} */ function simulateI2b2Obj() { var self = {}; var errorObject = { summary: "SHRINE Failed to Start", description: "The SHRINE software is not running at the queried site. This error must be corrected at the queried site." + "Check network status or contact your local SHRINE administrator. " + "For faster assistance, expand this window and provide all text below this line to your local SHRINE administrator.", details: "There is a fatal syntax error in the remote site's shrine.conf or another .conf file. " + "The remote site admin should check to make sure that there are no stray/missing quotes or brackets, " + "and that URLs are entered correctly.", codec: "" }; self.errorObject = errorObject; self.dispDIV = document.getElementById('infoQueryStatusText'); self.dispDIV.innerHTML = '
SHRINE Critical Error
'; //which hospital self.dispDIV.innerHTML += '

Error Summary:
'; self.dispDIV.innerHTML += "" + "" + errorObject.summary + ""; return self; } /** * Scope for error dialog. */ EnhancedError.createErrorDialogue = function (container, errorObjects) { var anchors, btnExpand, btnContract, errorData, i2b2Obj; //default error. if(!container || !errorObjects) { i2b2Obj = simulateI2b2Obj(); container = i2b2Obj.dispDIV; errorObjects = [i2b2Obj.errorObject]; } //this sets up the events. anchors = container.getElementsByClassName('query-error-anchor'); //something's wrong captain, abandon ship! if(!anchors.length|| !errorObjects.length) { return; } addAnchorEvents(); function expandErrorDetailDiv (ev) { var errorDetailDiv = $('errorDetailDiv'); btnExpand.style.display = 'none'; btnContract.style.display = 'inline'; errorDetailDiv.innerHTML = getExpandedHtml(); } function retractErrorDetailDiv (ev) { var errorDetailDiv = $('errorDetailDiv'); btnExpand.style.display = 'inline'; btnContract.style.display = 'none'; errorDetailDiv.innerHTML = getRetractedHtml(); } function onClick(evt) { //ie logic. var currentTarget = (evt.currentTarget !== undefined)? evt.currentTarget : evt.srcElement.parentElement.parentElement; errorData = currentTarget.__errorData__; btnExpand = document.getElementById('btnExpandErrorDetail'); btnContract = document.getElementById('btnContractErrorDetail'); // -- add event listeners for expand and contract as well --// addEventListener(btnExpand, 'click', expandErrorDetailDiv, false); addEventListener(btnContract,'click', retractErrorDetailDiv, false); showErrorDetail(errorData); } /** * * @param errorData * @returns {string} */ function getRetractedHtml () { - var wikiBaseUrl = (cei2b2.hive.cfg.wikiBaseUrl || 'https://open.med.harvard.edu/wiki/display/SHRINE/'); + var wikiBaseUrl = (i2b2.hive.cfg.wikiBaseUrl || 'https://open.med.harvard.edu/wiki/display/SHRINE/'); if(wikiBaseUrl.lastIndexOf('/') !== wikiBaseUrl.length -1){ wikiBaseUrl += '/'; } var retractedHtml = '
Summary:
'+ '
' + errorData.summary + '

' + '
Description:
'+ '
' + errorData.description + '

' + '
For information on troubleshooting and resolution, check' + ' the SHRINE Error' + ' Codex.
'; return retractedHtml; } /** * * @param errorData * @returns {string} */ function getExpandedHtml () { var expandedHtml = getRetractedHtml() + '
' + '
Copy the text below and paste it in an email to your site administrator for a faster response.
' + '
' + '
Technical Details:
' + errorData.details + '

' + '
Codec:
' + errorData.codec + '

' + '
Stamp:
' + errorData.stamp + '

' + '
Stack Trace Name:
' + errorData.exception.name + '

' + '
Stack Trace Message:
' + errorData.exception.message + '

' + '
Stack Trace Details:
' + errorData.exception.stackTrace + '

'; return expandedHtml; } /** * * @param detailObj */ function showErrorDetail(detailObj) { var handleCancel = function() { this.cancel(); removeAllEvents(); retractErrorDetailDiv(); } var dialogErrorDetail = new YAHOO.widget.SimpleDialog("dialogErrorDetail", { width: "820px", fixedcenter: true, constraintoviewport: true, modal: true, zindex: 700, buttons: [ { text: "Done", handler: handleCancel, isDefault: true }] }); dialogErrorDetail._doClose = function (e) { this.cancel(); removeAllEvents(); retractErrorDetailDiv(); } $('dialogErrorDetail').show(); dialogErrorDetail.validate = function(){ return true; }; dialogErrorDetail.render(document.body); // / display the dialoge dialogErrorDetail.center(); dialogErrorDetail.show(); $('errorDetailDiv').innerHTML = getRetractedHtml(); } function addAnchorEvents () { var el, length = anchors.length; // -- will need to iterate over these once they are created and add event listeners. for(var i = 0; i < length; i ++) { var el = anchors[i]; el.__errorData__ = errorObjects[i]; addEventListener(el, 'click', onClick, false); } } function removeAllEvents () { removeEventListener(btnExpand, 'click', expandErrorDetailDiv); removeEventListener(btnContract, 'click', retractErrorDetailDiv); } } /** * Parse problem node. * @param qriNode * @returns {{exception: {}}} */ EnhancedError.parseProblem = function (qriNode) { var details; var problem = { exception: {} }; problem.codec = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/codec'); problem.summary = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/summary'); problem.description = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/description'); problem.stamp = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/stamp'); //unescape embedded html. details = i2b2.h.XPath(qriNode, 'descendant-or-self::query_status_type/problem/details') //funky stuff goin' on...get outta here! if(!details.length) { problem.exception.name = problem.exception.message = problem.stackTrace = problem.codec = problem.summary = 'An unexpected error has occurred.'; } //error format as expected. else{ var innerHTML = (details[0].xml !== undefined)? details[0].xml : details[0].innerHTML?details[0].innerHTML:null; if(!innerHTML) { innerHTML = jQuery(details[0]).text(); } problem.details = innerHTML.unescapeHTML().replace(/(<([^>]+)>)/ig,""); problem.exception.name = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/details/exception/name'); problem.exception.message = grabXmlNodeData(qriNode, 'descendant-or-self::query_status_type/problem/details/exception/message'); problem.exception.stackTrace = parseErrorException(qriNode); } return problem; } /** * Replace all and with
tags. * @param node * @returns {*} */ function parseErrorException(node) { var innerHTML = (node.xml !== undefined)? node.xml : node.innerHTML?node.innerHTML:null;; if(!innerHTML) { innerHTML = jQuery(node).text(); } //no exception, abandon ship! if(innerHTML.indexOf('') == -1){ return ''; } var content, startIdx, endIdx; //fish out the problem section. content = innerHTML.split('') .join() .split('') .join(); //fish out the first stack trace. startIdx = content.indexOf('') + 12; endIdx = content.indexOf(''); content = content.substring(startIdx, endIdx); //remove all line tags and replace with line break. content = content.split('') .join('
') .split('
') .join() //remove all exception tags .split('') .join('
') .split('
') .join() //remove all stacktrace tags .split('') .join('
') .split('
') .join() //remove all message tags. .split('') .join('
') .split('
') .join(); return content; } /** * Grab data for node, return empty string if none. * @param node * @param xPathString * @returns {string} */ function grabXmlNodeData(node, xPathString){ var nodeVal = i2b2.h.XPath(node, xPathString); return (nodeVal.length)? nodeVal[0].firstChild.nodeValue : ''; } /** * * @param el * @param event * @param callback */ function addEventListener(el, event, callback) { if(el.addEventListener !== undefined) { el.addEventListener(event, callback, false); } else { el.attachEvent('on' + event, callback) } } /** * * @param el * @param event * @param callback */ function removeEventListener(el, event, callback) { if(el.removeEventListener !== undefined) { el.removeEventListener(event, callback); } else { el.detachEvent('on' + event, callback); } } return EnhancedError; })(); \ No newline at end of file