[CalendarServer-changes] [2906] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Aug 28 21:39:45 PDT 2008
Revision: 2906
http://trac.macosforge.org/projects/calendarserver/changeset/2906
Author: sagen at apple.com
Date: 2008-08-28 21:39:43 -0700 (Thu, 28 Aug 2008)
Log Message:
-----------
Fix for <rdar://problem/6166330> Calendar server should periodically publish a heartbeat node to let clients know notifications are in fact working
Modified Paths:
--------------
CalendarServer/trunk/conf/caldavd-test.plist
CalendarServer/trunk/conf/caldavd.plist
CalendarServer/trunk/twistedcaldav/config.py
CalendarServer/trunk/twistedcaldav/customxml.py
CalendarServer/trunk/twistedcaldav/notify.py
CalendarServer/trunk/twistedcaldav/static.py
CalendarServer/trunk/twistedcaldav/test/test_notify.py
Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/conf/caldavd-test.plist 2008-08-29 04:39:43 UTC (rev 2906)
@@ -526,6 +526,10 @@
<key>KeepAliveSeconds</key>
<integer>120</integer>
+ <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+ <key>HeartbeatSeconds</key>
+ <integer>1800</integer>
+
<!-- List of glob-like expressions defining which XMPP JIDs can converse with the server -->
<key>AllowedJIDs</key>
<array>
Modified: CalendarServer/trunk/conf/caldavd.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd.plist 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/conf/caldavd.plist 2008-08-29 04:39:43 UTC (rev 2906)
@@ -318,6 +318,10 @@
<!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
<key>KeepAliveSeconds</key>
<integer>120</integer>
+
+ <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
+ <key>HeartbeatSeconds</key>
+ <integer>1800</integer>
</dict>
</array>
</dict>
Modified: CalendarServer/trunk/twistedcaldav/config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/config.py 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/twistedcaldav/config.py 2008-08-29 04:39:43 UTC (rev 2906)
@@ -242,6 +242,7 @@
"Password" : "",
"ServiceAddress" : "", # "pubsub.xmpp.host.name"
"KeepAliveSeconds" : 120,
+ "HeartbeatSeconds" : 1800, # 30 minute pubsub heartbeat
"AllowedJIDs": [],
},
]
Modified: CalendarServer/trunk/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/customxml.py 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/twistedcaldav/customxml.py 2008-08-29 04:39:43 UTC (rev 2906)
@@ -253,6 +253,15 @@
name = "xmpp-uri"
protected = True
+class PubSubHeartbeatURIProperty (davxml.WebDAVTextElement):
+ """
+ A calendarhomefile property to indicate the pubsub XMPP URI to subscribe to
+ for server heartbeats.
+ """
+ namespace = calendarserver_namespace
+ name = "xmpp-heartbeat-uri"
+ protected = True
+
class IScheduleInbox (davxml.WebDAVEmptyElement):
"""
Denotes the resourcetype of a iSchedule Inbox.
@@ -269,6 +278,7 @@
namespace = calendarserver_namespace
name = "free-busy-url"
+
##
# Extensions to davxml.ResourceType
##
Modified: CalendarServer/trunk/twistedcaldav/notify.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/notify.py 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/twistedcaldav/notify.py 2008-08-29 04:39:43 UTC (rev 2906)
@@ -34,7 +34,6 @@
# TODO: bindAddress to local
# TODO: add CalDAVTester test for examining new xmpp-uri property
-# TODO: auto-registration and roster management for XMPP
from twisted.internet import protocol
from twisted.protocols import basic
@@ -55,6 +54,7 @@
"Coalescer",
"getNotificationClient",
"getPubSubConfiguration",
+ "getPubSubHeartbeatURI",
"getPubSubPath",
"getPubSubXMPPURI",
"INotifier",
@@ -488,16 +488,25 @@
'pubsub#persist_items' : '0',
}
- def __init__(self, settings, reactor=None, configOverride=None):
+ def __init__(self, settings, reactor=None, configOverride=None,
+ heartbeat=True, roster=True):
self.xmlStream = None
self.settings = settings
if reactor is None:
from twisted.internet import reactor
self.reactor = reactor
self.config = configOverride or config
+ self.doHeartbeat = heartbeat
+ self.doRoster = roster
self.roster = {}
+ def sendHeartbeat(self):
+ if self.doHeartbeat and self.xmlStream is not None:
+ self.enqueue("")
+ self.reactor.callLater(self.settings['HeartbeatSeconds'],
+ self.sendHeartbeat)
+
def enqueue(self, uri):
if self.xmlStream is not None:
# Convert uri to node
@@ -634,11 +643,12 @@
def requestRoster(self):
- self.roster = {}
- rosterIq = IQ(self.xmlStream, type='get')
- rosterIq.addElement("query", "jabber:iq:roster")
- rosterIq.addCallback(self.handleRoster)
- rosterIq.send()
+ if self.doRoster:
+ self.roster = {}
+ rosterIq = IQ(self.xmlStream, type='get')
+ rosterIq.addElement("query", "jabber:iq:roster")
+ rosterIq.addCallback(self.handleRoster)
+ rosterIq.send()
def allowedInRoster(self, jid):
for pattern in self.settings.get("AllowedJIDs", []):
@@ -720,6 +730,7 @@
xmlStream.addObserver('/message', self.handleMessage)
xmlStream.addObserver('/presence', self.handlePresence)
self.requestRoster()
+ self.sendHeartbeat()
def streamClosed(self):
@@ -789,7 +800,7 @@
class XMPPNotificationFactory(xmlstream.XmlStreamFactory, LoggingMixIn):
- def __init__(self, notifier, settings, reactor=None):
+ def __init__(self, notifier, settings, reactor=None, keepAlive=True):
self.log_info("Setting up XMPPNotificationFactory")
self.notifier = notifier
@@ -798,6 +809,7 @@
self.keepAliveSeconds = settings.get('KeepAliveSeconds', 120)
self.xmlStream = None
self.presenceCall = None
+ self.doKeepAlive = keepAlive
if reactor is None:
from twisted.internet import reactor
self.reactor = reactor
@@ -845,7 +857,7 @@
(self.jid,))
def sendPresence(self):
- if self.xmlStream is not None:
+ if self.doKeepAlive and self.xmlStream is not None:
presence = domish.Element(('jabber:client', 'presence'))
self.xmlStream.send(presence)
self.presenceCall = self.reactor.callLater(self.keepAliveSeconds,
@@ -876,13 +888,20 @@
return results
def getPubSubPath(uri, pubSubConfiguration):
- return ("/Public/CalDAV/%s/%d/%s/" % (pubSubConfiguration['host'],
- pubSubConfiguration['port'], uri.strip("/")))
+ path = "/Public/CalDAV/%s/%d/" % (pubSubConfiguration['host'],
+ pubSubConfiguration['port'])
+ if uri:
+ path += "%s/" % (uri.strip("/"),)
+ return path
def getPubSubXMPPURI(uri, pubSubConfiguration):
return "xmpp:%s?pubsub;node=%s" % (pubSubConfiguration['service'],
getPubSubPath(uri, pubSubConfiguration))
+def getPubSubHeartbeatURI(pubSubConfiguration):
+ return "xmpp:%s?pubsub;node=%s" % (pubSubConfiguration['service'],
+ getPubSubPath("", pubSubConfiguration))
+
#
# Notification Server service config
#
Modified: CalendarServer/trunk/twistedcaldav/static.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/static.py 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/twistedcaldav/static.py 2008-08-29 04:39:43 UTC (rev 2906)
@@ -75,6 +75,7 @@
from twistedcaldav.timezoneservice import TimezoneServiceResource
from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin
from twistedcaldav.notify import getPubSubConfiguration, getPubSubXMPPURI
+from twistedcaldav.notify import getPubSubHeartbeatURI
log = Logger()
@@ -598,6 +599,7 @@
liveProperties = CalDAVFile.liveProperties + (
(customxml.calendarserver_namespace, "xmpp-uri"),
+ (customxml.calendarserver_namespace, "xmpp-heartbeat-uri"),
)
def __init__(self, path, parent, record):
@@ -663,6 +665,14 @@
else:
return succeed(customxml.PubSubXMPPURIProperty())
+ elif qname == (customxml.calendarserver_namespace, "xmpp-heartbeat-uri"):
+ pubSubConfiguration = getPubSubConfiguration(config)
+ if pubSubConfiguration['enabled']:
+ return succeed(customxml.PubSubHeartbeatURIProperty(
+ getPubSubHeartbeatURI(pubSubConfiguration)))
+ else:
+ return succeed(customxml.PubSubHeartbeatURIProperty())
+
return super(CalendarHomeFile, self).readProperty(property, request)
Modified: CalendarServer/trunk/twistedcaldav/test/test_notify.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_notify.py 2008-08-29 02:43:07 UTC (rev 2905)
+++ CalendarServer/trunk/twistedcaldav/test/test_notify.py 2008-08-29 04:39:43 UTC (rev 2906)
@@ -335,7 +335,7 @@
self.xmlStream = StubXmlStream()
self.settings = { 'ServiceAddress' : 'pubsub.example.com' }
self.notifier = XMPPNotifier(self.settings, reactor=Clock(),
- configOverride=self.xmppEnabledConfig)
+ configOverride=self.xmppEnabledConfig, heartbeat=False)
self.notifier.streamOpened(self.xmlStream)
def test_sendWhileConnected(self):
@@ -456,7 +456,41 @@
str(valueElement))
+ def test_sendHeartbeat(self):
+ xmppConfig = Config(config_mod.defaultConfig)
+ xmppConfig.Notifications['Services'][1]['Enabled'] = True
+ xmppConfig.ServerHostName = "server.example.com"
+ xmppConfig.HTTPPort = 80
+
+ clock = Clock()
+ xmlStream = StubXmlStream()
+ settings = { 'ServiceAddress' : 'pubsub.example.com', 'JID' : 'jid',
+ 'Password' : 'password', 'KeepAliveSeconds' : 5,
+ 'HeartbeatSeconds' : 1800 }
+ notifier = XMPPNotifier(settings, reactor=clock, heartbeat=True,
+ roster=False, configOverride=xmppConfig)
+ factory = XMPPNotificationFactory(notifier, settings, reactor=clock,
+ keepAlive=False)
+ factory.connected(xmlStream)
+ factory.authenticated(xmlStream)
+
+ self.assertEquals(len(xmlStream.elements), 1)
+ heartbeat = xmlStream.elements[0]
+ self.assertEquals(heartbeat.name, 'iq')
+
+ clock.advance(1800)
+
+ self.assertEquals(len(xmlStream.elements), 2)
+ heartbeat = xmlStream.elements[1]
+ self.assertEquals(heartbeat.name, 'iq')
+
+ factory.disconnected(xmlStream)
+ clock.advance(1800)
+ self.assertEquals(len(xmlStream.elements), 2)
+
+
+
class XMPPNotificationFactoryTests(TestCase):
def test_sendPresence(self):
@@ -464,7 +498,7 @@
xmlStream = StubXmlStream()
settings = { 'ServiceAddress' : 'pubsub.example.com', 'JID' : 'jid',
'Password' : 'password', 'KeepAliveSeconds' : 5 }
- notifier = XMPPNotifier(settings, reactor=clock)
+ notifier = XMPPNotifier(settings, reactor=clock, heartbeat=False)
factory = XMPPNotificationFactory(notifier, settings, reactor=clock)
factory.connected(xmlStream)
factory.authenticated(xmlStream)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080828/52371dcf/attachment-0001.html
More information about the calendarserver-changes
mailing list