Versions Compared

Key

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

...

To get the attributes into an IPerson object use the new (as of uP 2.5) setAttributes method:

Code Block
/**
 * Associates attributes with the user
 * @param attrs
 */
public void setAttributes (Map attrs);

...

PersonDirectory is implemented using Spring. Currently a Spring beans.dtd-compliant XML file named personDirectoryContext.xml declares the configuration of an instance of IPersonAttributeDao. The class PersonDirectory delegates to this Spring-configured IPersonAttributeDao instance to actually implement the PersonDirectory behavior. PersonDirectory uses PortalApplicationContextFacade to access the the uPortal Spring application context.

JDBC Example

The default personDirectoryContext.xml that ships with uPortal declares that the IPersonAttributeDao we want to use is the LegacyPersonAttributeDao, which parses and instantiates the "recipe" given in PersonDirs.xml.includes JDBC beans to retrieve attributes for local uPortal usres such as fragment owners.  Below is an example of merging in additional attributes via the PersonDb DataSource.   Configuration supports mapping a column to multiple uPortal attribute names and using DataSources other than those configured in RDBMServices.

Code Block
xml
xml
<beans>
    <bean id="personAttributeDao" class="org.jasig.portal.services.persondir.support.legacy.LegacyPersonAttributeDao">
        <!-- the legacy implementation takes no configuration -->
    </bean>
</beans>
Note
titleExample disclaimer

While these examples conform to beans.dtd, they haven't necessarily been actually run in uPortal instances, so these XMLs might not actually work as is. If you find anything wrong with these example XMLs, please either fix them if you feel comfortable or else comment on this page so that they can be fixed. Thanks!

JDBC Example

Here's an example of using Spring to wire together a JdbcPersonAttributeDaoImpl that implements IPersonAttributeDao by querying a JDBC attribute store. The database used is that managed by RDBMServices under the name "personDb". We configure also the SQL query we'll use to get attributes for the user and the mapping from column names to uPortal attribute names. Configuration supports mapping a column to multiple uPortal attribute names and using DataSources other than those configured in RDBMServices.

Code Block
xmlxml

<beans>
    <!-- this is the key bean, with the special id "personAttributeDao" that PersonDirectory is looking for. -->
    <bean id="personAttributeDao"
        class="org.jasig.portal.services.persondir.support.JdbcPersonAttributeDaoImpl">
                        <!-- the JDBC implementation takes two arguments in its constructor.
                              the first is a DataSource -->
        <constructor-arg>
             <!-- here we're using the default DataSource from RDBMServices. -->
            <bean
                class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                <property name="staticMethod" value="org.jasig.portal.RDBMServices.getDataSource"/>
            </bean>
        </constructor-arg>
            <!-- the second constructor argument to the JDBC implementation is the SQL
              query that will yield a single row.  The ? will be replaced with the
              userid about whom we are querying -->
        <constructor-arg>
            <value>SELECT name, shirt_color FROM someschema.sometable
                WHERE uid = ?</value>
        </constructor-arg>
<bean id="myunivCachingPersonDbJdbcAttributeSource">
        <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />
        <property name="cacheNullResults" value="true" />
        <property name="userInfoCache">
            <bean>
                <property name="cacheFactory" ref="cacheFactory" />
                <property name="cacheName"
                    value="org.jasig.services.persondir.USER_INFO.myuniv_person_dir" />
            </bean>
        </property>
        <property name="cacheKeyGenerator" ref="userAttributeCacheKeyGenerator" />
        <property name="cachedPersonAttributesDao">
            <bean class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">   >
                <constructor-arg index="0" ref="PersonDB" />
                <constructor-arg>
                    <value>
                        SELECT DISTINCT first_name||' '||Last_name first_last, role,
                        contentGroup, person_type, first_name, last_name, middle_name,
                        email_alias, college, class_year, student_status, alias,
                        work_phone, netid
                        FROM person_directory_view where {0}
                    </value>
                </constructor-arg>
                <property name="usernameAttributeProvider" ref="usernameAttributeProvider" />    
                <!-- Map the table fields to P3P attribute names -->
                <property name="queryAttributeMapping">
                    <map>
                        <entry key="displayName" value="FIRST_LAST" />
                        <entry key="sn" value="LAST_NAME" />
                        <entry key="contentGroup" value="CONTENT_GROUP" />
                        <entry key="mail" value="EMAIL_ALIAS" />
                        <entry key="givenName" value="FIRST_NAME" />
                        <entry key="alias" value="ALIAS" />
                        <entry key="personType" value="PERSON_TYPE" />
                        <entry key="College" value="COLLEGE" />
                        <entry key="ClassYear" value="CLASS_YEAR" />
                        <entry key="StudentStatus" value="STUDENT_STATUS" />
                        <entry key="username" value="NETID" />
                        <entry key="WorkPhone" value="WORK_PHONE" />
                    </map>
                </property>
                <!-- Map the table fields to P3P attribute names -->
                <property name="resultAttributeMapping">
                    <map>
                        <entry key="FIRST_LAST">
                            <value>displayName</value>
                        </entry>
                        <entry key="LAST_NAME">
                            <set>
                                <value>sn</value>
                                <value>user.name.family</value>
                            </set>
                        </entry>
                        <entry key="ROLE">
                            <value>uPortalAffiliation</value>
                        </entry>
                        <entry key="CONTENTGROUP">
                            <set>
                                <value>contentGroup</value>
                            </set>
                        </entry>
                        <entry key="EMAIL_ALIAS">
                            <set>
                                <value>mail</value>
                                <value>user.home-info.online.email</value>
                            </set>
                        </entry>
                        <entry key="FIRST_NAME">
                            <value>givenName</value>
                        </entry>
                        <entry key="ALIAS">
                            <value>alias</value>
                        </entry>
                        <entry key="PERSON_TYPE">
                            <value>personType</value>
                        </entry>
                        <entry key="COLLEGE">
                            <value>College</value>
                        </entry>
                        <entry key="CLASS_YEAR">
                            <value>ClassYear</value>
                        </entry>
                        <entry key="STUDENT_STATUS">
                            <value>StudentStatus</value>
                        </entry>
                        <entry key="NETID">
                            <set>
                                <value>uid</value>
                                <value>netid</value>
                                <value>username</value>
                                <value>eduPersonPrincipalName</value>
                                <value>user.login.id</value>
                            </set>
                        </entry>
                        <entry key="WORK_PHONE">
                            <value>WorkPhone</value>
                        </entry>
                    </map>
                </property>
            </bean>
        </property>
    </bean>

For more examples, visit the page dedicated to JdbcPersonAttributeDaoImpl.

LDAP example

In this example we implement IPersonAttributeDao using an LdapPersonAttributeDaoImpl.

Here we use the ILdapServer named "personLdap" managed by LdapServices. We configure the map from LDAP attribute names to uPortal attribute names and the query we'll use to look up the user. Advanced configuration allows mapping LDAP attribute names to multiple uPortal attribute names.

Code Block
xml
xml

<beans>
    <bean id="personDirectory"
        class="org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl">
        <property name="ldapAttributesToPortalAttributes">
 <!-- the JDBC implementation has one other requirement: a Map  <map>
             from column names in the ResultSet to uPortal IPerson attribute names. --><entry key="name">
               <property name="columnsToAttributes">    <value>name</value>
        <map>        </entry>
                <entry key="nameshirt_color">
                    <value>name<<value>shirtColor</value>
                </entry>
            </map>
   <entry key="shirt_color">    </property>
        <property name="ldapServer">
      <value>shirtColor</value>      <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         </entry>       <property name="staticMethod">
    </map>         </property>     </bean>
</beans>

For more examples, visit the page dedicated to JdbcPersonAttributeDaoImpl.

LDAP example

In this example we implement IPersonAttributeDao using an LdapPersonAttributeDaoImpl.

Here we use the ILdapServer named "personLdap" managed by LdapServices. We configure the map from LDAP attribute names to uPortal attribute names and the query we'll use to look up the user. Advanced configuration allows mapping LDAP attribute names to multiple uPortal attribute names.

Code Block
xmlxml

<beans>
    <bean id="personDirectory" <value>org.jasig.portal.ldap.LdapServices.getLdapServer</value>
                </property>
        class="org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl">         <property name="ldapAttributesToPortalAttributesarguments">
            <map>        <list>
        <entry key="name">                <value>personLdap</value>
      <value>name</value>
                </entry>list>
                <entry key="shirt_color"></property>
            </bean>
        <value>shirtColor<</value>property>
        <property name="uidQuery">
      </entry>             </map><value>(cn={0})</value>
        </property>
    </bean>
   <property name="ldapServer"></beans>

Request Attribute Filter Example

The Request Attribute Filter is designed for use with Shibboleth. For a complete discussion of configuring uPortal for Shibboleth, see Shibboleth.  The following example shows a use of the RequestAttributeSourceFilter to retrieve the serverName attribute.  In a real life scenario you would want to retrieve person attributes provided in the request.

Code Block
langxml
    <!--
     | Servlet filter <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBeanthat creates an attribute for the serverName
     +-->
    <bean id="requestAttributeSourceFilter" class="org.jasig.services.persondir.support.web.RequestAttributeSourceFilter">
                <property name="additionalDescriptors" ref="staticMethodrequestAdditionalDescriptors" />
        <property name="serverNameAttribute" value="serverName" />
       <value>org.jasig.portal.ldap.LdapServices.getLdapServer</value>
                </property>
                <property name="argumentsprocessingPosition"> value="BOTH" />
                  <list>
                        <value>personLdap</value>
        </bean>

Merging example

This would get pretty boring if we could only ever have one source of user attributes at a time. MergingPersonAttributeDaoImpl merges attributes from multiple sources.

Here we're merging together attributes from a JDBCPersonAttributeDaoImpl and from an LdapPersonAttributeDaoImpl. Here we've accepted the default merge strategy, but MergingPersonAttributeDaoImpl is configurable to accept alternative merge strategies. MergingPersonAttributeDaoImpl can also be configured as to how it should handle exceptions thrown by the DAOs it is merging.

Code Block
xml
xml

<beans>
    <bean id="personAttributeDao"
           </list>class="org.jasig.portal.services.persondir.support.MergingPersonAttributeDaoImpl">
        <property name="personAttributeDaos">
            <list>
     </property>           <bean
 </bean>         </property>         <property nameclass="uidQueryorg.jasig.portal.services.persondir.support.JdbcPersonAttributeDaoImpl">
            <value>(cn={0})</value>        <constructor-arg>
   </property>     </bean> </beans> 

Request Attribute Filter Example

The Request Attribute Filter is designed for use with Shibboleth. For a complete discussion of configuring uPortal for Shibboleth, see Shibboleth.  The following example shows a use of the RequestAttributeSourceFilter to retrieve the serverName attribute.  In a real life scenario you would want to retrieve person attributes provided in the request.

Code Block
langxml
    <!--      | Servlet filter that creates an attribute for the serverName <bean
                  +-->     <bean id="requestAttributeSourceFilter" class="org.jasigspringframework.servicesjdbc.persondir.support.web.RequestAttributeSourceFilterdatasource.DriverManagerDataSource">
		         <property name="additionalDescriptors" ref="requestAdditionalDescriptors" />driverClassName"><value>${jdbc.driverClassName}</value></property>
		         <property name="serverNameAttribute" value="serverName" />url"><value>${jdbc.url}</value></property>
		         <property name="username"><value>${jdbc.username}</value></property>
		         <property name="processingPosition" value="BOTH" />password"><value>${jdbc.password}</value></property>
	               </bean>

Merging example

This would get pretty boring if we could only ever have one source of user attributes at a time. MergingPersonAttributeDaoImpl merges attributes from multiple sources.

Here we're merging together attributes from a JDBCPersonAttributeDaoImpl and from an LdapPersonAttributeDaoImpl. Here we've accepted the default merge strategy, but MergingPersonAttributeDaoImpl is configurable to accept alternative merge strategies. MergingPersonAttributeDaoImpl can also be configured as to how it should handle exceptions thrown by the DAOs it is merging.

Code Block
xmlxml

<beans>
                    </constructor-arg>
                    <constructor-arg>
             <bean id="personAttributeDao"         class="org.jasig.portal.services.persondir.support.MergingPersonAttributeDaoImpl">
  <value>SELECT name, shirt_color FROM
      <property name="personAttributeDaos">             <list>        someschema.sometable WHERE uid = ?</value>
    <bean                </constructor-arg>
    class="org.jasig.portal.services.persondir.support.JdbcPersonAttributeDaoImpl">                <property name="columnsToAttributes">
   <constructor-arg>                     <map>
  <bean                          class="org.springframework.jdbc.datasource.DriverManagerDataSource<entry key="name">
		         <property name="driverClassName"><value>${jdbc.driverClassName}</value></property> 		         <property name="url"><value>${jdbc.url}</value></property> 		         <property name="username"><value>${jdbc.username}</value></property>
		 <value>name</value>
          <property name="password"><value>${jdbc.password}</value></property>
	                  </bean>entry>
                     </constructor-arg>       <entry key="shirt_color">
            <constructor-arg>                    <value>shirtColor</value>
      <value>SELECT name, shirt_color FROM                   </entry>
         someschema.sometable WHERE uid = ?</value>           </map>
         </constructor-arg>           </property>
         <property name="columnsToAttributes">      </bean>
                <bean
 <map>                             <entry key="nameclass="org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl">
                    <property name="ldapAttributesToPortalAttributes">
          <value>name</value>                             </entry><map>
                             <entry key="shirt_colorname">
                                <value>shirtColor<<value>name</value>
                            </entry>
                        </map>    <entry key="shirt_color">
               </property>                 <<value>shirtColor</bean>value>
                <bean            </entry>
        class="org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl">                </map>
    <property name="ldapAttributesToPortalAttributes">               </property>
         <map>           <property name="ldapServer">
                <entry key="name">       <bean
                         <value>name</value>      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                      </entry>      <property name="staticMethod">
                     <entry key="shirt_color">          <value>
                      <value>shirtColor</value>              org.jasig.portal.ldap.LdapServices.getLdapServer</value>
              </entry>              </property>
          </map>                  <property name="arguments">
 </property>                     <property name="ldapServer">         <list>
               <bean                     <value>personLdap</value>
       class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">                         </list>
   <property name="staticMethod">                        </property>
        <value>                </bean>
                    org.jasig.portal.ldap.LdapServices.getLdapServer</value></property>
                    <property name="uidQuery">
        </property>                <value>(cn={0})</value>
            <property name="arguments">                                 <list>
                                    <value>personLdap</value>
                                </list>
                            </property>
                        </bean>
                    </property>
                    <property name="uidQuery">
                        <value>(cn={0})</value>
                    </property>
                </bean>
            </list>
        </property>
    </bean>
</beans>

Spring recap

Now, you might be thinking, "That makes perfect sense to me, I've seen this before because I use Spring for my other applications." If so, this way of configuration might be right for you.

LegacyPersonDirectoryToPersonAttributeDaoAdapter and PersonDirs.xml revisited

But you might be thinking, "That's really complicated. I don't like this. I'd be much happier using the old PersonDirs.xml approach to life." And if that's what you're thinking, LegacyPersonAttributeDao and the default personDirectory.xml configuration will probably be right for you.

Rolling your own

Or you might even be thinking, "I'd really rather just implement IPersonAttributeDao myself."
If you're thinking that, note that you can still use the provided IPersonAttributeDao support classes where they fit in with the particular attribute retrieval strategy you're trying to implement.

Code Block
xmlxml

<beans>
    <bean id="personAttributeDao"</property>
                </bean>
            </list>
        class="edu.youruniv.portal.persondir.CustomPersonAttributeDaoImpl"></property>
    </bean>
</beans>

Custom Java implementation

Warning

Not recommended

...

Rolling your own

If you have special requirements not handled by the Person Directory implementations you can still use the provided IPersonAttributeDao support classes where they fit in with the particular attribute retrieval strategy you're trying to implement.

Code Block
xml
xml

<beans>
    <bean id="personAttributeDao"
        class="edu.youruniv.portal.persondir

...

Note
titleCaching

As of uPortal 2.4.2, caching internal to PersonDirectory was removed. This was because the caching implementation leaked memory.

If you want to re-introduce caching, one way you could accomplish that would be with a caching wrapper. Such a wrapper would implement IPersonAttributeDao and be dependent upon an implementation of the same interface it implements. It would delegate to the underlying implementation, caching the results from its delegate and responding from its cache when possible. This can be a way to trade memory for performance in the case where you know exactly when your underlying attribute store (infrequently) updates.
.CustomPersonAttributeDaoImpl">
    </bean>
</beans>

Custom Java implementation

Warning
titleNot Recommended

Although not recommended it is possible to change the class name in the personDirectory.xml beans declaration to be a custom class of your choice, so long as it implements IPersonAttributeDao. You could then write a custom implementation that does exactly the queries, caching, and any other behavior you need.
<beans>
<!- notice that the bean's class has changed ->
<bean id="personAttributeDao">
<!-- if you're implementing all your configuration directly in the Java, you need not
add any properties here -->
</bean>
</beans>