[CalendarServer-changes] [14156] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Nov 12 10:09:15 PST 2014
Revision: 14156
http://trac.calendarserver.org//changeset/14156
Author: cdaboo at apple.com
Date: 2014-11-12 10:09:15 -0800 (Wed, 12 Nov 2014)
Log Message:
-----------
Fix cross-pod group proxy change handling.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tap/caldav.py
CalendarServer/trunk/calendarserver/tools/util.py
CalendarServer/trunk/conf/auth/accounts-test-pod.xml
CalendarServer/trunk/requirements-dev.txt
CalendarServer/trunk/requirements-stable.txt
CalendarServer/trunk/twistedcaldav/cache.py
CalendarServer/trunk/twistedcaldav/controlapi.py
CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py
CalendarServer/trunk/txdav/common/datastore/podding/directory.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/dps/client.py
CalendarServer/trunk/txdav/dps/commands.py
CalendarServer/trunk/txdav/dps/server.py
CalendarServer/trunk/txdav/who/augment.py
CalendarServer/trunk/txdav/who/cache.py
CalendarServer/trunk/txdav/who/groups.py
CalendarServer/trunk/txdav/who/test/test_delegates.py
CalendarServer/trunk/txdav/who/test/test_groups.py
Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -94,6 +94,7 @@
from txdav.who.groups import GroupCacher
from twistedcaldav import memcachepool
+from twistedcaldav.cache import MemcacheURLPatternChangeNotifier
from twistedcaldav.config import ConfigurationError
from twistedcaldav.localization import processLocalizationFiles
from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
@@ -916,10 +917,12 @@
# Optionally set up group cacher
if config.GroupCaching.Enabled:
+ cacheNotifier = MemcacheURLPatternChangeNotifier("/principals/__uids__/{token}/", cacheHandle="PrincipalToken") if config.EnableResponseCache else None
groupCacher = GroupCacher(
directory,
updateSeconds=config.GroupCaching.UpdateSeconds,
useDirectoryBasedDelegates=config.GroupCaching.UseDirectoryBasedDelegates,
+ cacheNotifier=cacheNotifier,
)
else:
groupCacher = None
@@ -1285,10 +1288,12 @@
# Optionally set up group cacher
if config.GroupCaching.Enabled:
+ cacheNotifier = MemcacheURLPatternChangeNotifier("/principals/__uids__/{token}/", cacheHandle="PrincipalToken") if config.EnableResponseCache else None
groupCacher = GroupCacher(
directory,
updateSeconds=config.GroupCaching.UpdateSeconds,
useDirectoryBasedDelegates=config.GroupCaching.UseDirectoryBasedDelegates,
+ cacheNotifier=cacheNotifier,
)
else:
groupCacher = None
@@ -1872,10 +1877,12 @@
# Optionally set up group cacher
if config.GroupCaching.Enabled:
+ cacheNotifier = MemcacheURLPatternChangeNotifier("/principals/__uids__/{token}/", cacheHandle="PrincipalToken") if config.EnableResponseCache else None
groupCacher = GroupCacher(
directory,
updateSeconds=config.GroupCaching.UpdateSeconds,
useDirectoryBasedDelegates=config.GroupCaching.UseDirectoryBasedDelegates,
+ cacheNotifier=cacheNotifier,
)
else:
groupCacher = None
Modified: CalendarServer/trunk/calendarserver/tools/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/util.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/calendarserver/tools/util.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -293,6 +293,8 @@
recordType, shortName = principalID.split(":", 1)
recordType = directory.oldNameToRecordType(recordType)
+ if recordType is None:
+ returnValue(None)
returnValue((yield directory.recordWithShortName(recordType, shortName)))
Modified: CalendarServer/trunk/conf/auth/accounts-test-pod.xml
===================================================================
--- CalendarServer/trunk/conf/auth/accounts-test-pod.xml 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/conf/auth/accounts-test-pod.xml 2014-11-12 18:09:15 UTC (rev 14156)
@@ -1627,4 +1627,718 @@
<full-name>Puser 100</full-name>
<email>puser100 at example.com</email>
</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000001</uid>
+ <guid>20000000-0000-0000-0000-000000000001</guid>
+ <short-name>group01</short-name>
+ <full-name>Group 01</full-name>
+ <email>group01 at example.com</email>
+ <member-uid>10000000-0000-0000-0000-000000000001</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000002</uid>
+ <guid>20000000-0000-0000-0000-000000000002</guid>
+ <short-name>group02</short-name>
+ <full-name>Group 02</full-name>
+ <email>group02 at example.com</email>
+ <member-uid>10000000-0000-0000-0000-000000000006</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000007</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000003</uid>
+ <guid>20000000-0000-0000-0000-000000000003</guid>
+ <short-name>group03</short-name>
+ <full-name>Group 03</full-name>
+ <email>group03 at example.com</email>
+ <member-uid>10000000-0000-0000-0000-000000000008</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000009</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000004</uid>
+ <guid>20000000-0000-0000-0000-000000000004</guid>
+ <short-name>group04</short-name>
+ <full-name>Group 04</full-name>
+ <email>group04 at example.com</email>
+ <member-uid>20000000-0000-0000-0000-000000000002</member-uid>
+ <member-uid>20000000-0000-0000-0000-000000000003</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000010</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000005</uid>
+ <guid>20000000-0000-0000-0000-000000000005</guid>
+ <short-name>group05</short-name>
+ <full-name>Group 05</full-name>
+ <email>group05 at example.com</email>
+ <member-uid>20000000-0000-0000-0000-000000000006</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000020</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000006</uid>
+ <guid>20000000-0000-0000-0000-000000000006</guid>
+ <short-name>group06</short-name>
+ <full-name>Group 06</full-name>
+ <email>group06 at example.com</email>
+ <member-uid>10000000-0000-0000-0000-000000000021</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000007</uid>
+ <guid>20000000-0000-0000-0000-000000000007</guid>
+ <short-name>group07</short-name>
+ <full-name>Group 07</full-name>
+ <email>group07 at example.com</email>
+ <member-uid>10000000-0000-0000-0000-000000000022</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000023</member-uid>
+ <member-uid>10000000-0000-0000-0000-000000000024</member-uid>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000008</uid>
+ <guid>20000000-0000-0000-0000-000000000008</guid>
+ <short-name>group08</short-name>
+ <full-name>Group 08</full-name>
+ <email>group08 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000009</uid>
+ <guid>20000000-0000-0000-0000-000000000009</guid>
+ <short-name>group09</short-name>
+ <full-name>Group 09</full-name>
+ <email>group09 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000010</uid>
+ <guid>20000000-0000-0000-0000-000000000010</guid>
+ <short-name>group10</short-name>
+ <full-name>Group 10</full-name>
+ <email>group10 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000011</uid>
+ <guid>20000000-0000-0000-0000-000000000011</guid>
+ <short-name>group11</short-name>
+ <full-name>Group 11</full-name>
+ <email>group11 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000012</uid>
+ <guid>20000000-0000-0000-0000-000000000012</guid>
+ <short-name>group12</short-name>
+ <full-name>Group 12</full-name>
+ <email>group12 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000013</uid>
+ <guid>20000000-0000-0000-0000-000000000013</guid>
+ <short-name>group13</short-name>
+ <full-name>Group 13</full-name>
+ <email>group13 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000014</uid>
+ <guid>20000000-0000-0000-0000-000000000014</guid>
+ <short-name>group14</short-name>
+ <full-name>Group 14</full-name>
+ <email>group14 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000015</uid>
+ <guid>20000000-0000-0000-0000-000000000015</guid>
+ <short-name>group15</short-name>
+ <full-name>Group 15</full-name>
+ <email>group15 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000016</uid>
+ <guid>20000000-0000-0000-0000-000000000016</guid>
+ <short-name>group16</short-name>
+ <full-name>Group 16</full-name>
+ <email>group16 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000017</uid>
+ <guid>20000000-0000-0000-0000-000000000017</guid>
+ <short-name>group17</short-name>
+ <full-name>Group 17</full-name>
+ <email>group17 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000018</uid>
+ <guid>20000000-0000-0000-0000-000000000018</guid>
+ <short-name>group18</short-name>
+ <full-name>Group 18</full-name>
+ <email>group18 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000019</uid>
+ <guid>20000000-0000-0000-0000-000000000019</guid>
+ <short-name>group19</short-name>
+ <full-name>Group 19</full-name>
+ <email>group19 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000020</uid>
+ <guid>20000000-0000-0000-0000-000000000020</guid>
+ <short-name>group20</short-name>
+ <full-name>Group 20</full-name>
+ <email>group20 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000021</uid>
+ <guid>20000000-0000-0000-0000-000000000021</guid>
+ <short-name>group21</short-name>
+ <full-name>Group 21</full-name>
+ <email>group21 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000022</uid>
+ <guid>20000000-0000-0000-0000-000000000022</guid>
+ <short-name>group22</short-name>
+ <full-name>Group 22</full-name>
+ <email>group22 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000023</uid>
+ <guid>20000000-0000-0000-0000-000000000023</guid>
+ <short-name>group23</short-name>
+ <full-name>Group 23</full-name>
+ <email>group23 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000024</uid>
+ <guid>20000000-0000-0000-0000-000000000024</guid>
+ <short-name>group24</short-name>
+ <full-name>Group 24</full-name>
+ <email>group24 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000025</uid>
+ <guid>20000000-0000-0000-0000-000000000025</guid>
+ <short-name>group25</short-name>
+ <full-name>Group 25</full-name>
+ <email>group25 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000026</uid>
+ <guid>20000000-0000-0000-0000-000000000026</guid>
+ <short-name>group26</short-name>
+ <full-name>Group 26</full-name>
+ <email>group26 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000027</uid>
+ <guid>20000000-0000-0000-0000-000000000027</guid>
+ <short-name>group27</short-name>
+ <full-name>Group 27</full-name>
+ <email>group27 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000028</uid>
+ <guid>20000000-0000-0000-0000-000000000028</guid>
+ <short-name>group28</short-name>
+ <full-name>Group 28</full-name>
+ <email>group28 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000029</uid>
+ <guid>20000000-0000-0000-0000-000000000029</guid>
+ <short-name>group29</short-name>
+ <full-name>Group 29</full-name>
+ <email>group29 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000030</uid>
+ <guid>20000000-0000-0000-0000-000000000030</guid>
+ <short-name>group30</short-name>
+ <full-name>Group 30</full-name>
+ <email>group30 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000031</uid>
+ <guid>20000000-0000-0000-0000-000000000031</guid>
+ <short-name>group31</short-name>
+ <full-name>Group 31</full-name>
+ <email>group31 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000032</uid>
+ <guid>20000000-0000-0000-0000-000000000032</guid>
+ <short-name>group32</short-name>
+ <full-name>Group 32</full-name>
+ <email>group32 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000033</uid>
+ <guid>20000000-0000-0000-0000-000000000033</guid>
+ <short-name>group33</short-name>
+ <full-name>Group 33</full-name>
+ <email>group33 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000034</uid>
+ <guid>20000000-0000-0000-0000-000000000034</guid>
+ <short-name>group34</short-name>
+ <full-name>Group 34</full-name>
+ <email>group34 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000035</uid>
+ <guid>20000000-0000-0000-0000-000000000035</guid>
+ <short-name>group35</short-name>
+ <full-name>Group 35</full-name>
+ <email>group35 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000036</uid>
+ <guid>20000000-0000-0000-0000-000000000036</guid>
+ <short-name>group36</short-name>
+ <full-name>Group 36</full-name>
+ <email>group36 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000037</uid>
+ <guid>20000000-0000-0000-0000-000000000037</guid>
+ <short-name>group37</short-name>
+ <full-name>Group 37</full-name>
+ <email>group37 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000038</uid>
+ <guid>20000000-0000-0000-0000-000000000038</guid>
+ <short-name>group38</short-name>
+ <full-name>Group 38</full-name>
+ <email>group38 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000039</uid>
+ <guid>20000000-0000-0000-0000-000000000039</guid>
+ <short-name>group39</short-name>
+ <full-name>Group 39</full-name>
+ <email>group39 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000040</uid>
+ <guid>20000000-0000-0000-0000-000000000040</guid>
+ <short-name>group40</short-name>
+ <full-name>Group 40</full-name>
+ <email>group40 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000041</uid>
+ <guid>20000000-0000-0000-0000-000000000041</guid>
+ <short-name>group41</short-name>
+ <full-name>Group 41</full-name>
+ <email>group41 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000042</uid>
+ <guid>20000000-0000-0000-0000-000000000042</guid>
+ <short-name>group42</short-name>
+ <full-name>Group 42</full-name>
+ <email>group42 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000043</uid>
+ <guid>20000000-0000-0000-0000-000000000043</guid>
+ <short-name>group43</short-name>
+ <full-name>Group 43</full-name>
+ <email>group43 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000044</uid>
+ <guid>20000000-0000-0000-0000-000000000044</guid>
+ <short-name>group44</short-name>
+ <full-name>Group 44</full-name>
+ <email>group44 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000045</uid>
+ <guid>20000000-0000-0000-0000-000000000045</guid>
+ <short-name>group45</short-name>
+ <full-name>Group 45</full-name>
+ <email>group45 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000046</uid>
+ <guid>20000000-0000-0000-0000-000000000046</guid>
+ <short-name>group46</short-name>
+ <full-name>Group 46</full-name>
+ <email>group46 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000047</uid>
+ <guid>20000000-0000-0000-0000-000000000047</guid>
+ <short-name>group47</short-name>
+ <full-name>Group 47</full-name>
+ <email>group47 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000048</uid>
+ <guid>20000000-0000-0000-0000-000000000048</guid>
+ <short-name>group48</short-name>
+ <full-name>Group 48</full-name>
+ <email>group48 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000049</uid>
+ <guid>20000000-0000-0000-0000-000000000049</guid>
+ <short-name>group49</short-name>
+ <full-name>Group 49</full-name>
+ <email>group49 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000050</uid>
+ <guid>20000000-0000-0000-0000-000000000050</guid>
+ <short-name>group50</short-name>
+ <full-name>Group 50</full-name>
+ <email>group50 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000051</uid>
+ <guid>20000000-0000-0000-0000-000000000051</guid>
+ <short-name>group51</short-name>
+ <full-name>Group 51</full-name>
+ <email>group51 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000052</uid>
+ <guid>20000000-0000-0000-0000-000000000052</guid>
+ <short-name>group52</short-name>
+ <full-name>Group 52</full-name>
+ <email>group52 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000053</uid>
+ <guid>20000000-0000-0000-0000-000000000053</guid>
+ <short-name>group53</short-name>
+ <full-name>Group 53</full-name>
+ <email>group53 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000054</uid>
+ <guid>20000000-0000-0000-0000-000000000054</guid>
+ <short-name>group54</short-name>
+ <full-name>Group 54</full-name>
+ <email>group54 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000055</uid>
+ <guid>20000000-0000-0000-0000-000000000055</guid>
+ <short-name>group55</short-name>
+ <full-name>Group 55</full-name>
+ <email>group55 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000056</uid>
+ <guid>20000000-0000-0000-0000-000000000056</guid>
+ <short-name>group56</short-name>
+ <full-name>Group 56</full-name>
+ <email>group56 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000057</uid>
+ <guid>20000000-0000-0000-0000-000000000057</guid>
+ <short-name>group57</short-name>
+ <full-name>Group 57</full-name>
+ <email>group57 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000058</uid>
+ <guid>20000000-0000-0000-0000-000000000058</guid>
+ <short-name>group58</short-name>
+ <full-name>Group 58</full-name>
+ <email>group58 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000059</uid>
+ <guid>20000000-0000-0000-0000-000000000059</guid>
+ <short-name>group59</short-name>
+ <full-name>Group 59</full-name>
+ <email>group59 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000060</uid>
+ <guid>20000000-0000-0000-0000-000000000060</guid>
+ <short-name>group60</short-name>
+ <full-name>Group 60</full-name>
+ <email>group60 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000061</uid>
+ <guid>20000000-0000-0000-0000-000000000061</guid>
+ <short-name>group61</short-name>
+ <full-name>Group 61</full-name>
+ <email>group61 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000062</uid>
+ <guid>20000000-0000-0000-0000-000000000062</guid>
+ <short-name>group62</short-name>
+ <full-name>Group 62</full-name>
+ <email>group62 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000063</uid>
+ <guid>20000000-0000-0000-0000-000000000063</guid>
+ <short-name>group63</short-name>
+ <full-name>Group 63</full-name>
+ <email>group63 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000064</uid>
+ <guid>20000000-0000-0000-0000-000000000064</guid>
+ <short-name>group64</short-name>
+ <full-name>Group 64</full-name>
+ <email>group64 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000065</uid>
+ <guid>20000000-0000-0000-0000-000000000065</guid>
+ <short-name>group65</short-name>
+ <full-name>Group 65</full-name>
+ <email>group65 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000066</uid>
+ <guid>20000000-0000-0000-0000-000000000066</guid>
+ <short-name>group66</short-name>
+ <full-name>Group 66</full-name>
+ <email>group66 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000067</uid>
+ <guid>20000000-0000-0000-0000-000000000067</guid>
+ <short-name>group67</short-name>
+ <full-name>Group 67</full-name>
+ <email>group67 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000068</uid>
+ <guid>20000000-0000-0000-0000-000000000068</guid>
+ <short-name>group68</short-name>
+ <full-name>Group 68</full-name>
+ <email>group68 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000069</uid>
+ <guid>20000000-0000-0000-0000-000000000069</guid>
+ <short-name>group69</short-name>
+ <full-name>Group 69</full-name>
+ <email>group69 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000070</uid>
+ <guid>20000000-0000-0000-0000-000000000070</guid>
+ <short-name>group70</short-name>
+ <full-name>Group 70</full-name>
+ <email>group70 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000071</uid>
+ <guid>20000000-0000-0000-0000-000000000071</guid>
+ <short-name>group71</short-name>
+ <full-name>Group 71</full-name>
+ <email>group71 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000072</uid>
+ <guid>20000000-0000-0000-0000-000000000072</guid>
+ <short-name>group72</short-name>
+ <full-name>Group 72</full-name>
+ <email>group72 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000073</uid>
+ <guid>20000000-0000-0000-0000-000000000073</guid>
+ <short-name>group73</short-name>
+ <full-name>Group 73</full-name>
+ <email>group73 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000074</uid>
+ <guid>20000000-0000-0000-0000-000000000074</guid>
+ <short-name>group74</short-name>
+ <full-name>Group 74</full-name>
+ <email>group74 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000075</uid>
+ <guid>20000000-0000-0000-0000-000000000075</guid>
+ <short-name>group75</short-name>
+ <full-name>Group 75</full-name>
+ <email>group75 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000076</uid>
+ <guid>20000000-0000-0000-0000-000000000076</guid>
+ <short-name>group76</short-name>
+ <full-name>Group 76</full-name>
+ <email>group76 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000077</uid>
+ <guid>20000000-0000-0000-0000-000000000077</guid>
+ <short-name>group77</short-name>
+ <full-name>Group 77</full-name>
+ <email>group77 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000078</uid>
+ <guid>20000000-0000-0000-0000-000000000078</guid>
+ <short-name>group78</short-name>
+ <full-name>Group 78</full-name>
+ <email>group78 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000079</uid>
+ <guid>20000000-0000-0000-0000-000000000079</guid>
+ <short-name>group79</short-name>
+ <full-name>Group 79</full-name>
+ <email>group79 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000080</uid>
+ <guid>20000000-0000-0000-0000-000000000080</guid>
+ <short-name>group80</short-name>
+ <full-name>Group 80</full-name>
+ <email>group80 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000081</uid>
+ <guid>20000000-0000-0000-0000-000000000081</guid>
+ <short-name>group81</short-name>
+ <full-name>Group 81</full-name>
+ <email>group81 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000082</uid>
+ <guid>20000000-0000-0000-0000-000000000082</guid>
+ <short-name>group82</short-name>
+ <full-name>Group 82</full-name>
+ <email>group82 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000083</uid>
+ <guid>20000000-0000-0000-0000-000000000083</guid>
+ <short-name>group83</short-name>
+ <full-name>Group 83</full-name>
+ <email>group83 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000084</uid>
+ <guid>20000000-0000-0000-0000-000000000084</guid>
+ <short-name>group84</short-name>
+ <full-name>Group 84</full-name>
+ <email>group84 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000085</uid>
+ <guid>20000000-0000-0000-0000-000000000085</guid>
+ <short-name>group85</short-name>
+ <full-name>Group 85</full-name>
+ <email>group85 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000086</uid>
+ <guid>20000000-0000-0000-0000-000000000086</guid>
+ <short-name>group86</short-name>
+ <full-name>Group 86</full-name>
+ <email>group86 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000087</uid>
+ <guid>20000000-0000-0000-0000-000000000087</guid>
+ <short-name>group87</short-name>
+ <full-name>Group 87</full-name>
+ <email>group87 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000088</uid>
+ <guid>20000000-0000-0000-0000-000000000088</guid>
+ <short-name>group88</short-name>
+ <full-name>Group 88</full-name>
+ <email>group88 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000089</uid>
+ <guid>20000000-0000-0000-0000-000000000089</guid>
+ <short-name>group89</short-name>
+ <full-name>Group 89</full-name>
+ <email>group89 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000090</uid>
+ <guid>20000000-0000-0000-0000-000000000090</guid>
+ <short-name>group90</short-name>
+ <full-name>Group 90</full-name>
+ <email>group90 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000091</uid>
+ <guid>20000000-0000-0000-0000-000000000091</guid>
+ <short-name>group91</short-name>
+ <full-name>Group 91</full-name>
+ <email>group91 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000092</uid>
+ <guid>20000000-0000-0000-0000-000000000092</guid>
+ <short-name>group92</short-name>
+ <full-name>Group 92</full-name>
+ <email>group92 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000093</uid>
+ <guid>20000000-0000-0000-0000-000000000093</guid>
+ <short-name>group93</short-name>
+ <full-name>Group 93</full-name>
+ <email>group93 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000094</uid>
+ <guid>20000000-0000-0000-0000-000000000094</guid>
+ <short-name>group94</short-name>
+ <full-name>Group 94</full-name>
+ <email>group94 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000095</uid>
+ <guid>20000000-0000-0000-0000-000000000095</guid>
+ <short-name>group95</short-name>
+ <full-name>Group 95</full-name>
+ <email>group95 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000096</uid>
+ <guid>20000000-0000-0000-0000-000000000096</guid>
+ <short-name>group96</short-name>
+ <full-name>Group 96</full-name>
+ <email>group96 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000097</uid>
+ <guid>20000000-0000-0000-0000-000000000097</guid>
+ <short-name>group97</short-name>
+ <full-name>Group 97</full-name>
+ <email>group97 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000098</uid>
+ <guid>20000000-0000-0000-0000-000000000098</guid>
+ <short-name>group98</short-name>
+ <full-name>Group 98</full-name>
+ <email>group98 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000099</uid>
+ <guid>20000000-0000-0000-0000-000000000099</guid>
+ <short-name>group99</short-name>
+ <full-name>Group 99</full-name>
+ <email>group99 at example.com</email>
+</record>
+<record type="group">
+ <uid>20000000-0000-0000-0000-000000000100</uid>
+ <guid>20000000-0000-0000-0000-000000000100</guid>
+ <short-name>group100</short-name>
+ <full-name>Group 100</full-name>
+ <email>group100 at example.com</email>
+</record>
</directory>
Modified: CalendarServer/trunk/requirements-dev.txt
===================================================================
--- CalendarServer/trunk/requirements-dev.txt 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/requirements-dev.txt 2014-11-12 18:09:15 UTC (rev 14156)
@@ -7,4 +7,4 @@
mockldap
q
--editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVClientLibrary/trunk@13420#egg=CalDAVClientLibrary
---editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVTester/trunk@14118#egg=CalDAVTester
+--editable svn+http://svn.calendarserver.org/repository/calendarserver/CalDAVTester/trunk@14154#egg=CalDAVTester
Modified: CalendarServer/trunk/requirements-stable.txt
===================================================================
--- CalendarServer/trunk/requirements-stable.txt 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/requirements-stable.txt 2014-11-12 18:09:15 UTC (rev 14156)
@@ -5,7 +5,7 @@
# For CalendarServer development, don't try to get these projects from PyPI; use svn.
-e .
--e svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14133#egg=twextpy
+-e svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@14155#egg=twextpy
-e svn+http://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk@13420#egg=kerberos
-e svn+http://svn.calendarserver.org/repository/calendarserver/PyCalendar/trunk@14025#egg=pycalendar
Modified: CalendarServer/trunk/twistedcaldav/cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/cache.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/twistedcaldav/cache.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -135,6 +135,40 @@
+class MemcacheURLPatternChangeNotifier(CachePoolUserMixIn):
+ """
+ A change notifier used to target arbitrary tokens.
+ """
+ log = Logger()
+
+ def __init__(self, urlPattern, cachePool=None, cacheHandle="Default"):
+ self._urlPattern = urlPattern
+ self._cachePool = cachePool
+ self._cachePoolHandle = cacheHandle
+
+
+ def _newCacheToken(self):
+ return str(uuid.uuid4())
+
+
+ def changed(self, token):
+ """
+ Change the cache token for a resource
+
+ return: A L{Deferred} that fires when the token has been changed.
+ """
+
+ url = self._urlPattern.format(token=token)
+
+ self.log.debug("Changing Cache Token for {url}", url=url)
+ return self.getCachePool().set(
+ 'cacheToken:{url}'.format(url=url),
+ self._newCacheToken(),
+ expireTime=config.ResponseCacheTimeout * 60,
+ )
+
+
+
class BaseResponseCache(object):
"""
A base class which provides some common operations
Modified: CalendarServer/trunk/twistedcaldav/controlapi.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/controlapi.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/twistedcaldav/controlapi.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -325,6 +325,7 @@
@inlineCallbacks
def action_refreshgroups(self, j):
txn = self._store.newTransaction()
+ yield txn.directoryService().flush()
wp = yield GroupCacherPollingWork.reschedule(txn, 0, force=True)
jobID = wp.workItem.jobID
yield txn.commit()
Modified: CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -303,14 +303,23 @@
principals.append(principal)
newUIDs.add(principal.principalUID())
- # Get the old set of UIDs
- # oldUIDs = (yield self._index().getMembers(self.uid))
+ # Get the old set of expanded UIDs
+ oldUIDs = set()
oldPrincipals = yield self.groupMembers()
- oldUIDs = [p.principalUID() for p in oldPrincipals]
+ oldUIDs.update([p.principalUID() for p in oldPrincipals])
+ oldPrincipals = yield self.expandedGroupMembers()
+ oldUIDs.update([p.principalUID() for p in oldPrincipals])
# Change membership
yield self.setGroupMemberSetPrincipals(principals)
+ # Get the new set of UIDs
+ newUIDs = set()
+ newPrincipals = yield self.groupMembers()
+ newUIDs.update([p.principalUID() for p in newPrincipals])
+ newPrincipals = yield self.expandedGroupMembers()
+ newUIDs.update([p.principalUID() for p in newPrincipals])
+
# Invalidate the primary principal's cache, and any principal's whose
# membership status changed
yield self.parent.cacheNotifier.changed()
Modified: CalendarServer/trunk/txdav/common/datastore/podding/directory.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/podding/directory.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/common/datastore/podding/directory.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -27,6 +27,55 @@
"""
@inlineCallbacks
+ def send_all_group_delegates(self, txn, server):
+ """
+ Request all group delegates on another pod.
+
+ @param txn: transaction to use
+ @type txn: L{CommonStoreTransaction}
+ @param server: server to query
+ @type server: L{Server}
+ """
+
+ request = {
+ "action": "all-group-delegates",
+ }
+ response = yield self.sendRequestToServer(txn, server, request)
+
+ if response["result"] == "ok":
+ returnValue(set(response["value"]))
+ elif response["result"] == "exception":
+ raise namedClass(response["class"])(response["result"])
+
+
+ @inlineCallbacks
+ def recv_all_group_delegates(self, txn, request):
+ """
+ Process an all group delegates cross-pod request. Request arguments as per L{send_all_group_delegates}.
+
+ @param request: request arguments
+ @type request: C{dict}
+ """
+
+ if request["action"] != "all-group-delegates":
+ raise FailedCrossPodRequestError("Wrong action '{}' for recv_all_group_delegates".format(request["action"]))
+
+ try:
+ delegatedUIDs = yield txn.allGroupDelegates()
+ except Exception as e:
+ returnValue({
+ "result": "exception",
+ "class": ".".join((e.__class__.__module__, e.__class__.__name__,)),
+ "request": str(e),
+ })
+
+ returnValue({
+ "result": "ok",
+ "value": list(delegatedUIDs),
+ })
+
+
+ @inlineCallbacks
def send_set_delegates(self, txn, delegator, delegates, readWrite):
"""
Set delegates for delegator on another pod.
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -1376,9 +1376,11 @@
)
if membershipChanged:
- yield self.synchronizeMembers(groupID, set(memberUIDs))
+ addedUIDs, removedUIDs = yield self.synchronizeMembers(groupID, set(memberUIDs))
+ else:
+ addedUIDs = removedUIDs = None
- returnValue(membershipChanged)
+ returnValue((membershipChanged, addedUIDs, removedUIDs,))
@inlineCallbacks
@@ -1394,22 +1396,19 @@
@param newMemberUIDs: set of new member UIDs in the group
@type newMemberUIDs: L{set} of L{str}
"""
- numRemoved = numAdded = 0
cachedMemberUIDs = (yield self.groupMemberUIDs(groupID))
removed = cachedMemberUIDs - newMemberUIDs
for memberUID in removed:
- numRemoved += 1
yield self.removeMemberFromGroup(memberUID, groupID)
added = newMemberUIDs - cachedMemberUIDs
for memberUID in added:
- numAdded += 1
yield self.addMemberToGroup(memberUID, groupID)
yield self.groupChanged(groupID, added, removed)
- returnValue((numAdded, numRemoved))
+ returnValue((added, removed,))
@inlineCallbacks
Modified: CalendarServer/trunk/txdav/dps/client.py
===================================================================
--- CalendarServer/trunk/txdav/dps/client.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/dps/client.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -44,7 +44,7 @@
WikiAccessForUIDCommand, ContinuationCommand,
StatsCommand, ExternalDelegatesCommand, ExpandedMemberUIDsCommand,
AddMembersCommand, RemoveMembersCommand,
- UpdateRecordsCommand, ExpandedMembersCommand
+ UpdateRecordsCommand, ExpandedMembersCommand, FlushCommand
)
from txdav.who.delegates import RecordType as DelegatesRecordType
from txdav.who.directory import (
@@ -423,6 +423,15 @@
@inlineCallbacks
+ def flush(self):
+ try:
+ yield self._sendCommand(FlushCommand)
+ returnValue(None)
+ except ConnectError:
+ returnValue(None)
+
+
+ @inlineCallbacks
def stats(self):
try:
result = yield self._sendCommand(StatsCommand)
Modified: CalendarServer/trunk/txdav/dps/commands.py
===================================================================
--- CalendarServer/trunk/txdav/dps/commands.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/dps/commands.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -266,6 +266,14 @@
+class FlushCommand(amp.Command):
+ arguments = []
+ response = [
+ ('flush', amp.Boolean()),
+ ]
+
+
+
class StatsCommand(amp.Command):
arguments = []
response = [
Modified: CalendarServer/trunk/txdav/dps/server.py
===================================================================
--- CalendarServer/trunk/txdav/dps/server.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/dps/server.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -41,7 +41,7 @@
WikiAccessForUIDCommand, ContinuationCommand,
ExternalDelegatesCommand, StatsCommand, ExpandedMemberUIDsCommand,
AddMembersCommand, RemoveMembersCommand,
- UpdateRecordsCommand, # RemoveRecordsCommand,
+ UpdateRecordsCommand, FlushCommand, # RemoveRecordsCommand,
)
from txdav.who.wiki import WikiAccessLevel
from zope.interface import implementer
@@ -647,6 +647,16 @@
returnValue(response)
+ @FlushCommand.responder
+ @inlineCallbacks
+ def flush(self):
+ yield self._directory.flush()
+ response = {
+ "flush": True,
+ }
+ returnValue(response)
+
+
@StatsCommand.responder
@inlineCallbacks
def stats(self):
Modified: CalendarServer/trunk/txdav/who/augment.py
===================================================================
--- CalendarServer/trunk/txdav/who/augment.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/who/augment.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -128,6 +128,10 @@
cls._timings[key] = (count, timeSpent)
+ def flush(self):
+ return self._directory.flush()
+
+
def stats(self):
results = {}
results.update(self._timings)
Modified: CalendarServer/trunk/txdav/who/cache.py
===================================================================
--- CalendarServer/trunk/txdav/who/cache.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/who/cache.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -416,5 +416,11 @@
)
+ @inlineCallbacks
+ def flush(self):
+ self.resetCache()
+ yield self._directory.flush()
+
+
def stats(self):
return self._directory.stats()
Modified: CalendarServer/trunk/txdav/who/groups.py
===================================================================
--- CalendarServer/trunk/txdav/who/groups.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/who/groups.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -23,11 +23,13 @@
from twext.enterprise.dal.syntax import Delete, Select, Parameter
from twext.enterprise.jobqueue import WorkItem, RegeneratingWorkItem
from twext.python.log import Logger
-from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed, \
+ DeferredList
from twistedcaldav.config import config
from txdav.caldav.datastore.sql import CalendarStoreFeatures
from txdav.common.datastore.sql_tables import schema, _BIND_MODE_OWN
import datetime
+import itertools
import time
log = Logger()
@@ -249,13 +251,15 @@
self, directory,
updateSeconds=600,
useDirectoryBasedDelegates=False,
- directoryBasedDelegatesSource=None
+ directoryBasedDelegatesSource=None,
+ cacheNotifier=None,
):
self.directory = directory
self.useDirectoryBasedDelegates = useDirectoryBasedDelegates
if useDirectoryBasedDelegates and directoryBasedDelegatesSource is None:
directoryBasedDelegatesSource = self.directory.recordsWithDirectoryBasedDelegates
self.directoryBasedDelegatesSource = directoryBasedDelegatesSource
+ self.cacheNotifier = cacheNotifier
self.updateSeconds = updateSeconds
@@ -440,19 +444,30 @@
)
if groupID:
- membershipChanged = yield txn.refreshGroup(
+ membershipChanged, addedUIDs, removedUIDs = yield txn.refreshGroup(
groupUID, record, groupID,
cachedName, cachedMembershipHash, cachedExtant
)
if membershipChanged:
self.log.info(
- "Membership changed for group {uid} {name}",
+ "Membership changed for group {uid} {name}:\n\tadded {added}\n\tremoved {removed}",
uid=groupUID,
- name=cachedName
+ name=cachedName,
+ added=",".join(addedUIDs),
+ removed=",".join(removedUIDs),
)
+
+ # Send cache change notifications
+ if self.cacheNotifier is not None:
+ self.cacheNotifier.changed(groupUID)
+ for uid in itertools.chain(addedUIDs, removedUIDs):
+ self.cacheNotifier.changed(uid)
+
+ # Notifier other store APIs of changes
wpsAttendee = yield self.scheduleGroupAttendeeReconciliations(txn, groupID)
wpsShareee = yield self.scheduleGroupShareeReconciliations(txn, groupID)
+
returnValue(wpsAttendee + wpsShareee)
else:
self.log.debug(
@@ -536,11 +551,24 @@
@inlineCallbacks
def groupsToRefresh(self, txn):
- delegatedUIDs = frozenset((yield txn.allGroupDelegates()))
+ delegatedUIDs = set((yield txn.allGroupDelegates()))
self.log.info(
"There are {count} group delegates", count=len(delegatedUIDs)
)
+ # Also get group delegates from other pods
+ if txn.directoryService().serversDB is not None and len(txn.directoryService().serversDB.allServersExceptThis()) != 0:
+ results = yield DeferredList([
+ txn.store().conduit.send_all_group_delegates(txn, server) for
+ server in txn.directoryService().serversDB.allServersExceptThis()
+ ], consumeErrors=True)
+ for result in results:
+ if result and result[0]:
+ delegatedUIDs.update(result[1])
+ self.log.info(
+ "There are {count} group delegates on this and other pods", count=len(delegatedUIDs)
+ )
+
# Get groupUIDs for all group attendees
ga = schema.GROUP_ATTENDEE
gr = schema.GROUPS
Modified: CalendarServer/trunk/txdav/who/test/test_delegates.py
===================================================================
--- CalendarServer/trunk/txdav/who/test/test_delegates.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/who/test/test_delegates.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -200,7 +200,7 @@
groupID, name, _ignore_membershipHash, _ignore_modified,
_ignore_extant
) = (yield txn.groupByUID(group1.uid))
- _ignore_numAdded, _ignore_numRemoved = (
+ _ignore_added, _ignore_removed = (
yield self.groupCacher.synchronizeMembers(txn, groupID, newSet)
)
delegates = (yield Delegates.delegatesOf(txn, delegator, True, expanded=True))
Modified: CalendarServer/trunk/txdav/who/test/test_groups.py
===================================================================
--- CalendarServer/trunk/txdav/who/test/test_groups.py 2014-11-12 18:05:43 UTC (rev 14155)
+++ CalendarServer/trunk/txdav/who/test/test_groups.py 2014-11-12 18:09:15 UTC (rev 14156)
@@ -131,13 +131,13 @@
)
)
newSet.add(record.uid)
- numAdded, numRemoved = (
+ added, removed = (
yield self.groupCacher.synchronizeMembers(
txn, groupID, newSet
)
)
- self.assertEquals(numAdded, 1)
- self.assertEquals(numRemoved, 2)
+ self.assertEquals(added, set(["__dre1__", ]))
+ self.assertEquals(removed, set(["__glyph1__", "__sagen1__", ]))
records = (yield self.groupCacher.cachedMembers(txn, groupID))
self.assertEquals(
set([r.shortNames[0] for r in records]),
@@ -145,11 +145,11 @@
)
# Remove all members
- numAdded, numRemoved = (
+ added, removed = (
yield self.groupCacher.synchronizeMembers(txn, groupID, set())
)
- self.assertEquals(numAdded, 0)
- self.assertEquals(numRemoved, 3)
+ self.assertEquals(added, set())
+ self.assertEquals(removed, set(["__wsanchez1__", "__cdaboo1__", "__dre1__", ]))
records = (yield self.groupCacher.cachedMembers(txn, groupID))
self.assertEquals(len(records), 0)
@@ -483,7 +483,133 @@
yield txn.commit()
+ @inlineCallbacks
+ def test_groupChangeCacheNotification(self):
+ """
+ Verify refreshGroup() triggers a cache notification for the group and all
+ members that are added or removed
+ """
+ class TestNotifier(object):
+ changedTokens = []
+ def changed(self, token):
+ self.changedTokens.append(token)
+
+ self.groupCacher.cacheNotifier = TestNotifier()
+
+ # No change
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__sub_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [])
+
+ # Add member to group
+ record = yield self.directory.recordWithUID(u"__top_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__dre1__")
+ yield record.addMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ # Remove member from group
+ record = yield self.directory.recordWithUID(u"__top_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__dre1__")
+ yield record.removeMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ # Add member to sub-group
+ record = yield self.directory.recordWithUID(u"__sub_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__dre1__")
+ yield record.addMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__sub_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__sub_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ # Remove member from sub-group
+ record = yield self.directory.recordWithUID(u"__sub_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__dre1__")
+ yield record.removeMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__sub_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__sub_group_1__",
+ "__dre1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ # Remove sub-group member from group
+ record = yield self.directory.recordWithUID(u"__top_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__sub_group_1__")
+ yield record.removeMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__sagen1__",
+ "__cdaboo1__",
+ ])
+ TestNotifier.changedTokens = []
+
+ # Add sub-group member to group
+ record = yield self.directory.recordWithUID(u"__top_group_1__")
+ addrecord = yield self.directory.recordWithUID(u"__sub_group_1__")
+ yield record.addMembers([addrecord, ])
+
+ yield self.groupCacher.refreshGroup(self.transactionUnderTest(), "__top_group_1__")
+ yield self.commit()
+
+ self.assertEqual(TestNotifier.changedTokens, [
+ "__top_group_1__",
+ "__sagen1__",
+ "__cdaboo1__",
+ ])
+ TestNotifier.changedTokens = []
+
+
+
class DynamicGroupTest(StoreTestCase):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20141112/0fb6dd1b/attachment-0001.html>
More information about the calendarserver-changes
mailing list