Providers Upgrade from 2.1.x to 2.2

Here's a quick outline of what's been done so far:

  1. Refactored existing package names to their 2.2 package counterparts
  2. Modified the components.xml in providers to point to the UCD provider beans that Scott developed
  3. Replaced getHibernateTemplate().findByNamedQuery code fragment in the three manager implementations with a Hibernate callback function (see below for details) – then, unmodified this to call getHibernateTemplate.findByNamedQuery without the third set of params.
  4. Temporarily commented out the preformatted query 'findCoursesByCourseTitle' in CourseInfo.hbm.xml, since this is throwing an error and doesn't seem to be used
  5. Temporarily modified the components.xml to ignore the CourseManagementProvider stuff, since this is throwing an error and I want to get the UserDirectoryProvider and GroupProvider working first.
  6. Modified the UserDirectoryProviderServiceImpl.java so that getId() is replaced with getEid() as per the directions in the migration plan provided by the Sakai Foundation
  7. Modified the CourseManagementManagerImpl to user getUserByEid instead of getUser when passing a kerberos id, fixed problem above (now crossed-out)
  8. The following tests now work in test-harness:
    • CourseManagementManagerTest.class
    • GroupManagerTest.class
    • UserDirectoryManagerTest
    • CourseServiceTest.class
  9. Fixed the problem with 'findCourseByCourseTitle' above, now crossed out, refactored the names of the named queries
  10. Created a DataManager interface and DataManagerImpl superclass which the three Manager classes now inherit, this class implements the findByCourse... wrappers for each query, introduces another layer of abstraction around the Hibernate code
  11. Created a new interface and abstract superclass for CourseService: SiteService and SiteServiceImpl – these classes should facilitate a clean request/site creation process.
    • Added new hbm and classes for SiteInfo and MetaData objects
    • Created a simple ProjectService interface and ProjectServiceImpl class
    • Migrated ucd-training-admin tool over to 2.2, changed named to ucd-enterprise-data-tool
    • Began to modify ucd-enterprise-data-tool to handle request/approval process, so it will create Project sites using the ProjectServiceImpl class... next step is to modify CourseServiceImpl to do the same for Course sites
  12. After discussion of 11/17 we've (Thomas, Jon, James) decided to divide the providers implementation from the batching, white list/black list and site management stuff
    • Revision 49, 50, 51 11/19-20: Thomas has created a new project directory under sakai_mini called 'site-management'. For the moment, the ucd-data-enterprise-service will maintain its current name and contain the DAO's and Manager classes to talk to the sakai_external database. (See Thomas' email of 11/20)
    • Revision 52 11/20: Various refactoring in site-management, changes to the DataManager, DataManagerImpl classes, renaming of SiteInfo and implementing classes to reflect the 'CourseRequest' and 'ProjectRequest' convention. Modification of associated hbm files to create a simple joined-subclass relationship among these 'Request' objects. Minor modification to the UserDirectoryProviderServiceImpl to fit with changes made in 2.1.x.
    • Revision 53 11/20: Renamed the provider implementation classes in an effort to be more succinct and precise about what they are implementing – basically, removed the redundant 'service' so it's just the interface + 'Impl'
      • UserDirectoryProviderServiceImpl -> UserDirectoryProviderImpl
      • UserKerberosAuthenticationService -> KerberosAuthenticationService
      • UserKerberosAuthenticationServiceImpl -> KerberosAuthenticationServiceImpl
      • GroupProviderServiceImpl -> GroupProviderImpl
      • CourseManagementProviderServiceImpl -> CourseManagementProviderImpl
    • Revision 54 11/20: Renamed the manager interfaces and their implementing classes in ucd-enterprise-data-service to be more concise
    • Revision 55 11/20: Refactored site-management to handle the changes made in rev 54
    • Revision 56 11/20: Refactored providers to handle the changes made in rev 53,54,55
    • Revision 57 11/20: Moved 'hasCourseInfo' method out of the CourseService and into CourseManager – since all it does is wrap getCourseInfo with a test for whether it's null or not, doesn't make a whole lot of sense to me to call this business logic. Checkin for ucd-enterprise-data-service.
    • Revision 58,59 11/20: Changes to injection throughout site-management, creation of SiteUtils class, substitution for SiteUtils and CourseManager calls where possible, in place of CourseService, to free CourseService up to focus on business logic, rather than pure data access.
    • Revision 60 11/20: Providers checkin for components.xml changes to fit the substitutions in 57,58,59.
    • Revision 61 11/20: Changes throughout the daos to use TERM_CODE rather than TERM_YEAR and TERM_ID grouping. In coordination with database change (by Brian) to include this field in all of the Materialized Views where it's relevant.
    • Revision 62 11/20: Changes to the CourseService to inherit from our local SiteService, AbstractSiteService. Some fixes to the integration test code. NOTE: The inheritance of the Spring injection in AbstractSiteService/CourseService does not seem to be exactly right yet – I'm getting an exception in one of the testcases
    • Revision 74 11/27: Added CourseRequest.java and ProjectService.java under site-management, along with a bunch of revised files.

Thomas' email of 11/20

Today, I committed some more changes to the sakai_mini revisions 49, 50, and 51. I actually got things working at r51. Here are some more details:

  • Both site-management (SM) and ucd-enterprise-data-service (UEDS) have a DataManager. Especially the SM DataManger needs to be cleaned up because it's just a copy of the UEDS one. I guess you can remove all the methods except for two in the SM one.
  • I prepared the SM components.xml file so that it would add the new HBMs to the global session factory. Those specific declarations are commented out for now, but they should be fairly close to a working setup.
  • I left the Utils class in the UEDS to avoid UEDS to SM calls. I also added three methods to the Utils class that are in the CourseService. There is probably more that we can refactor. I haven't replaced any SM calls to CourseService methods that are in Utils now too.
  • I created a new package for the providers in SM so that these classes are not bunched up with all the SM services. We still need to figure out if this is the final location for the providers. I also had to add SM dependencies to the provider component's project.xml file.
  • I am sure that I missed a few things and I haven't fully cleaned everything up yet. But, these latest changes give us the one way dependency SM --> UEDS, which is good software engineering practice, and avoids any hard to deal with circular dependencies.

Issues raised in Nov 13, 2006 Meeting w/ Kirk, Sandra

  1. Status of Melete?
  2. Status of WebDav? – sounds like this is most critical

Future improvements – currently on the back burner

  1. Statistics tool/EventServer plugin will need to be fit into the work effort at some point

Suggestion from Brian - Nov 10, 2006

If possible, it would be nice to switch over to LDAP for PersonInfo rather than using the feed from MOTHRA

  • Brian suggests we get rid of UCDSAKAI_PERSON
  • Possible issue with distauth, pitms. Ideally, we need a cleaner object model – such as might be provided by the CourseManagement work – but it might be possible to attach pitms, etc as properties of the User object and then handle everything in the providers code

Replaced getHibernateTemplate().findByNamedQuery

Nov 14, 2006

After some extensive debugging, we've modified the components.xml file and the findByQuery to use the new best practice referenced below

Replacement code Nov 14
      protected List findByNamedQuery(String queryName, Object[] args) {
		List list = null;
		try {
			Query query = sessionFactory.getCurrentSession().getNamedQuery(queryName);
			for (int i=0;i<args.length;i++) {
				query.setParameter(i, args[i]);
			}
			list  = query.list();
		} catch (DataAccessException dae) {
			LOG.error("Unable to find by named query " + queryName, dae);
		} catch (HibernateException he) {
			LOG.error("Unable to find by named query " + queryName, he);
		} catch (Exception e) {
			LOG.error("Unable to find by named query " + queryName, e);
		}
		return list;
	}
components.xml snip
	<bean id="edu.ucdavis.sakai.transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="edu.ucdavis.sakai.external.sessionFactory" />
		</property>
	</bean>
	

	<bean id="edu.ucdavis.sakai.api.enterprise.manager.DataManagerTarget"
		class="edu.ucdavis.sakai.impl.enterprise.manager.DataManagerImpl"
		singleton="true">
		<property name="sessionFactory">
			<ref local="edu.ucdavis.sakai.external.sessionFactory" />
		</property>
	</bean>

	
	<bean
		id="edu.ucdavis.sakai.api.enterprise.manager.DataManager"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref bean="edu.ucdavis.sakai.transactionManager" />
		</property>
		<property name="target">
			<ref bean="edu.ucdavis.sakai.api.enterprise.manager.DataManagerTarget" />
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>

Nov 14, 2006

Thomas has suggested we modify this to use the new Hibernate 3 contextualized session pattern, which requires some modification to the components.xml file – tried the most straightforward conversion on 11/13 and ran into problems, backed out these changes until we've got more of the big pieces working

Nov 10, 2006

This is no longer turned on, after consulting with Thomas, switched back to findByNamedQuery, renamed the 'askHibernate' method below to 'findByNamedQuery' and trapped all Hibernate exceptions, logged, so this method does not throw exceptions

Original code fragment (example)
List courses = getHibernateTemplate().findByNamedQuery("findCourseInfoByYearTermCntlNum",
					new Object[] { courseInfoFields[COURSE_TERM_YEAR],
							courseInfoFields[COURSE_TERM_ID],
							courseInfoFields[COURSE_CNTL_NUM] },
					new Type[] { Hibernate.STRING, Hibernate.STRING,
							Hibernate.STRING });
Replacement code (example)
List courses = askHibernate("findCourseInfoByYearTermCntlNum", new Object[] { courseInfoFields[COURSE_TERM_YEAR],
					courseInfoFields[COURSE_TERM_ID],
					courseInfoFields[COURSE_CNTL_NUM] });
askHibernate method, CourseManagementManagerImpl.java
        private List askHibernate(final String queryName, final Object[] args) {
		HibernateCallback hc = new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException {
				Query q = session.getNamedQuery(queryName);
				if (args != null) 
					for (int i=0;i<args.length;i++) {
						String className = args[i].getClass().getName();
						if (className.equals("java.lang.String")) {
							q.setString(i, (String)args[i]);
						} else if (className.equals("java.lang.Integer")) {
							q.setInteger(i, (Integer)args[i]);
						}
					}
				return q.list();
			}
		};
		return getHibernateTemplate().executeFind(hc);
	}