Developer's Guide

Introduction

The Sakai CalDAV integration is an alternative implementation of Sakai's CalendarService interface that uses HTTP requests to a CalDAV server to fulfill the API. The bulk of the code is in CalDAVCalendarService which is used in place of Sakai's DbCalendarService.

The purpose of the integration is to take advantage of an institution's official calendar system to store calendar events for Sakai. The usefulness of Sakai's calendar is limited if it is completely separate and disconnected from students' and instructors' primary calendar.

One question that has come up is, "If there is an enterprise calendar system for the institution, why should Sakai have any calendar in it at all?" The answer is that Sakai defines a context for each course and project. Since a student or instructor can visit a course worksite and see documents, announcements, and discussions relevant to that course, it's also a good place to surface calendar events relevant in that context as well.

The JIRA item for CalDAV integration is http://jira.sakaiproject.org/jira/browse/SAK-13277

Getting the Code

The CalDAV code is being developed as a branch of the calendar/ module in the public Sakai repository. There are also some modifications to util/ that were necessary to make the calendar module unit-testable. The branches were made from the 2.5.x code. To begin development with the CalDAV code, begin by checking out Sakai 2.5.x, and then switch the calendar and util modules to their CalDAV branches:

svn checkout https://source.sakaiproject.org/svn/sakai/branches/sakai_2-5-x
svn switch https://source.sakaiproject.org/svn/calendar/branches/SAK-13277 ./sakai_2-5-x/calendar
svn switch https://source.sakaiproject.org/svn/util/branches/SAK-13277 ./sakai_2-5-x/util

Dependencies

The CalDAV code relies on a stack of open source projects to make CalDAV requests. Since the CalDAV standard extends WebDAV, which in turn extends HTTP, we depend on caldav4j, which uses the Slide WebDAV client and Apache HttpClient. Since CalDAV delivers a payload in the iCalendar format, we make heavy use of ical4j:

We needed to patch a couple of issues we ran into with caldav4j. We want to submit these changes to that project for review, but in the meantime, a slightly modified copy of the caldav4j source code is in our repository (its license is favorable for this). Before the Sakai CalDAV code will work properly, you must first descend into the caldav4j-src and build it with mvn install. It has some unit tests that expect an instance of Chandler server (also known as Cosmo) to be running on localhost. This isn't hard to setup; It's another Tomcat-based server that starts up with a single command. http://chandlerproject.org/Developers/DownloadChandlerServer If you don't want to bother with that, you can build with tests disabled: mvn install -Dmaven.test.skip=true.

Code Details

Almost all of the code is in CalDAVCalendarService.java which has an important inner class called CalDAVStorage. Both of these follow from the model of DbCalendarService and its inner class, DbStorage. The CalDAV code is substituted for the database version by modifying /calendar-impl/pack/src/webapp/WEB-INF/components.xml

The quick way to get a sense of how we take Sakai API calls and turn them into CalDAV requests over HTTP is to look at public List<CalendarEvent> getEvents(Calendar calendar, long l, long m) within CalDAVStorage. The pseudocode of that method is here:

  1. Set up an instance of HttpClient using an assumed site's owner for credentials.
  2. Instantiate a caldav4j CalDAVCalendarCollection object using the HttpClient and the remote path to the calendar.
  3. call getEventResources on the CalDAVCalendarCollection, passing it the time range for which we want calendar events. This method returns a List of iCalendars.
  4. for each vEvent in each iCalendar, call a local method called makeCalendarEventForCalDAVvEvent. This method is where the translation occurs between an iCalendar vEvent and a Sakai CalendarEvent.
  5. return the list of Sakai CalendarEvents.

The next important method to understand is public void commitEvent(Calendar calendar, CalendarEventEdit edit). This is where we put together an iCalendar from a Sakai Calendar and then do a CalDAV PUT operation.

Development Tips

I would not have been able to learn how CalDAV works without HTTPScoop, a simple tool for the Mac that records requests and responses over HTTP. There are certainly other ways to do this, such as with tcpdump or Wireshark, but I have found these difficult to use, and HTTPScoop has earned my 15 euros many times over in the past two months.

When testing new CalDAV, reading the actual HTTP requests and responses as they go over the wire is the best way to see what is really happening with the API. You can see, for example, that Sakai is somewhat verbose with its API calls, and that if it comes to that, there will be plenty of places to tune for performance.