Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Next, we will retrieve the new SHRINE webapp from the HMS Sonatype Nexus server at: https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/shrine-war/1.25.4/. From there, download shrine-war-1.25.4.war to the webapps/ directory on the SHRINE server and rename it to shrine.war.

...

Much like shrine.war, the SHRINE Data Steward can be found on the HMS Sonatype Nexus server at https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/steward/1.25.4/. From there, download steward-1.25.4.war to the webapps/ directory on the SHRINE server and rename it to steward.war.

...

Like other SHRINE artifacts, the SHRINE proxy can be found on the HMS Sonatype Nexus server at https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/shrine-proxy/1.25.4/. From there, download shrine-proxy-1.25.4.war to the webapps/ directory on the SHRINE server and rename it to shrine-proxy.war.

...

The SHRINE webclient can be found on the HMS Sonatype Nexus server at https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/shrine-webclient/1.25.4/. From there, download shrine-webclient-1.25.4-dist.zip file to the webapps/ directory on the SHRINE server and rename it to shrine-webclient.zip. Then, unzip the shrine-webclient.zip file.

...

Like other SHRINE artifacts, the SHRINE Dashboard can be found on the HMS Sonatype Nexus server at https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/dashboard-war/1.25.4/. From there, download dashboard-war-1.25.4.war to the webapps/ directory on the SHRINE server and rename it to shrine-dashboard.war.

...

Like other SHRINE artifacts, the SHRINE Node Metadata Service can be found on the HMS Sonatype Nexus server at https://repo.open.med.harvard.edu/nexus/content/groups/public/net/shrine/meta-war/1.25.4/. From there, download meta-war-1.25.4.war to the webapps/ directory on the SHRINE server and rename it to shrine-metadata.war.

...

Since SHRINE 1.25.4, there are 2 a couple of changes to SHRINE's configuration file:

  1. You will need to add a new code block within the main shrine {} block:

    Code Block
    languagebash
    themeRDark
    messagequeue {
    	blockingq {
    		serverUrl = “https://shrine_hub_url:6443/shrine-metadata/mom”
    	}
    }
  2. Please take note that the database profile class names have changed: 

    1. slick.driver.MySQLDriver$ to slick.jdbc.MySQLProfile$ 

    2. slick.driver.H2Profile$ to slick.jdbc.H2Profile$ 

    3. slick.driver.PostgresProfile$ to slick.jdbc.PostgresProfile$ 

    4. slick.driver.SQLServerProfile$ to slick.jdbc.SQLServerProfile$ 

    5. slick.driver.JdbcProfile$ to slick.jdbc.JdbcProfile$

    6. slick.driver.OracleProfile$ to slick.jdbc.OracleProfile$

  3. Add externalStewardBaseUrl to the 'emailDataSteward' section under the steward {} block:
    1. externalStewardBaseUrl = "https://your_shrine_url:port/steward"

  4. If you are not using port 6443 to serve SHRINE:

    You will need to override a URL in shrine.conf to see progress and results from QUEUED queries. 

    Code Block
    languagebash
    themerdark
    shrine {
      queryEntryPoint {
        queuedQueryPollUrl = "https://localhost:6443/shrine/rest/i2b2/request" //Change to your url and port number
      }
    }

     

Sample SHRINE configuration file (for a downstream node)

...

Code Block
languagebash
themeRDark
titleshrine.conf
collapsetrue
shrine {
  pmEndpoint {
    url = "http://i2b2_node_url:9090/i2b2/services/PMService/getServices"
  }
  ontEndpoint {
    url = "http://i2b2_node_url:9090/i2b2/services/OntologyService"
  }
  
  hiveCredentials {
    domain = "i2b2demo"
    username = "demo"
    password = "demouser"
    crcProjectId = "Demo"
    ontProjectId = "SHRINE"
  }

  messagequeue {
    blockingq {
        serverUrl = "https://shrine-act-test.hms.harvard.edu:6443/shrine-metadata/mom"
    }
  }
  
  breakdownResultOutputTypes {
    PATIENT_AGE_COUNT_XML {
      description = "Age patient breakdown"
    }
    PATIENT_RACE_COUNT_XML {
      description = "Race patient breakdown"
    }
    PATIENT_VITALSTATUS_COUNT_XML {
      description = "Vital Status patient breakdown"
    } 
    PATIENT_GENDER_COUNT_XML {
      description = "Gender patient breakdown"
    }
  }

  queryEntryPoint {
    create = true
    audit {
      collectQepAudit = false
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/qepAuditDB"
        slickProfileClassName = "slick.jdbc.MySQLProfile$"
      }
    }
      
    trustModelIsHub = true
    attachSigningCert = true
    authenticationType = "pm"
    authorizationType = "shrine-steward"
 
    queuedQueryPollUrl = "https://your_shrine_url:6443/shrine/rest/i2b2/request" //Change to your url and port number

    shrineSteward {
      qepUserName = "qep"
      qepPassword = "trustme"
      stewardBaseUrl = "https://localhost:6443"
    }

      includeAggregateResults = false
      
      maxQueryWaitTime {
        minutes = 5
      }

    broadcasterServiceEndpoint {
        url = "https://shrine-act-test.hms.harvard.edu:6443/shrine/rest/broadcaster/broadcast"
    }
  } //end queryEntryPoint

  adapter {
    create = true
    audit {
      collectAdapterAudit = false
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/adapterAuditDB"
        slickProfileClassName = "slick.jdbc.MySQLProfile$" 
      }
    }

    crcEndpoint {
      url = "http://i2b2_node_url:9090/i2b2/services/QueryToolService"
    }

    adapterLockoutAttemptsThreshold = 0
    setSizeObfuscation = true
    adapterMappingsFileName = "AdapterMappings.csv"

    maxSignatureAge {
      minutes = 5
    }

    immediatelyRunIncomingQueries = true

  } // end adapter

    networkStatusQuery = "\\\\SHRINE\\SHRINE\\Demographics\\Gender\\Male\\"
    humanReadableNodeName = "Harvard Test Node"
    shrineDatabaseType = "mysql"

    keystore {
      file = "/opt/shrine/shrine.keystore"
      password = "password"
      privateKeyAlias = "privateKeyAlias"
      keyStoreType = "JKS"
      caCertAliases = ["shrine-hub-ca"]
    }

    problem {
      problemHandler = "net.shrine.problem.LogAndDatabaseProblemHandler$"
      database {
    	dataSourceFrom = "JNDI"
    	jndiDataSourceName = "java:comp/env/jdbc/problemDB"
    	slickProfileClassName = "slick.jdbc.MySQLProfile$"
      }
    }

  dashboard {
    happyBaseUrl = "https://localhost:6443/shrine/rest/happy"
    statusBaseUrl = "https://localhost:6443/shrine/rest/internalstatus"

    database {
      dataSourceFrom = "JNDI"
      jndiDataSourceName = "java:comp/env/jdbc/problemDB"
      slickProfileClassName = "slick.jdbc.MySQLProfile$"
    }
  } //end dashboard

    status {
      permittedHostOfOrigin = "localhost"
    }

    squerylDataSource {
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/shrineDB"
      }
    }

    authenticate {
      usersource {
        domain = "i2b2demo"
      }
    }

  steward {
    createTopicsMode = Approved

    emailDataSteward {
      sendAuditEmails = false  //false to turn off the whole works of emailing the data steward      //interval = "1 day" //Audit researchers daily
      //timeAfterMidnight = "6 hours" //Audit researchers at 6 am. If the interval is less than 1 day then this delay is ignored.
      //maxQueryCountBetweenAudits = 30 //If a researcher runs more than this many queries since the last audit audit her
      //minTimeBetweenAudits = "30 days" //If a researcher runs at least one query, audit those queries if this much time has passed
 
      //You must provide the email address of the shrine node system admin, to handle bounces and invalid addresses
      //from = "shrine-admin@example.com"
      //You must provide the email address of the data steward
      //to = "shrine-steward@example.com"
 
      //subject = "Audit SHRINE researchers"
      //The baseUrl for the data steward to be substituted in to email text. Must be supplied if it is used in the email text.
      //stewardBaseUrl = "https://example.com:6443/steward/"
      //externalStewardBaseUrl = "https://example.com:6443/steward/"
 
      //Text to use for the email audit.
      //AUDIT_LINES will be replaced by a researcherLine for each researcher to audit.
      //STEWARD_BASE_URL will be replaced by the value in stewardBaseUrl if available.
      //emailBody = """Please audit the following users at STEWARD_BASE_URL at your earliest convinience: AUDIT_LINES"""
      //note that this can be a multiline message
 
      //Text to use per researcher to audit.
      //FULLNAME, USERNAME, COUNT and LAST_AUDIT_DATE will be replaced with appropriate text.
      //researcherLine = "FULLNAME (USERNAME) has run COUNT queries since LAST_AUDIT_DATE."
    }

    database {
      dataSourceFrom = "JNDI"
      jndiDataSourceName = "java:comp/env/jdbc/stewardDB"
      slickProfileClassName = "slick.jdbc.MySQLProfile$"
    }
  } // end steward

  email {
  }
} // end shrine section

...

 

Code Block
languagesql
themerdark
bash-4.1$ psql
postgres=# \c i2b2pm
i2b2pm=# \d+ pm_user_login
                           Table "public.pm_user_login"
    Column     |            Type             | Modifiers | Storage  | Description
---------------+-----------------------------+-----------+----------+-------------
 user_id       | character varying(50)       | not null  | extended |
 attempt_cd    | character varying(50)       | not null  | extended |
 entry_date    | timestamp without time zone | not null  | plain    |
 changeby_char | character varying(50)       |           | extended |
 status_cd     | character varying(50)       |           | extended |
Indexes:
    "pm_user_login_pkey" PRIMARY KEY, btree (entry_date, user_id)
Has OIDs: no
 
i2b2pm=# ALTER TABLE "pm_user_login" DROP CONSTRAINT "pm_user_login_pkey" ;
ALTER TABLE
 
i2b2pm=# \d+ pm_user_login
                           Table "public.pm_user_login"
    Column     |            Type             | Modifiers | Storage  | Description
---------------+-----------------------------+-----------+----------+-------------
 user_id       | character varying(50)       | not null  | extended |
 attempt_cd    | character varying(50)       | not null  | extended |
 entry_date    | timestamp without time zone | not null  | plain    |
 changeby_char | character varying(50)       |           | extended |
 status_cd     | character varying(50)       |           | extended |
Has OIDs: no

 

Allow for Many More Types of Status from the i2b2 CRC

Change the shrine_query_history's QUERY_RESULT's status column's type from an enum to a text field to accommodate many more types from the i2b2 CRC. This will allow some results previously interpreted as errors to be interpreted as QUEUED. See SHRINE-2715.

 

For Mysql:

 

Code Block
languagesql
themerdark
mysql> use shrine_query_history;
mysql> alter table QUERY_RESULT change status status varchar(30) not null;

 

 

For Oracle:

 

Code Block
languagesql
themerdark
-- To find the constraint name on the status column:
SELECT COLUMN_NAME,CONSTRAINT_NAME,TABLE_NAME FROM user_cons_columns WHERE TABLE_NAME = 'QUERY_RESULT';
-- To drop that constraint:
ALTER TABLE QUERY_RESULT DROP CONSTRAINT <constraint_name_for_status>;

 

 

For MS SQL Server:

 

Code Block
languagesql
themerdark
USE shrine_query_history;
  
-- To find the constraint name on the status column:
 
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME= 'QUERY_RESULT';
 
-- To drop that constraint:
 
ALTER TABLE QUERY_RESULT DROP CONSTRAINT <constraint_name_for_status>;

 

 

...

You will need to add the line “dist/shrine.bundle.js” and remove or comment out the other three js files.

Sample SHRINE configuration file (for a downstream node)

Code Block
languagebash
themeRDark
titleshrine.conf
collapsetrue
shrine {
  pmEndpoint {
    url = "http://i2b2_node_url:9090/i2b2/services/PMService/getServices"
  }
  ontEndpoint {
    url = "http://i2b2_node_url:9090/i2b2/services/OntologyService"
  }
  
  hiveCredentials {
    domain = "i2b2demo"
    username = "demo"
    password = "demouser"
    crcProjectId = "Demo"
    ontProjectId = "SHRINE"
  }

  messagequeue {
    blockingq {
        serverUrl = "https://shrine_hub_url:6443/shrine-metadata/mom"
    }
  }
  
  breakdownResultOutputTypes {
    PATIENT_AGE_COUNT_XML {
      description = "Age patient breakdown"
    }
    PATIENT_RACE_COUNT_XML {
      description = "Race patient breakdown"
    }
    PATIENT_VITALSTATUS_COUNT_XML {
      description = "Vital Status patient breakdown"
    } 
    PATIENT_GENDER_COUNT_XML {
      description = "Gender patient breakdown"
    }
  }

  queryEntryPoint {
    create = true
    audit {
      collectQepAudit = false
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/qepAuditDB"
        slickProfileClassName = "slick.jdbc.MySQLProfile$"
      }
    }
      
    trustModelIsHub = true
    attachSigningCert = true
    authenticationType = "pm"
    authorizationType = "shrine-steward"

    shrineSteward {
      qepUserName = "qep"
      qepPassword = "trustme"
      stewardBaseUrl = "https://localhost:6443"
    }

      includeAggregateResults = false
      
      maxQueryWaitTime {
        minutes = 5
      }

    broadcasterServiceEndpoint {
        url = "https://shrine_hub_url:6443/shrine/rest/broadcaster/broadcast"
    }
  } //end queryEntryPoint

  adapter {
    create = true
    audit {
      collectAdapterAudit = false
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/adapterAuditDB"
        slickProfileClassName = "slick.jdbc.MySQLProfile$" 
      }
    }

    crcEndpoint {
      url = "http://i2b2_node_url:9090/i2b2/services/QueryToolService"
    }

    adapterLockoutAttemptsThreshold = 0
    setSizeObfuscation = true
    adapterMappingsFileName = "AdapterMappings.csv"

    maxSignatureAge {
      minutes = 5
    }

    immediatelyRunIncomingQueries = true

  } // end adapter

    networkStatusQuery = "\\\\SHRINE\\SHRINE\\Demographics\\Gender\\Male\\"
    humanReadableNodeName = "Harvard Test Node"
    shrineDatabaseType = "mysql"

    keystore {
      file = "/opt/shrine/shrine.keystore"
      password = "password"
      privateKeyAlias = "privateKeyAlias"
      keyStoreType = "JKS"
      caCertAliases = ["shrine-hub-ca"]
    }

    problem {
      problemHandler = "net.shrine.problem.LogAndDatabaseProblemHandler$"
      database {
    	dataSourceFrom = "JNDI"
    	jndiDataSourceName = "java:comp/env/jdbc/problemDB"
    	slickProfileClassName = "slick.jdbc.MySQLProfile$"
      }
    }

  dashboard {
    happyBaseUrl = "https://localhost:6443/shrine/rest/happy"
    statusBaseUrl = "https://localhost:6443/shrine/rest/internalstatus"

    database {
      dataSourceFrom = "JNDI"
      jndiDataSourceName = "java:comp/env/jdbc/problemDB"
      slickProfileClassName = "slick.jdbc.MySQLProfile$"
    }
  } //end dashboard

    status {
      permittedHostOfOrigin = "localhost"
    }

    squerylDataSource {
      database {
        dataSourceFrom = "JNDI"
        jndiDataSourceName = "java:comp/env/jdbc/shrineDB"
      }
    }

    authenticate {
      usersource {
        domain = "i2b2demo"
      }
    }

  steward {
    createTopicsMode = Approved 

    emailDataSteward {
      sendAuditEmails = false  //false to turn off the whole works of emailing the data steward      //interval = "1 day" //Audit researchers daily
      //timeAfterMidnight = "6 hours" //Audit researchers at 6 am. If the interval is less than 1 day then this delay is ignored.
      //maxQueryCountBetweenAudits = 30 //If a researcher runs more than this many queries since the last audit audit her
      //minTimeBetweenAudits = "30 days" //If a researcher runs at least one query, audit those queries if this much time has passed
  
      //You must provide the email address of the shrine node system admin, to handle bounces and invalid addresses
      //from = "shrine-admin@example.com"
      //You must provide the email address of the data steward
      //to = "shrine-steward@example.com"
  
      //subject = "Audit SHRINE researchers"
      //The baseUrl for the data steward to be substituted in to email text. Must be supplied if it is used in the email text.
      //stewardBaseUrl = "https://example.com:8443/steward/"
  
      //Text to use for the email audit.
      //AUDIT_LINES will be replaced by a researcherLine for each researcher to audit.
      //STEWARD_BASE_URL will be replaced by the value in stewardBaseUrl if available.
      //emailBody = """Please audit the following users at STEWARD_BASE_URL at your earliest convinience: AUDIT_LINES"""
      //note that this can be a multiline message
  
      //Text to use per researcher to audit.
      //FULLNAME, USERNAME, COUNT and LAST_AUDIT_DATE will be replaced with appropriate text.
      //researcherLine = "FULLNAME (USERNAME) has run COUNT queries since LAST_AUDIT_DATE."
    }

    database {
      dataSourceFrom = "JNDI"
      jndiDataSourceName = "java:comp/env/jdbc/stewardDB"
      slickProfileClassName = "slick.jdbc.MySQLProfile$"
    }
  } // end steward

  email {
  }
} // end shrine section

 

Configure support for client-side https Proxies (i.e, UCSD's infrastructure)

 

Configure support for client-side https Proxies (i.e, UCSD's infrastructure)

Set Java system properties to use Set Java system properties to use a client-side https proxy. In /opt/shrine/tomcat/bin/setenv.sh , add values for http.proxyHost and http.proxyPort to the export CATALINA_OPTS="" 
 

Code Block
languagebash
themerdark
export CATALINA_OPTS="-Dhttp.proxyHost=yourProxyHost -Dhttp.proxyPort=yourProxyHostPort"
Info
titleNote

Please note, if you are not running a client-side proxy, you can skip this section!

 

Start SHRINE

...