[CalendarServer-changes] [6823] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jan 28 14:44:05 PST 2011
Revision: 6823
http://trac.macosforge.org/projects/calendarserver/changeset/6823
Author: sagen at apple.com
Date: 2011-01-28 14:44:03 -0800 (Fri, 28 Jan 2011)
Log Message:
-----------
Adds home nodeName( ) method for retrieving pubsub node name (while also waiting for their creation)
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tap/util.py
CalendarServer/trunk/twistedcaldav/cache.py
CalendarServer/trunk/twistedcaldav/directory/test/test_livedirectory.py
CalendarServer/trunk/twistedcaldav/notify.py
CalendarServer/trunk/twistedcaldav/resource.py
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/common/datastore/file.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/common/datastore/test/util.py
CalendarServer/trunk/txdav/idav.py
Modified: CalendarServer/trunk/calendarserver/tap/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/util.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/calendarserver/tap/util.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -53,7 +53,7 @@
from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
from twistedcaldav.directory.sudo import SudoDirectoryService
from twistedcaldav.directory.wiki import WikiDirectoryService
-from twistedcaldav.notify import NotifierFactory
+from twistedcaldav.notify import NotifierFactory, getPubSubConfiguration
from twistedcaldav.directorybackedaddressbook import DirectoryBackedAddressBookResource
from twistedcaldav.resource import CalDAVResource, AuthenticationWrapper
from twistedcaldav.schedule import IScheduleInboxResource
@@ -172,6 +172,7 @@
notifierFactory = NotifierFactory(
config.Notifications.InternalNotificationHost,
config.Notifications.InternalNotificationPort,
+ pubSubConfig=getPubSubConfiguration(config)
)
else:
notifierFactory = None
Modified: CalendarServer/trunk/twistedcaldav/cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/cache.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/twistedcaldav/cache.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -436,3 +436,6 @@
def getID(self, label="default"):
return None
+
+ def nodeName(self, label="default"):
+ return succeed(None)
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_livedirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_livedirectory.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_livedirectory.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -182,6 +182,8 @@
if runODTests:
from twistedcaldav.directory.appleopendirectory import OpenDirectoryService
+ print "Running live OD tests"
+
class LiveODDirectoryServiceCase(LiveDirectoryTests, TestCase):
def setUp(self):
Modified: CalendarServer/trunk/twistedcaldav/notify.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/notify.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/twistedcaldav/notify.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -39,7 +39,7 @@
from twisted.internet.protocol import ReconnectingClientFactory, ServerFactory
from twisted.internet.ssl import ClientContextFactory
-from twisted.internet.defer import inlineCallbacks, Deferred
+from twisted.internet.defer import inlineCallbacks, Deferred, returnValue
from twisted.protocols.basic import LineReceiver
from twisted.plugin import IPlugin
from twisted.application import internet, service
@@ -142,6 +142,21 @@
else:
return "%s|%s" % (self._prefix, id)
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ id = self.getID(label=label)
+ pubSubConfig = self._notifierFactory.pubSubConfig
+ name = getPubSubPath(id, pubSubConfig)
+ try:
+ if self._notifierFactory.nodeCacher:
+ nodeCacher = self._notifierFactory.nodeCacher
+ else:
+ nodeCacher = getNodeCacher()
+ (yield nodeCacher.waitForNode(self, name))
+ except NodeCreationException, e:
+ self.log_warn(e)
+ returnValue(None)
+ returnValue(name)
class NotificationClientLineProtocol(LineReceiver, LoggingMixIn):
"""
@@ -205,10 +220,16 @@
gateway.
"""
- def __init__(self, host, port, reactor=None):
+ def __init__(self, gatewayHost, gatewayPort, pubSubConfig=None,
+ nodeCacher=None, reactor=None):
+
self.factory = None
- self.host = host
- self.port = port
+
+ self.gatewayHost = gatewayHost
+ self.gatewayPort = gatewayPort
+ self.pubSubConfig = pubSubConfig
+ self.nodeCacher = nodeCacher
+
self.observers = set()
self.queued = set()
@@ -219,7 +240,8 @@
def send(self, op, id):
if self.factory is None:
self.factory = NotificationClientFactory(self)
- self.reactor.connectTCP(self.host, self.port, self.factory)
+ self.reactor.connectTCP(self.gatewayHost, self.gatewayPort,
+ self.factory)
self.log_debug("Creating factory")
msg = "%s %s" % (op, str(id))
Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/twistedcaldav/resource.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -536,10 +536,8 @@
dataObject = getattr(self, "_newStoreObject")
if dataObject:
label = "collection" if isvirt else "default"
- notifierID = dataObject.notifierID(label=label)
- if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
- pubSubConfiguration = getPubSubConfiguration(config)
- nodeName = getPubSubPath(notifierID, pubSubConfiguration)
+ nodeName = (yield dataObject.nodeName(label=label))
+ if nodeName:
propVal = customxml.PubSubXMPPPushKeyProperty(nodeName)
returnValue(propVal)
@@ -2220,87 +2218,71 @@
returnValue(customxml.MaxCollections.fromString(config.MaxCollectionsPerHome))
elif qname == (customxml.calendarserver_namespace, "push-transports"):
- notifierID = self._newStoreHome.notifierID()
- if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
- children = []
+ if config.Notifications.Services.XMPPNotifier.Enabled:
+ nodeName = (yield self._newStoreHome.nodeName())
+ if nodeName:
+ notifierID = self._newStoreHome.notifierID()
+ if notifierID:
+ children = []
- apsConfiguration = getPubSubAPSConfiguration(notifierID, config)
- if apsConfiguration:
- children.append(
- customxml.PubSubTransportProperty(
- customxml.PubSubSubscriptionProperty(
- davxml.HRef(
- apsConfiguration["SubscriptionURL"]
- ),
- ),
- customxml.PubSubAPSBundleIDProperty(
- apsConfiguration["APSBundleID"]
- ),
- type="APSD",
- )
- )
+ apsConfiguration = getPubSubAPSConfiguration(notifierID, config)
+ if apsConfiguration:
+ children.append(
+ customxml.PubSubTransportProperty(
+ customxml.PubSubSubscriptionProperty(
+ davxml.HRef(
+ apsConfiguration["SubscriptionURL"]
+ ),
+ ),
+ customxml.PubSubAPSBundleIDProperty(
+ apsConfiguration["APSBundleID"]
+ ),
+ type="APSD",
+ )
+ )
- pubSubConfiguration = getPubSubConfiguration(config)
- if pubSubConfiguration['xmpp-server']:
- children.append(
- customxml.PubSubTransportProperty(
- customxml.PubSubXMPPServerProperty(
- pubSubConfiguration['xmpp-server']
- ),
- customxml.PubSubXMPPURIProperty(
- getPubSubXMPPURI(notifierID, pubSubConfiguration)
- ),
- type="XMPP",
- )
- )
+ pubSubConfiguration = getPubSubConfiguration(config)
+ if pubSubConfiguration['xmpp-server']:
+ children.append(
+ customxml.PubSubTransportProperty(
+ customxml.PubSubXMPPServerProperty(
+ pubSubConfiguration['xmpp-server']
+ ),
+ customxml.PubSubXMPPURIProperty(
+ getPubSubXMPPURI(notifierID, pubSubConfiguration)
+ ),
+ type="XMPP",
+ )
+ )
- returnValue(customxml.PubSubPushTransportsProperty(*children))
+ returnValue(customxml.PubSubPushTransportsProperty(*children))
- else:
- returnValue(customxml.PubSubPushTransportsProperty())
+ returnValue(customxml.PubSubPushTransportsProperty())
elif qname == (customxml.calendarserver_namespace, "pushkey"):
- notifierID = self._newStoreHome.notifierID()
- if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
- pubSubConfiguration = getPubSubConfiguration(config)
- nodeName = getPubSubPath(notifierID, pubSubConfiguration)
+ if config.Notifications.Services.XMPPNotifier.Enabled:
+ nodeName = (yield self._newStoreHome.nodeName())
+ if nodeName:
+ returnValue(customxml.PubSubXMPPPushKeyProperty(nodeName))
+ returnValue(customxml.PubSubXMPPPushKeyProperty())
- # Create the pubsub node so client has something to subscribe
- # to
- try:
- (yield getNodeCacher().waitForNode(
- self._newStoreHome._notifier, nodeName))
- except NodeCreationException, e:
- self.log_warn(e)
- returnValue(customxml.PubSubXMPPPushKeyProperty(nodeName))
- else:
- returnValue(customxml.PubSubXMPPPushKeyProperty())
-
-
elif qname == (customxml.calendarserver_namespace, "xmpp-uri"):
- notifierID = self._newStoreHome.notifierID()
- if notifierID is not None and config.Notifications.Services.XMPPNotifier.Enabled:
- pubSubConfiguration = getPubSubConfiguration(config)
+ if config.Notifications.Services.XMPPNotifier.Enabled:
+ nodeName = (yield self._newStoreHome.nodeName())
+ if nodeName:
+ notifierID = self._newStoreHome.notifierID()
+ if notifierID:
+ pubSubConfiguration = getPubSubConfiguration(config)
+ returnValue(customxml.PubSubXMPPURIProperty(
+ getPubSubXMPPURI(notifierID, pubSubConfiguration)))
- # Create the pubsub node so client has something to subscribe
- # to
- nodeName = getPubSubPath(notifierID, pubSubConfiguration)
- try:
- (yield getNodeCacher().waitForNode(
- self._newStoreHome._notifier, nodeName))
- except NodeCreationException, e:
- self.log_warn(e)
+ returnValue(customxml.PubSubXMPPURIProperty())
- returnValue(customxml.PubSubXMPPURIProperty(
- getPubSubXMPPURI(notifierID, pubSubConfiguration)))
- else:
- returnValue(customxml.PubSubXMPPURIProperty())
-
elif qname == (customxml.calendarserver_namespace, "xmpp-heartbeat-uri"):
- pubSubConfiguration = getPubSubConfiguration(config)
- if pubSubConfiguration['enabled']:
+ if config.Notifications.Services.XMPPNotifier.Enabled:
+ pubSubConfiguration = getPubSubConfiguration(config)
returnValue(
customxml.PubSubHeartbeatProperty(
customxml.PubSubHeartbeatURIProperty(
@@ -2311,16 +2293,14 @@
)
)
)
- else:
- returnValue(customxml.PubSubHeartbeatURIProperty())
+ returnValue(customxml.PubSubHeartbeatURIProperty())
elif qname == (customxml.calendarserver_namespace, "xmpp-server"):
- pubSubConfiguration = getPubSubConfiguration(config)
- if pubSubConfiguration['enabled']:
+ if config.Notifications.Services.XMPPNotifier.Enabled:
+ pubSubConfiguration = getPubSubConfiguration(config)
returnValue(customxml.PubSubXMPPServerProperty(
pubSubConfiguration['xmpp-server']))
- else:
- returnValue(customxml.PubSubXMPPServerProperty())
+ returnValue(customxml.PubSubXMPPServerProperty())
returnValue((yield super(CommonHomeResource, self).readProperty(property, request)))
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -405,8 +405,22 @@
self.assertEquals(calendar.notifierID(), "CalDAV|home1")
self.assertEquals(calendar.notifierID(label="collection"), "CalDAV|home1/calendar_1")
+ @inlineCallbacks
+ def test_nodeNameSuccess(self):
+ home = yield self.homeUnderTest()
+ name = yield home.nodeName()
+ self.assertEquals(name, "/CalDAV/example.com/home1/")
@inlineCallbacks
+ def test_nodeNameFailure(self):
+ # The StubNodeCacher is set up to fail when the node name has the
+ # word "fail" in it, for testing the failure mode:
+ home = yield self.transactionUnderTest().calendarHomeWithUID("fail",
+ create=True)
+ name = yield home.nodeName()
+ self.assertEquals(name, None)
+
+ @inlineCallbacks
def test_calendarHomeWithUID_exists(self):
"""
Finding an existing calendar home by UID results in an object that
Modified: CalendarServer/trunk/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/file.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/txdav/common/datastore/file.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -526,6 +526,16 @@
else:
return None
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ if self._notifiers:
+ for notifier in self._notifiers:
+ name = (yield notifier.nodeName(label=label))
+ if name is not None:
+ returnValue(name)
+ else:
+ returnValue(None)
+
def notifyChanged(self):
"""
Trigger a notification of a change
@@ -838,6 +848,16 @@
else:
return None
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ if self._notifiers:
+ for notifier in self._notifiers:
+ name = (yield notifier.nodeName(label=label))
+ if name is not None:
+ returnValue(name)
+ else:
+ returnValue(None)
+
def notifyChanged(self):
"""
Trigger a notification of a change
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -770,6 +770,16 @@
else:
return None
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ if self._notifiers:
+ for notifier in self._notifiers:
+ name = (yield notifier.nodeName(label=label))
+ if name is not None:
+ returnValue(name)
+ else:
+ returnValue(None)
+
def notifyChanged(self):
"""
Trigger a notification of a change
@@ -1566,6 +1576,16 @@
else:
return None
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ if self._notifiers:
+ for notifier in self._notifiers:
+ name = (yield notifier.nodeName(label=label))
+ if name is not None:
+ returnValue(name)
+ else:
+ returnValue(None)
+
def notifyChanged(self):
"""
Trigger a notification of a change
@@ -2131,6 +2151,15 @@
else:
return None
+ @inlineCallbacks
+ def nodeName(self, label="default"):
+ if self._notifiers:
+ for notifier in self._notifiers:
+ name = (yield notifier.nodeName(label=label))
+ if name is not None:
+ returnValue(name)
+ else:
+ returnValue(None)
def notifyChanged(self):
"""
Modified: CalendarServer/trunk/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/util.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/txdav/common/datastore/test/util.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -28,7 +28,7 @@
from twext.python.vcomponent import VComponent
from twisted.internet import reactor
-from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.defer import Deferred, inlineCallbacks, succeed
from twisted.internet.task import deferLater
from twisted.python import log
from twisted.application.service import Service
@@ -39,7 +39,7 @@
from txdav.common.icommondatastore import NoSuchHomeChildError
from twext.enterprise.adbapi2 import ConnectionPool
from twisted.internet.defer import returnValue
-from twistedcaldav.notify import Notifier
+from twistedcaldav.notify import Notifier, NodeCreationException
def allInstancesOf(cls):
@@ -283,7 +283,15 @@
return self.commit()
+class StubNodeCacher(object):
+ def waitForNode(self, notifier, nodeName):
+ if "fail" in nodeName:
+ raise NodeCreationException("Could not create node")
+ else:
+ return succeed(True)
+
+
class StubNotifierFactory(object):
"""
For testing push notifications without an XMPP server.
@@ -291,6 +299,13 @@
def __init__(self):
self.reset()
+ self.nodeCacher = StubNodeCacher()
+ self.pubSubConfig = {
+ "enabled" : True,
+ "service" : "pubsub.example.com",
+ "host" : "example.com",
+ "port" : "123",
+ }
def newNotifier(self, label="default", id=None, prefix=None):
return Notifier(self, label=label, id=id, prefix=prefix)
Modified: CalendarServer/trunk/txdav/idav.py
===================================================================
--- CalendarServer/trunk/txdav/idav.py 2011-01-28 22:28:21 UTC (rev 6822)
+++ CalendarServer/trunk/txdav/idav.py 2011-01-28 22:44:03 UTC (rev 6823)
@@ -236,3 +236,25 @@
@return: a string (or None if notifications are disabled)
"""
+
+ def nodeName(label):
+ """
+ Returns a pubsub node path.
+
+ A pubsub node path is comprised of the following values:
+
+ /<protocol>/<hostname>/<notifierID>/
+
+ <protocol> is either CalDAV or CardDAV
+ <hostname> is the name of the calendar server
+ <notifierID> is a unique string representing the resource
+
+ This method builds this string based on pubsub configuration
+ that was passed to the NotifierFactory, and it also attempts
+ to create and configure the node in the pubsub server. If that
+ fails, a value of None will be returned. This is used when a client
+ requests push-related DAV properties.
+
+ @return: a deferred to a string (or None if notifications are disabled
+ or the node could not be created)
+ """
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110128/ea0db73d/attachment-0001.html>
More information about the calendarserver-changes
mailing list