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:
Project |
URL |
---|---|
caldav4j |
|
Slide WebDAV client |
|
HttpClient |
|
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:
- Set up an instance of
HttpClient
using an assumed site's owner for credentials. - Instantiate a caldav4j
CalDAVCalendarCollection
object using theHttpClient
and the remote path to the calendar. - call
getEventResources
on theCalDAVCalendarCollection
, passing it the time range for which we want calendar events. This method returns aList
of iCalendars. - 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 SakaiCalendarEvent
. - 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.