[CalendarServer-changes] [8216] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Fri Oct 21 11:35:10 PDT 2011
Revision: 8216
http://trac.macosforge.org/projects/calendarserver/changeset/8216
Author: sagen at apple.com
Date: 2011-10-21 11:35:09 -0700 (Fri, 21 Oct 2011)
Log Message:
-----------
Adds a principal cache during the calendar-user-address normalization process of upgrades.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
CalendarServer/trunk/twistedcaldav/upgrade.py
Modified: CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_upgrade.py 2011-10-20 22:23:12 UTC (rev 8215)
+++ CalendarServer/trunk/twistedcaldav/test/test_upgrade.py 2011-10-21 18:35:09 UTC (rev 8216)
@@ -23,7 +23,7 @@
from twistedcaldav.mail import MailGatewayTokensDatabase
from twistedcaldav.upgrade import (
xattrname, UpgradeError, upgradeData, updateFreeBusySet,
- removeIllegalCharacters
+ removeIllegalCharacters, normalizeCUAddrs
)
from twistedcaldav.test.util import TestCase
from calendarserver.tools.util import getDirectory
@@ -1422,6 +1422,69 @@
self.assertFalse(changed)
+ def test_normalizeCUAddrs(self):
+ """
+ Ensure that calendar user addresses (CUAs) are cached so we can
+ reduce the number of principal lookup calls during upgrade.
+ """
+
+ class StubPrincipal(object):
+ def __init__(self, record):
+ self.record = record
+
+ class StubRecord(object):
+ def __init__(self, fullName, guid, cuas):
+ self.fullName = fullName
+ self.guid = guid
+ self.calendarUserAddresses = cuas
+
+ class StubDirectory(object):
+ def __init__(self):
+ self.count = 0
+
+ def principalForCalendarUserAddress(self, cuaddr):
+ self.count += 1
+ record = records.get(cuaddr, None)
+ if record is not None:
+ return StubPrincipal(record)
+ else:
+ raise Exception
+
+ records = {
+ "mailto:a at example.com" :
+ StubRecord("User A", 123, ("mailto:a at example.com", "urn:uuid:123")),
+ "mailto:b at example.com" :
+ StubRecord("User B", 234, ("mailto:b at example.com", "urn:uuid:234")),
+ }
+
+ directory = StubDirectory()
+ cuaCache = {}
+ normalizeCUAddrs(normalizeEvent, directory, cuaCache)
+ normalizeCUAddrs(normalizeEvent, directory, cuaCache)
+
+ # Ensure we only called principalForCalendarUserAddress 3 times. It
+ # would have been 8 times without the cuaCache.
+ self.assertEquals(directory.count, 3)
+
+normalizeEvent = """BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+TRANSP:OPAQUE
+UID:1E238CA1-3C95-4468-B8CD-C8A399F78C71
+DTSTART:20090203
+DTEND:20090204
+ORGANIZER;CN="User A":mailto:a at example.com
+SUMMARY:New Event
+DESCRIPTION:Foo
+ATTENDEE;CN="User A";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:a at example.com
+ATTENDEE;CN="User B";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:b at example.com
+ATTENDEE;CN="Unknown";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:unknown at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+
+
event01_before = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//iCal 3.0//EN
Modified: CalendarServer/trunk/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/upgrade.py 2011-10-20 22:23:12 UTC (rev 8215)
+++ CalendarServer/trunk/twistedcaldav/upgrade.py 2011-10-21 18:35:09 UTC (rev 8216)
@@ -115,38 +115,10 @@
- def normalizeCUAddrs(data, directory):
- cal = Component.fromString(data)
- def lookupFunction(cuaddr):
- try:
- principal = directory.principalForCalendarUserAddress(cuaddr)
- except Exception, e:
- log.debug("Lookup of %s failed: %s" % (cuaddr, e))
- principal = None
- if principal is None:
- return (None, None, None)
- else:
- rec = principal.record
+ def upgradeCalendarCollection(calPath, directory, cuaCache):
- # RFC5545 syntax does not allow backslash escaping in
- # parameter values. A double-quote is thus not allowed
- # in a parameter value except as the start/end delimiters.
- # Single quotes are allowed, so we convert any double-quotes
- # to single-quotes.
- fullName = rec.fullName.replace('"', "'")
-
- return (fullName, rec.guid, rec.calendarUserAddresses)
-
- cal.normalizeCalendarUserAddresses(lookupFunction)
-
- newData = str(cal)
- return newData, not newData == data
-
-
- def upgradeCalendarCollection(calPath, directory):
-
errorOccurred = False
collectionUpdated = False
@@ -189,7 +161,7 @@
continue
try:
- data, fixed = normalizeCUAddrs(data, directory)
+ data, fixed = normalizeCUAddrs(data, directory, cuaCache)
if fixed:
log.debug("Normalized CUAddrs in %s" % (resPath,))
needsRewrite = True
@@ -236,7 +208,7 @@
return errorOccurred
- def upgradeCalendarHome(homePath, directory):
+ def upgradeCalendarHome(homePath, directory, cuaCache):
errorOccurred = False
@@ -254,7 +226,7 @@
rmdir(calPath)
continue
log.debug("Upgrading calendar: %s" % (calPath,))
- if not upgradeCalendarCollection(calPath, directory):
+ if not upgradeCalendarCollection(calPath, directory, cuaCache):
errorOccurred = True
# Change the calendar-free-busy-set xattrs of the inbox to the
@@ -392,6 +364,7 @@
directory = getDirectory()
+ cuaCache = {}
docRoot = config.DocumentRoot
@@ -515,7 +488,7 @@
continue
if not upgradeCalendarHome(homePath,
- directory):
+ directory, cuaCache):
errorOccurred = True
count += 1
@@ -532,6 +505,55 @@
raise UpgradeError("Data upgrade failed, see error.log for details")
+def normalizeCUAddrs(data, directory, cuaCache):
+ """
+ Normalize calendar user addresses to urn:uuid: form.
+
+ @param data: the calendar data to convert
+ @type data: C{str}
+ @param directory: the directory service to lookup CUAs with
+ @type data: L{DirectoryService}
+ @param cuaCache: the dictionary to use as a cache across calls, which is
+ updated as a side-effect
+ @type cuaCache: C{dict}
+ @return: tuple of (converted calendar data, boolean signaling whether
+ there were any changes to the data)
+ """
+ cal = Component.fromString(data)
+
+ def lookupFunction(cuaddr):
+ try:
+ if cuaCache.has_key(cuaddr):
+ principal = cuaCache[cuaddr]
+ else:
+ principal = directory.principalForCalendarUserAddress(cuaddr)
+ except Exception, e:
+ log.debug("Lookup of %s failed: %s" % (cuaddr, e))
+ principal = None
+
+ cuaCache[cuaddr] = principal
+
+ if principal is None:
+ return (None, None, None)
+ else:
+ rec = principal.record
+
+ # RFC5545 syntax does not allow backslash escaping in
+ # parameter values. A double-quote is thus not allowed
+ # in a parameter value except as the start/end delimiters.
+ # Single quotes are allowed, so we convert any double-quotes
+ # to single-quotes.
+ fullName = rec.fullName.replace('"', "'")
+
+ return (fullName, rec.guid, rec.calendarUserAddresses)
+
+ cal.normalizeCalendarUserAddresses(lookupFunction)
+
+ newData = str(cal)
+ return newData, not newData == data
+
+
+
@inlineCallbacks
def upgrade_to_2(config):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20111021/5fbbd86a/attachment.html>
More information about the calendarserver-changes
mailing list