Course Management Integration

Sakai Course Management Service - A Tutorial

  1. What's the point?
  2. What is it?
  3. How do you customize it?

Course Management Service Goals

Unlike standalone sites such as Flickr, a collaborative learning environment (CLE) usually fits into an predefined world of people, groups, and roles (or enterprise integration data). A CLE may need to associate:

  • Courses, sections, and departments with site names and descriptions
  • Courses and sections with online user groups
  • Instructors, student enrollments, teaching assistants, and departmental administrators with site memberships and permissions

In some cases, the CLE might send data back out to external systems - for example, when submitting final grades for students or broadcasting section membership switches - but even then the terms of the integration tend to be set by the external systems. Few registrars will change their rules for the benefit of a CLE.

In early releases, Sakai assumed a fairly simple relationship between institutional divisions and web sites, and didn't offer tools access to much enterprise data beyond what was required by site management. Because community members needed both more flexibility and more power. in 2005-2007 a group of universities collaborated to research, define, implement, and integrate a rich Course Management interface (or CM API) inside Sakai.

Clients of this API might include Sakai authorization services, user group and role services, site management applications, gradebook applications, roster displays, and course catalog browsers. Since the CM API models course organization without any dependencies on other Sakai services, even non-Sakai software might use the interface as a starting point.

Implementations of this API might be institution-specific or based on existing enterprise data packages, but in either case the API provides a "generic" face that lets client code be written in a cross-institutional fashion.

CM API Clients

The CM API finds use in the following areas of Sakai 2.4.x.

Integration with Authorization, Groups, and the Section Info tool

When a course has been associated with a site, its section data and memberships may be added automatically to the site. Course and section enrollments (along with any non-student memberships) will automatically be reflected in the site until the instructor decides to switch from auto-management to self-managed sections.

System admins can choose between four configuration options via a "sakai.properties" string. Details are below.

Integration with the Roster tool

Student enrollment data can be displayed in the Roster tool.

Integration with the Site Manage tool

Instructors can base sites on a combination of officially assigned courses and sections. Site Manage restricts course site creation to courses and sections that are associated with current academic sessions (AKA terms or semesters).

Courses and sections can also be added to a site via a simple course management browser.

CM API overview

CM limitations

Research uncovered three major obstacles to the project's goals:

Problem #1: Definitions vary widely among institutions

The temporal range of a set of course offerings might be called a "Semester", a "Quarter", a "Term", or a "Session". A single set of enrollments might be associated with something called a "Section", a "Class", a "Course", or a "Course Offering".

Solution: Use vague terms (largely drawn from the OKI OSID).

Problem #2: Structures vary widely even within institutions

At a large university, introductory language classes might be set up very differently from independent study units or lab science classes. Individual departments and schools may have their own typical approaches to course structure and administration.

Solution: Define an API flexible to match the known use cases.

This combination of vague terminology and flexible relationships virtually guarantees that the result will not match any vocabulary with which you're familiar. Look at how some typical use cases map to the CM API before guessing at your own instituional data mappings.

For example, the "Enrollment Set" described by the CM API is rarely described explicitly at a university. In some schools, a large Lecture section is implicitly associated with official enrollment records, whereas a student enrolled in that "primary" section might be a member of multiple "secondary" Discussion or Lab sections without receiving separate final course grades for each. Other schools follow other rules. Because official enrollment data is usually treated differently from simple group membership, a separate object was defined to abstract it.

As another example, the CM API subsumes familiar (but widely varying) terms like "Department" or "School" in the less-familiar category of "Course Sets".

Problem #3: Business rules vary widely

Solution: Don't try to enforce business rules. The CM API is an anemic data model whose primary audience is the CLE, not the registrar or course catalog administration. For example, there's no internal provision for reconciling changes made through the Sakai Section Info tool with changes made from registrar data. Instead, the out-of-the-box software assumes all-or-nothing control.

Use Cases

The Course Management project site contains a useful set of Abstract Course and Site Structure Patterns and a set of Real-World Institutional Data Mappings.

In this simple pattern, a single course is associated with a single site, student enrollment is in the course, and there are no sections:

This introductory science course has a large Lecture section (with an official instructor and enrollment set) whose students and teaching assistants are split between many Lab and Discussion sections:

CM Concepts

The basic Sakai course structure is one of containment. A CourseSet describes a collection of CanonicalCourses or CourseOfferings. A CanonicalCourse describes a set of CourseOfferings. A CourseOffering may contain Sections. A Section may contain other Sections (sub-sections).

Other key associations are:

  • AcademicSession with CourseOfferings
  • EnrollmentSet with a CourseOffering or Section
  • Enrollment records with an EnrollmentSet
  • User Memberships with a CourseSet, CourseOffering, or Section.

Course Management Service Business Objects

AcademicSession

An Academic Session provides a schedule-based context for CourseOfferings within a CanonicalCourse. This will generally reflect semesters, terms, or quarters (e.g., "Fall 2007" and "Spring 2008"), but may be used to represent any ordering of CourseOfferings. The Start and End dates can be used for time-based ordering and for determining which course data is underway.

Although many institutions only have one Academic Session active at any one time, the service method getCurrentAcademicSessions() returns a list to support use cases such as the following:

  • Some universities provide summer courses of varying length, some of which overlap.
  • Large installations might cover several colleges or graduate programs which maintain separate schedules.
  • Online learning environments may support staggered sessions, or self-paced sessions whose start and end are determined by goals.

    Not all CourseOfferings are associated with an AcademicSession. Professional schools and distance learning environments sometimes do without academic terms, for example.

CanonicalCourse

A Canonical Course names and describes a a curriculum or academic program that is (or can be) offered repeatedly. It is an course definition abstracted from any particular instance of the course, as might be described in a course catalog.

CanonicalCourses can be organized under an academic department or in other ways by adding them to a CourseSet.

CourseOffering

A Course Offering represents an instance of a CanonicalCourse, usually as offered during an AcademicSession. For more flexible scheduling, the CourseOffering object can override the default AcademicSession start and end dates with its own StartDate and EndDate.

CourseSet

A Course Set is a collection of CanonicalCourses and/or CourseOfferings used to describe majors, departments and other high level collections of courses. A CourseSet can contain other CourseSets to support a hierarchy such as "School / Department / Division".

Besides a unique Enterprise ID (EID), Title, and Description, a CourseSet has a "Category" field that can be used for institution-specific filtering and searching. (For example, one Category value might be "Department", giving application writers a way to hierarchically browse the course catalog starting from the Department level.)

Enrollment

An Enrollment represents the official relationship of a student to something that gets a final grade (or equivalent). Generally, this is enrollment in a single CourseOffering or Section. Enrollment properties include whether the student has dropped the enrollment, EnrollmentStatus (such as "Waitlisted"), Credits, and GradingScheme strings.

Membership

Membership simply relates a user to a particular role within a course data unit. For example, a user might play the role of:

  • A "Department Admin" in a CourseSet
  • A "GSI" in a CourseSection
  • A "Lecturer" in a CourseSection
  • An "Instructor" in a CourseOffering

The Membership's Status property can be used to indicate "Active", "Inactive", or other institution-defined statuses.

EnrollmentSet

An Enrollment Set contains Enrollments for a particular Section or CourseOffering, along with enrollment-related metadata such as OfficialInstructors and DefaultEnrollmentCredits. Separated from Section as some institutions have Sections that do not carry credit and other institutions have a CourseOffering with no Sections.

Section

A Section represents a cohort or a group within a CourseOffering. There may be multiple Sections related to a CourseOffering. Sections may also contain other Sections as subsections. A single person may be a member of multiple Sections within a single CourseOffering.

Sections are defined differently in different universities. Some define sections strictly in a student information or registrar system. Others define them completely within the course management systems. Still others use a mix of both approaches. The Course Management service interface and default implementation do not provide a mechanism for specifying and enforcing business rules around section memberships. If necessary, those must be handled in integration code.

A Section typically has a Category code (such as "LAB", "DISC" for "Discussion", or "SEM" for "Seminar"). Sets of sections of a uniform Category are often created (for example, four lecture sections and four lab sections), and students enrolled in a course are often distributed across these section sets such that each student is a member of only one Section for each Category.

A Section may also be associated with a set of Meetings that describe when and where the section meets, and a MaxSize (the maximum number of students allowed).

Some sections may have an official meaning beyond just a place to meet and learn. Some sections are graded and will appear on a transcript, while others meet as a requirement of another section. Sections that carry credits and official grades separately have an EnrollmentSet.

CM Service Interfaces

The Course Management API has two service interfaces.

CourseManagementService is read-only, and is the only one used by other Sakai components and applications.

CourseManagementAdministration is an optional interface that, if implemented, gives installations a way to update course management data stored within Sakai itself.

Integrating with CM

Decide on an integration strategy

  1. Understand the CM object model and typical use cases.
  2. Understand your institution's course management model.
  3. Understand what your support staff and users want out of an LMS / CLE. Will Sakai course sites and sections be created and managed by central administration? Or by instructors? Or by some mix? If site and section creation is fairly rigid and can be automated, there may be less need for you to worry about Sakai's site administration tools.
  4. See what data you can get from where. If some enterprise data simply isn't available to you, there's not much point building it into the model.

Development

  1. Decide the mapping between your available institutional data and the CM model.
  2. Decide how to map institutional enterprise roles (including enrollment statuses) to Sakai roles.
  3. Decide on a development approach. (See below for more.)
  4. Write integration tests as you go! This will speed up your development effort considerably, since you won't have to deploy to a real server and get real users to test the system. It will also make it much easier for you or other maintainers to adapt the integration to changed conditions (for example, when SIS modifies database tables). For sample code, see the UC Berkeley snapshot listed below.
  5. Configure the GroupProvider as needed. (See below for more.)
  6. Set sakai.properties as needed. (See below for more.)
  7. Implement SectionFieldManager for Site Manage and change legacy code as needed.

Development approaches

Sakai 2.4.* and 2.5.* come with a Hibernate-based reference implementation of the Course Management API. When running Sakai in demo mode, test data is loaded into the tables defined by this implementation.

To integrate your own institutional data with Sakai, you can follow any of the following paths:

  • Use the RI, populating the Hibernate-defined tables with the CourseManagementAdministration API through Quartz jobs, web services, etc.
  • Use the RI, customizing the Hibernate mappings to point to your custom DB schema.
  • Write a custom implementation of the CM API, drawing directly on your institutional data sources.

Sample production code is available for all three of these approaches.

  • UC Berkeley sample code - Custom implementation of the CM API using Spring JDBC against Oracle views provided by SIS
  • Stanford documentation - RI, loading tables via XML feeds from SIS
  • UC Davis sample code - RI, Hibernate mappings changed to point to SIS-supplied tables

Default CM Group Provider

Sakai handles site group and role integration with the Group Provider interface. The default implementation distributed with Sakai is the CourseManagementGroupProvider.

In its 2.4.x and 2.5.x versions, you may very well have to comment out the "org.sakaiproject.authz.api.GroupProvider" bean configuration in the "provider" module's components.xml file so that you can configure the CourseManagementGroupProvider with different mappings. (We hope to fix that for 2.6.)

However, it's likely that you will not have to re-write any Java code, since the CourseManagementGroupProvider is designed to be fairly generic in linking Course Management data to Sakai authorization.

The following Group Provider methods expose enterprise defined groups in Sakai:

Map getGroupRolesForUser(String userId);
Map getUserRolesForGroup(String providerId);
String preferredRole(String one, String other);

For "getUserRolesForGroup", CourseManagementGroupProvider assumes that the providerId contains a list of Course Management EIDs for sections, course offerings, and/or course sets. It assembles a list of users and roles from student enrollment records, officially assigned instructors, and memberships. Similarly, "getGroupRolesForUser" assembles a list of Course Management EIDs and roles.

Course management membership roles and/or enrollment statuses are converted to Sakai roles using a complex XML-settable property called "roleResolvers". Any role or status not included in the roleResolvers will not lead to Sakai group membership. Here's the default setting:

<property name="roleResolvers">
	<list>
		<bean class="org.sakaiproject.coursemanagement.impl.provider.SectionRoleResolver">
			<property name="roleMap">
				<map>
					<entry key="I" value="Instructor" />
					<entry key="S" value="Student" />
					<entry key="GSI" value="Teaching Assistant"/>
				</map>
			</property>
			<property name="officialInstructorRole" value="Instructor" />
			<property name="enrollmentStatusRoleMap">
				<map>
					<entry key="enrolled" value="Student" />
					<entry key="wait" value="Student" />
				</map>
			</property>
		</bean>
		<bean class="org.sakaiproject.coursemanagement.impl.provider.CourseOfferingRoleResolver">
			<property name="roleMap">
				<map>
					<entry key="CourseAdmin" value="Instructor" />
					<entry key="I" value="Instructor" />
				</map>
			</property>
		</bean>
		<bean class="org.sakaiproject.coursemanagement.impl.provider.CourseSetRoleResolver">
			<property name="roleMap">
				<map>
					<entry key="DeptAdmin" value="Instructor" />
				</map>
			</property>
		</bean>
	</list>
</property>

CourseManagementGroupProvider stores role preference order in an XML-settable property called "rolePreferences". Here's the default setting:

<property name="rolePreferences">
	<list>
		<value>Instructor</value>
		<value>Teaching Assistant</value>
		<value>Student</value>
	</list>
</property>

To keep enrollment records synchronized with course site access, Sakai will need to be able to go from the site data to the corresponding Course Management data. Although Sakai site management allows multiple course offerings and sections to be associated with a site, Sakai's site authorization code only stores a single string to identify the site's "provider ID". The following Group Provider methods handle compound group IDs:

String packId(String[] ids);
String[] unpackId(String id);

The default implementation generates a provider ID string by concatenating all section EIDs with "" signs. (For example, if a course site has been created and associated with rosters from the sections "CHEM 101 LAB 002 F2007" and "CHEM 101 DISC 002 F2007", then the site's provider ID will be set to "CHEM 101 LAB 002 F2007+CHEM 101 DISC 002 F2007".) The only reason you'd have to change this code is if section IDs at your institution include the "" character.

Configuring the Group Provider

When planning your integration strategy, you will probably find enterprise data that describes institution-wide and/or context-specific roles for users. If you're adding users to sites or automatically, you'll want to use that data to set their Sakai-wide and/or site-specific roles.

  1. How do institutional roles map to Sakai roles? (E.g., should a department administrator be displayed in Sakai as an "Instructor"?)
  2. How does enrollment status affect Sakai roles? (E.g., should a student with an enrollment status field of "WAITLISTED" be added to a course site or not?)
  3. When a single user plays multiple roles, which should take precedence? (E.g., if the institutional LDAP shows a grad student as both a "STUDENT" and a "STAFF_MEMBER", how should they be displayed in Sakai?)

As an example of how you might configure the CourseManagementGroupProvider through "components.xml", here are the settings used at UC Berkeley:

<bean id="org.sakaiproject.authz.api.GroupProvider"
	class="org.sakaiproject.coursemanagement.impl.provider.CourseManagementGroupProvider"
	singleton="true"
	init-method="init"
	destroy-method="destroy">
	<property name="cmService">
		<ref bean="org.sakaiproject.coursemanagement.api.CourseManagementService"/>
	</property>
	<property name="rolePreferences">
		<list>
			<value>Instructor</value>
			<value>Student</value>
		</list>
	</property>
	<property name="roleResolvers">
		<list>
			<bean class="org.sakaiproject.coursemanagement.impl.provider.SectionRoleResolver">
				<property name="roleMap">
					<map>
						<entry key="Instructor" value="Instructor" />
						<entry key="Student" value="Student" />
					</map>
				</property>
				<property name="officialInstructorRole" value="Instructor" />
				<property name="enrollmentStatusRoleMap">
					<map>
						<entry key="E" value="Student" />
						<entry key="W" value="Student" />
						<entry key="C" value="Student" />
					</map>
				</property>
			</bean>
		</list>
	</property>
</bean>

Important sakai.properties

config@org.sakaiproject.section.api.SectionManager

Options are:

  • MANUAL_DEFAULT : Manual by default. The Section Info tool allows the user to choose whether sections should be internally or externally managed. Sections will not be generated for sites unless a site maintainer switches the default "manual" setting to automatic.
  • MANUAL_MANDATORY : Exclusively manual. The Section Info tool does not allow for externally managed sections, and sections will never be created automatically.
  • AUTOMATIC_DEFAULT : Automatic by default. The Section Info tool allows the user to choose whether sections should be internally or externally managed. Sections will be generated for sites associated with any number of rosters. The default setting for new sites will be automatic management of sections.
  • AUTOMATIC_MANDATORY : Exclusively automatic. The Section Info tool does not allow for internally managed sections. All sections are created automatically, based on the rosters associated with the site.

The default value is AUTOMATIC_DEFAULT.

org.sakaiproject.coursemanagement.api.CourseManagementService

If you're not using the default (demo) Course Management implementation, set this to the singleton name of your CM component.

SectionFieldManager and other Site Manage changes

TBD

References