Group event example using implicit scheduling

The iTIP specification (RFC 2446 or its Calsify successor) contains a group event example showing an initial invitation, a reply and an update to a group event.

The example only shows the messages that are exchanged between the different calendar clients. It does not show what each client would store in the actual calendars of the participants after each step. This is for good reason since iTIP defines only messages between CUAs and also because an iTIP aware client does not necessarily store the actual calendar in iCalendar format (might be a proprietary format).

But in any case, iTIP aware clients have to deal with 2 types of objects:

  • iTIP messages (invitations, responses,...).
  • calendar resources (the event and tasks that users see in their calendar).
The client must handle the complex logic of creating one from another, merging them together,...

Using the new CalDAV Scheduling model, this becomes much simpler since clients do need to worry only about their copy of the event. I'll try to show that by turning the above mentioned iTIP example into a CalDAV Scheduling example.

Organizer A invites B, C, D, and E (See 4.2.1 A Group Event Request in iTIP):

To initiate the group event , the organizer (A) simply creates a regular calendar resource in any of his calendar collections:

>> Request <<

PUT /home/A/calendar/qwue23489.ics HTTP/1.1
If-None-Match: \*
Host: cal.example.com
Content-Type: text/calendar
Content-Length: xxxx
   
BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

>> Response <<

HTTP/1.1 201 Created
Content-Length: 0
Date: Thu, 11 Jun 2009 09:32:12 GMT

On storing this calendar resource, the server notices that it is a scheduling resource:

  • the organizer is the owner of the calendar collection,
  • the resource has attendees without a SCHEDULE-AGENT=CLIENT parameter.

As a consequence, the server will automatically deliver a copy of the same event in each attendee's calendar (and put a corresponding iTIP message in their scheduling inbox).

The Organizer client can check whether the delivery succeeded by doing a GET on the just created resource and checking the SCHEDULE-STATUS of each attendee:

>> Request <<

GET /home/A/calendar/qwue23489.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:32:24 GMT
ETag: "123456789-000-111"
Schedule-Tag: "123456789-000-111"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=ROOM:conf_Big@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Reply from attendee B (See 4.2.2 Reply To A Group Event Request in iTIP. )

The calendar client of user B does a synchronization between its local cache and the default calendar collection of user B and fetches the event.

>> Request <<

GET /home/B/calendar/bzyw23492.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:34:24 GMT
ETag: "123456789-000-112"
Schedule-Tag: "123456789-000-112"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Attendee B accepts the invitation. The CUA simply does so by issuing a PUT on the same (attendee's) calendar resource, with an updated PARTSTAT for Attendee B. It makes use of the conditional If-Schedule-Tag-Match header to avoid minor update by other attendees conflicting with its own change:

>> Request <<

PUT /home/B/calendar/bzyw23492.ics HTTP/1.1
If-Schedule-Tag-Match: "123456789-000-112"
Host: cal.example.com
Content-Type: text/calendar
Content-Length: xxxx   

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;PARTSTAT=ACCEPTED;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
>> Response <<

HTTP/1.1 204 No Content
Content-Length: 0
Date: Thu, 11 Jun 2009 09:34:30 GMT

The server will then automatically process the reply and update the Organizer's copy accordingly.

Organizer receives the reply from Attendee B

The Organizer's CUA fetches the new version of the group meeting:

>> Request <<

GET /home/A/calendar/qwue23489.ics HTTP/1.1
Host: cal.example.com
   
>> Response <<

HTTP/1.1 200 OK
Content-Type: text/calendar
Content-Length: XXX
Date: Thu, 11 Jun 2009 09:40:24 GMT
ETag: "123456789-000-333"
Schedule-Tag: "123456789-000-333"

BEGIN:VCALENDAR
PRODID:-//ACME/DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;SCHEDULE-STATUS="2.0";PARTSTAT=ACCEPTED;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";TYPE=ROOM:conf_Big@example.com
ATTENDEE;SCHEDULE-STATUS="1.2";ROLE=NON-PARTICIPANT:Mailto:E@example.com
DTSTAMP:20090611T190000Z
DTSTART:20090701T200000Z
DTEND:20090701T2000000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Of course, this example is only scratching the surface of what it takes to create a good scheduling aware client but it shows that minimal scheduling processing can be achieved at a very low cost.


Comments:

Hm, I don't like it. Maybe we need a specific POST or other method to change an attendee status.
Just a rough feeling. That "If-Schedule-Tag-Match" sounds just wrong.

A bit more constructive: all the GETs do not show an If-None-Match, thats a must in any real world client.

Posted by Helge on May 07, 2009 at 06:33 PM CEST #

The whole logic behind the new scheduling spec is that you can update your own copy and reply to an invitation in one single PUT (as opposed to doing a PUT on your copy + a POST of an iTIP REPLY).
Now I imagine that the server could update the invitee's copy after a POST but clients still need to deal with iTIP messages.

About the GETs:
\* the first one corresponds to the organizer CUA retrieving the SCHEDULE-STATUS of each attendees, after having created the resource so caching is not involved.
\* about the other ones, it all depends how the client does the synchronization. Most calendar clients do a PROPFIND at the calendar collection level, retrieving the ctag or getetag properties of each resource, then do individual GETs (or a multiget REPORT) of only changed or newly added resources. Did not want to clutter the example with such PROPFIND.

Posted by Arnaud Quillaud on May 11, 2009 at 07:18 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

arnaudq

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks