Copy of Embedding Kuali Rice

Overview

Running a Rice client application in Embedded Mode means:

  • one or more Rice modules - in particular, KEW and KIM - is executing from within the application
  • the client application has direct access to the Rice Standalone Server database

Access to the Rice Database

A Rice client application requires three schemas:

  1. A schema that backs the Rice Standalone Server - generally referred to as the Rice database. The client application uses this schema to store all KEW transactions and expose services on the KSB registry.
  2. A Rice-provisioned schema for accessing the Rice database through a role with appropriate permissions (e.g. CRUD on KEW tables, but read-only on KNS tables). Because Rice is "schema-unaware", private synonyms pointing to the objects in the Rice database are created in this schema.
  3. A schema that backs the Rice client tables. This is generally hosted in the client application's database. It is used primarily for managing local Rice related Quartz jobs and thus, does not require access to any other schema.

Prerequisites

  1. A database account with access to the Rice database
  2. LDAP Service Accounts on ldap.ucdavis.edu for dc=ucdavis,dc=edu and dc=it,dc=ucdavis,dc=edu trees.
  3. Procure the UC Davis-specific rice-api and rice-impl JARs and all transitive dependencies using either of the following methods:
    • Download ucd-rice-standalone-server-impl WAR from Artifactory . This WAR contains all dependencies.
    • Maven users: Add ucd-rice-impl as a dependency in your project (most likely the root POM).
      pom.xml
      <repositories>
          <repository>
              <id>ucd-maven</id>
              <name>UCD Maven Repository</name>
      	<url>http://maven.ucdavis.edu/repo</url>
          </repository>  
      </repositories>
      
      <properties>
          <ucd-rice-impl.version>[some UCD Rice Implementation version]</ucd-rice-impl.version>
      </properties>
      
      <dependencies>
          <dependency>
              <groupId>edu.ucdavis.kuali.rice</groupId>
              <artifactId>ucd-rice-impl</artifactId>
              <version>${ucd-rice-impl.version}</version>               
          </dependency>	
      </dependencies>
      

Properties Configuration

We use a simple XML configuration to declare properties as key-value pairs. For example:

/usr/local/rice/rice-config.xml
<config>
    <param name="datasource.ojb.platform">Oracle</param>
    <param name="datasource.platform">org.kuali.rice.core.database.platform.OraclePlatform</param>
    <param name="datasource.url">jdbc:oracle:thin:@dbhost.ucdavis.edu:1521:SID</param>
    <param name="datasource.driver.name">oracle.jdbc.driver.OracleDriver</param>
    <param name="datasource.pool.validationQuery">select 1 from duak</param>
    <param name="datasource.pool.maxWait">30000</param>
    <param name="datasource.pool.size">30</param>
    <param name="datasource.pool.maxActive">50</param>
    <param name="datasource.minIdle">7</param>
    <param name="datasource.initialSize">7</param>
    <param name="datasource.accessToUnderlyingConnectionAllowed">true</param>
    <param name="datasource.username">my_db_user</param>
    <param name="datasource.password">my_db_password</param>
<config>

Configuration File Options

  • Default Rice Configuration
    • By default Rice looks for rice-config.xml in /usr/local/rice/ at launch time. Externalizing the configuration out to the file system allows us to substitute different values for different properties in different environments. We don't need to create a configuration file for say, the TEST vs. the PROD environment, and then build the application (i.e. the same WAR can be deployed in any instance).
    • See a full-blown set of sample properties .
  • Other Kuali Application Configurations
    • Kuali COEUS

Core Data Source Configuration

Kuali Rice uses Java Open Transaction Manager, so we declare the appropriate beans.

classpath:edu/ucdavis/myapp/config/application-data.xml
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">
    <property name="defaultTimeout" value="${transaction.timeout}"/>
</bean>
	
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="jotm"/>
    <property name="userTransaction" ref="jotm"/>
</bean>

We must declare three data sources:

  1. A transactional data source where the local client application's Rice tables are located. This is required by JOTM.
    classpath:edu/ucdavis/myapp/config/application-data.xml
    <bean id="dataSource" class="org.kuali.rice.core.database.XAPoolDataSource">
        <property name="transactionManager" ref="jotm" />
        <property name="driverClassName" value="${datasource.driver.name}" />
        <property name="url" value="${datasource.url}" />
        <property name="maxSize" value="${datasource.pool.size}" />
        <property name="minSize" value="${datasource.initialSize}" />
        <property name="maxWait" value="${datasource.pool.maxWait}" />
        <property name="validationQuery" value="${datasource.pool.validationQuery}" />
        <property name="username" value="${datasource.username}" />
        <property name="password" value="${datasource.password}" />
    </bean>
    
  2. A non-transactional data source pointing to those same Rice tables. This is required by Quartz.
    classpath:edu/ucdavis/myapp/config/application-data.xml
    <bean id="nonTransactionalDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="url" value="${datasource.url}"/>
        <property name="username" value="${datasource.username}"/>
        <property name="password" value="${datasource.password}"/>
        <property name="driverClassName" value="${datasource.driver.name}" />
        <property name="initialSize" value="${datasource.initialSize}" />
        <property name="minIdle" value="${datasource.minIdle}" />
        <property name="maxActive" value="${datasource.maxActive}" />
        <property name="maxWait" value="${datasource.maxWait}" />
        <property name="validationQuery" value="${datasource.validationQuery}" />
        <property name="testOnBorrow" value="${datasource.testOnBorrow}" />
        <property name="testOnReturn" value="${datasource.testOnReturn}" />
        <property name="testWhileIdle" value="${datasource.testWhileIdle}" />
        <property name="accessToUnderlyingConnectionAllowed" value="${datasource.accessToUnderlyingConnectionAllowed}" />
    </bean>
    

    To take advantage of pooling capabilities, testOnBorrow should be set to true.

  3. A transactional data source pointing to the database of the Rice Standalone Server.
    classpath:edu/ucdavis/myapp/config/application-data.xml
    <bean id="standaloneDataSource" class="org.kuali.rice.core.database.XAPoolDataSource">
        <property name="transactionManager" ref="jotm" />
        <property name="driverClassName" value="${standalone.datasource.driver.name}" />
        <property name="url" value="${standalone.datasource.url}" />
        <property name="maxSize" value="${standalone.datasource.pool.size}" />
        <property name="minSize" value="${standalone.datasource.initialSize}" />
        <property name="maxWait" value="${standalone.datasource.pool.maxWait}" />
        <property name="validationQuery" value="${standalone.datasource.pool.validationQuery}" />
        <property name="username" value="${standalone.datasource.username}" />
        <property name="password" value="${standalone.datasource.password}" />
    </bean>
    

KIM Service Configuration

The UCD KIM Identity Service fetches Entity and Principal information from UCD LDAP and, optionally, Display Name from White Pages. It is instantiated by declaring classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kim-wp-service.xml if using White Pages, or classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kim-service.xml if not using White Pages, in the Spring context.

Data Source Configuration

KIM Identity Service requires two LDAP data sources:

  1. A data source pointing to the dc=ucdavis,dc=edu tree to retrieve entries in the ou=People and ou=Listings schemas.
    classpath:edu/ucdavis/myapp/config/application-data.xml
    <bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="url" value="${ldap.url}" />
        <property name="base" value="${ldap.base}" />
        <property name="userDn" value="${ldap.user}" />
        <property name="password" value="${ldap.password}" />
        <property name="pooled" value="false" />
    </bean>
    
  2. A data source pointing to the dc=it,dc=ucdavis,dc=edu tree server to retrieve entries in the ou=Accounts schema.
    classpath:edu/ucdavis/myapp/config/application-data.xml
    <bean id="ldapItContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="url" value="${ldap.it.url}" />
        <property name="base" value="${ldap.it.base}" />
        <property name="userDn" value="${ldap.it.user}" />
        <property name="password" value="${ldap.it.password}" />    	
        <property name="pooled" value="false" />
    </bean>
    

Optionally, KIM Identity Service provides access to the PEOPLE_DISPLAY_NAME view in the ORG schema in Mothra. whitePagesDataSource

classpath:edu/ucdavis/myapp/config/application-data.xml
<bean id="whitePagesDataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="url" value="${whitepages.datasource.url}"/>
    <property name="username" value="${whitepages.datasource.username}"/>
    <property name="password" value="${whitepages.datasource.password}"/>
    <property name="driverClassName" value="${whitepages.datasource.driver.name}" />
    <property name="initialSize" value="${whitepages.datasource.initialSize}" />
    <property name="minIdle" value="${whitepages.datasource.minIdle}" />
    <property name="maxActive" value="${whitepages.datasource.maxActive}" />
    <property name="maxWait" value="${whitepages.datasource.maxWait}" />
    <property name="validationQuery" value="${whitepages.datasource.validationQuery}" />
    <property name="testOnBorrow" value="${whitepages.datasource.testOnBorrow}" />
    <property name="testOnReturn" value="${whitepages.datasource.testOnReturn}" />
    <property name="testWhileIdle" value="${whitepages.datasource.testWhileIdle}" />
    <property name="accessToUnderlyingConnectionAllowed" value="${whitepages.datasource.accessToUnderlyingConnectionAllowed}" />
</bean>

To take advantage of pooling capabilities, testOnBorrow should be set to true.

KEW Service Configuration

As of 1.0.1.1-UCD-SR1d, Rice applications will no longer encrypt workflow document content. This is accomplished by disabling encryption using the out-of-the-box non-encryption implementation (org.kuali.rice.core.service.impl.NoEncryptionEncryptionServiceImpl). It is instantiated by declaring classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kew-service.xml in the Spring context.

Consequently, the encryption.key property is no longer required.

KNS Service Configuration

  1. Maintenance Document Encryption
    • As of 1.0.1.1-UCD-SR1d, Rice applications will no longer encrypt maintenance document content.
    • This is accomplished by disabling encryption using the out-of-the-box non-encryption implementation (org.kuali.rice.core.service.impl.NoEncryptionEncryptionServiceImpl).
    • Disable encryption by declaring the classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kns-service.xml Spring file (see UCD Spring Bean Configuration).
    • Remove (or comment out) references to the encryption.key property (e.g. in rice-config.xml, kc-config.xml, embedded-client-config.xml, etc.).
  2. Configure Rice Application Configuration Service
    • A client application must declare which package prefixes it is responsible for servicing.
    • If not, then it will by default, try to handle requests over the service bus for Rice objects (those prefixed with org.kuali.rice).
    • The application.url needs to be set such that the requester knows which server is handling the request.
    • Override the Rice Application Configuration Service like so:
      my-rice-config.xml
      <param name="application.url">https://myappserver.ucdavis.edu/</param>
      
      myRiceSpringBeans.xml
      <bean id="riceApplicationConfigurationService" class="org.kuali.rice.kns.service.impl.RiceApplicationConfigurationServiceImpl">
          <property name="packagePrefixes">
              <list>
                  <value>edu.ucdavis.myapplicationprefix</value>
              </list>
          </property>	
      </bean>
      

UCD Spring Bean Configuration

Declare the UCD-implemented Rice services using either of the following methods:

  1. Declare them as part of the rice.additionalSpringFiles property and pass that as a token into the rice bean
    /usr/local/rice/rice-config.xml
    <param name="rice.additionalSpringFiles">classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kim-service.xml,classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kew-service.xml,classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kns-service.xml</param>
    
    classpath:edu/ucdavis/myapp/config/rice-common.xml
    <bean id="rice" class="org.kuali.rice.core.config.RiceConfigurer">
    ...
        <property name="additionalSpringFiles">
            <value>${rice.additionalSpringFiles}</value>
        </property>
    ...
    </bean>
    
  2. Declare them directly in the rice bean using the additionalSpringFiles property (see Rice Bean Configuration)
    classpath:edu/ucdavis/myapp/config/rice-common.xml
    <bean id="rice" class="org.kuali.rice.core.config.RiceConfigurer">
    ...
        <property name="additionalSpringFiles">
            <list>
                ...
                <value>classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kim-service.xml</value>
                <value>classpath:edu/ucdavis/kuali/rice/kew/config/ucd-kew-service.xml</value>
                <value>classpath:edu/ucdavis/kuali/rice/kns/config/ucd-kns-service.xml</value>
                ...
            </list>
        </property>
    ...
    </bean>
    
  3. If you're using Spring's ContextLoaderListener, declare them in web.xml
    src/main/webapp/WEB-INF/web.xml
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            ...
            classpath:edu/ucdavis/kuali/rice/kim/config/ucd-kim-service.xml
            classpath:edu/ucdavis/kuali/rice/kew/config/ucd-kew-service.xml
            classpath:edu/ucdavis/kuali/rice/kns/config/ucd-kns-service.xml
            ...
        </param-value>
    </context-param>
    

Rice Bean Configuration

Finally, we declare the rice bean and inject all of the core data source beans into it along with any required additional Spring files.

classpath:edu/ucdavis/myapp/config/rice-common.xml
<bean id="rice" class="org.kuali.rice.core.config.RiceConfigurer">
    <property name="dataSource" ref="dataSource" />
    <property name="nonTransactionalDataSource" ref="nonTransactionalDataSource"/>
    <property name="serverDataSource" ref="standaloneDataSource"/>
    <property name="transactionManager" ref="jotm" />
    <property name="userTransaction" ref="jotm" />
    <property name="serviceNamespace" value="${service.namespace}" />
    <property name="environment" value="${environment}" />
    <property name="rootConfig" ref="config" />
    <property name="ksbConfigurer">
        <bean class="org.kuali.rice.ksb.messaging.config.KSBConfigurer">
            <property name="serviceServletUrl" value="${serviceServletUrl}" />
        </bean>
    </property>
    <property name="kewConfigurer">
        <bean class="org.kuali.rice.kew.config.KEWConfigurer">
            <property name="clientProtocol" value="local" />
        </bean>
    </property>
    <property name="knsConfigurer">
        <bean class="org.kuali.rice.kns.config.KNSConfigurer"/>
    </property>
    <property name="kimConfigurer">
        <bean class="org.kuali.rice.kim.config.KIMConfigurer"/>
    </property>
    <property name="kcbConfigurer">
        <bean class="org.kuali.rice.kcb.config.KCBConfigurer"/>
    </property>
    <property name="additionalSpringFiles">
        <value>${rice.additionalSpringFiles}</value>
    </property>
</bean>