comparison sat_pubsub/iidavoll.py @ 232:923281d4c5bc

renamed idavoll directory to sat_pubsub
author Goffi <goffi@goffi.org>
date Thu, 17 May 2012 12:48:14 +0200
parents idavoll/iidavoll.py@274a45d2a5ab
children 564ae55219e1
comparison
equal deleted inserted replaced
231:d99047cd90f9 232:923281d4c5bc
1 # Copyright (c) 2003-2008 Ralph Meijer
2 # See LICENSE for details.
3
4 """
5 Interfaces for idavoll.
6 """
7
8 from zope.interface import Attribute, Interface
9
10 class IBackendService(Interface):
11 """ Interface to a backend service of a pubsub service. """
12
13
14 def __init__(storage):
15 """
16 @param storage: Object providing L{IStorage}.
17 """
18
19
20 def supportsPublisherAffiliation():
21 """ Reports if the backend supports the publisher affiliation.
22
23 @rtype: C{bool}
24 """
25
26
27 def supportsOutcastAffiliation():
28 """ Reports if the backend supports the publisher affiliation.
29
30 @rtype: C{bool}
31 """
32
33
34 def supportsPersistentItems():
35 """ Reports if the backend supports persistent items.
36
37 @rtype: C{bool}
38 """
39
40
41 def getNodeType(nodeIdentifier):
42 """ Return type of a node.
43
44 @return: a deferred that returns either 'leaf' or 'collection'
45 """
46
47
48 def getNodes():
49 """ Returns list of all nodes.
50
51 @return: a deferred that returns a C{list} of node ids.
52 """
53
54
55 def getNodeMetaData(nodeIdentifier):
56 """ Return meta data for a node.
57
58 @return: a deferred that returns a C{list} of C{dict}s with the
59 metadata.
60 """
61
62
63 def createNode(nodeIdentifier, requestor):
64 """ Create a node.
65
66 @return: a deferred that fires when the node has been created.
67 """
68
69
70 def registerPreDelete(preDeleteFn):
71 """ Register a callback that is called just before a node deletion.
72
73 The function C{preDeletedFn} is added to a list of functions to be
74 called just before deletion of a node. The callback C{preDeleteFn} is
75 called with the C{nodeIdentifier} that is about to be deleted and
76 should return a deferred that returns a list of deferreds that are to
77 be fired after deletion. The backend collects the lists from all these
78 callbacks before actually deleting the node in question. After
79 deletion all collected deferreds are fired to do post-processing.
80
81 The idea is that you want to be able to collect data from the node
82 before deleting it, for example to get a list of subscribers that have
83 to be notified after the node has been deleted. To do this,
84 C{preDeleteFn} fetches the subscriber list and passes this list to a
85 callback attached to a deferred that it sets up. This deferred is
86 returned in the list of deferreds.
87 """
88
89
90 def deleteNode(nodeIdentifier, requestor):
91 """ Delete a node.
92
93 @return: a deferred that fires when the node has been deleted.
94 """
95
96
97 def purgeNode(nodeIdentifier, requestor):
98 """ Removes all items in node from persistent storage """
99
100
101 def subscribe(nodeIdentifier, subscriber, requestor):
102 """ Request the subscription of an entity to a pubsub node.
103
104 Depending on the node's configuration and possible business rules, the
105 C{subscriber} is added to the list of subscriptions of the node with id
106 C{nodeIdentifier}. The C{subscriber} might be different from the
107 C{requestor}, and if the C{requestor} is not allowed to subscribe this
108 entity an exception should be raised.
109
110 @return: a deferred that returns the subscription state
111 """
112
113
114 def unsubscribe(nodeIdentifier, subscriber, requestor):
115 """ Cancel the subscription of an entity to a pubsub node.
116
117 The subscription of C{subscriber} is removed from the list of
118 subscriptions of the node with id C{nodeIdentifier}. If the
119 C{requestor} is not allowed to unsubscribe C{subscriber}, an an
120 exception should be raised.
121
122 @return: a deferred that fires when unsubscription is complete.
123 """
124
125
126 def getSubscribers(nodeIdentifier):
127 """ Get node subscriber list.
128
129 @return: a deferred that fires with the list of subscribers.
130 """
131
132
133 def getSubscriptions(entity):
134 """ Report the list of current subscriptions with this pubsub service.
135
136 Report the list of the current subscriptions with all nodes within this
137 pubsub service, for the C{entity}.
138
139 @return: a deferred that returns the list of all current subscriptions
140 as tuples C{(nodeIdentifier, subscriber, subscription)}.
141 """
142
143
144 def getAffiliations(entity):
145 """ Report the list of current affiliations with this pubsub service.
146
147 Report the list of the current affiliations with all nodes within this
148 pubsub service, for the C{entity}.
149
150 @return: a deferred that returns the list of all current affiliations
151 as tuples C{(nodeIdentifier, affiliation)}.
152 """
153
154
155 def publish(nodeIdentifier, items, requestor):
156 """ Publish items to a pubsub node.
157
158 @return: a deferred that fires when the items have been published.
159 @rtype: L{Deferred<twisted.internet.defer.Deferred>}
160 """
161
162
163 def registerNotifier(observerfn, *args, **kwargs):
164 """ Register callback which is called for notification. """
165
166
167 def getNotifications(nodeIdentifier, items):
168 """
169 Get notification list.
170
171 This method is called to discover which entities should receive
172 notifications for the given items that have just been published to the
173 given node.
174
175 The notification list contains tuples (subscriber, subscriptions,
176 items) to result in one notification per tuple: the given subscriptions
177 yielded the given items to be notified to this subscriber. This
178 structure is needed allow for letting the subscriber know which
179 subscriptions yielded which notifications, while catering for
180 collection nodes and content-based subscriptions.
181
182 To minimize the amount of notifications per entity, implementers
183 should take care that if all items in C{items} were yielded
184 by the same set of subscriptions, exactly one tuple is for this
185 subscriber is returned, so that the subscriber would get exactly one
186 notification. Alternatively, one tuple per subscription combination.
187
188 @param nodeIdentifier: The identifier of the node the items were
189 published to.
190 @type nodeIdentifier: C{unicode}.
191 @param items: The list of published items as
192 L{Element<twisted.words.xish.domish.Element>}s.
193 @type items: C{list}
194 @return: The notification list as tuples of
195 (L{JID<twisted.words.protocols.jabber.jid.JID>},
196 C{list} of L{Subscription<wokkel.pubsub.Subscription>},
197 C{list} of L{Element<twisted.words.xish.domish.Element>}.
198 @rtype: C{list}
199 """
200
201
202 def getItems(nodeIdentifier, requestor, maxItems=None, itemIdentifiers=[]):
203 """ Retrieve items from persistent storage
204
205 If C{maxItems} is given, return the C{maxItems} last published
206 items, else if C{itemIdentifiers} is not empty, return the items
207 requested. If neither is given, return all items.
208
209 @return: a deferred that returns the requested items
210 """
211
212
213 def retractItem(nodeIdentifier, itemIdentifier, requestor):
214 """ Removes item in node from persistent storage """
215
216
217
218 class IStorage(Interface):
219 """
220 Storage interface.
221 """
222
223
224 def getNode(nodeIdentifier):
225 """
226 Get Node.
227
228 @param nodeIdentifier: NodeID of the desired node.
229 @type nodeIdentifier: C{str}
230 @return: deferred that returns a L{INode} providing object.
231 """
232
233
234 def getNodeIds():
235 """
236 Return all NodeIDs.
237
238 @return: deferred that returns a list of NodeIDs (C{unicode}).
239 """
240
241
242 def createNode(nodeIdentifier, owner, config):
243 """
244 Create new node.
245
246 The implementation should make sure, the passed owner JID is stripped
247 of the resource (e.g. using C{owner.userhostJID()}). The passed config
248 is expected to have values for the fields returned by
249 L{getDefaultConfiguration}, as well as a value for
250 C{'pubsub#node_type'}.
251
252 @param nodeIdentifier: NodeID of the new node.
253 @type nodeIdentifier: C{unicode}
254 @param owner: JID of the new nodes's owner.
255 @type owner: L{JID<twisted.words.protocols.jabber.jid.JID>}
256 @param config: Node configuration.
257 @type config: C{dict}
258 @return: deferred that fires on creation.
259 """
260
261
262 def deleteNode(nodeIdentifier):
263 """
264 Delete a node.
265
266 @param nodeIdentifier: NodeID of the new node.
267 @type nodeIdentifier: C{unicode}
268 @return: deferred that fires on deletion.
269 """
270
271
272 def getAffiliations(entity):
273 """
274 Get all affiliations for entity.
275
276 The implementation should make sure, the passed owner JID is stripped
277 of the resource (e.g. using C{owner.userhostJID()}).
278
279 @param entity: JID of the entity.
280 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
281 @return: deferred that returns a C{list} of tuples of the form
282 C{(nodeIdentifier, affiliation)}, where C{nodeIdentifier} is
283 of the type L{unicode} and C{affiliation} is one of
284 C{'owner'}, C{'publisher'} and C{'outcast'}.
285 """
286
287
288 def getSubscriptions(entity):
289 """
290 Get all subscriptions for an entity.
291
292 The implementation should make sure, the passed owner JID is stripped
293 of the resource (e.g. using C{owner.userhostJID()}).
294
295 @param entity: JID of the entity.
296 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
297 @return: deferred that returns a C{list} of tuples of the form
298 C{(nodeIdentifier, subscriber, state)}, where
299 C{nodeIdentifier} is of the type C{unicode}, C{subscriber} of
300 the type J{JID<twisted.words.protocols.jabber.jid.JID>}, and
301 C{state} is C{'subscribed'}, C{'pending'} or
302 C{'unconfigured'}.
303 """
304
305
306 def getDefaultConfiguration(nodeType):
307 """
308 Get the default configuration for the given node type.
309
310 @param nodeType: Either C{'leaf'} or C{'collection'}.
311 @type nodeType: C{str}
312 @return: The default configuration.
313 @rtype: C{dict}.
314 @raises: L{idavoll.error.NoCollections} if collections are not
315 supported.
316 """
317
318
319
320 class INode(Interface):
321 """
322 Interface to the class of objects that represent nodes.
323 """
324
325 nodeType = Attribute("""The type of this node. One of {'leaf'},
326 {'collection'}.""")
327 nodeIdentifier = Attribute("""The node identifer of this node""")
328
329
330 def getType():
331 """
332 Get node's type.
333
334 @return: C{'leaf'} or C{'collection'}.
335 """
336
337
338 def getConfiguration():
339 """
340 Get node's configuration.
341
342 The configuration must at least have two options:
343 C{pubsub#persist_items}, and C{pubsub#deliver_payloads}.
344
345 @return: C{dict} of configuration options.
346 """
347
348
349 def getMetaData():
350 """
351 Get node's meta data.
352
353 The meta data must be a superset of the configuration options, and
354 also at least should have a C{pubsub#node_type} entry.
355
356 @return: C{dict} of meta data.
357 """
358
359
360 def setConfiguration(options):
361 """
362 Set node's configuration.
363
364 The elements of {options} will set the new values for those
365 configuration items. This means that only changing items have to
366 be given.
367
368 @param options: a dictionary of configuration options.
369 @returns: a deferred that fires upon success.
370 """
371
372
373 def getAffiliation(entity):
374 """
375 Get affiliation of entity with this node.
376
377 @param entity: JID of entity.
378 @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
379 @return: deferred that returns C{'owner'}, C{'publisher'}, C{'outcast'}
380 or C{None}.
381 """
382
383
384 def getSubscription(subscriber):
385 """
386 Get subscription to this node of subscriber.
387
388 @param subscriber: JID of the new subscriptions' entity.
389 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
390 @return: deferred that returns the subscription state (C{'subscribed'},
391 C{'pending'} or C{None}).
392 """
393
394
395 def getSubscriptions(state=None):
396 """
397 Get list of subscriptions to this node.
398
399 The optional C{state} argument filters the subscriptions to their
400 state.
401
402 @param state: Subscription state filter. One of C{'subscribed'},
403 C{'pending'}, C{'unconfigured'}.
404 @type state: C{str}
405 @return: a deferred that returns a C{list} of
406 L{wokkel.pubsub.Subscription}s.
407 """
408
409
410 def addSubscription(subscriber, state, config):
411 """
412 Add new subscription to this node with given state.
413
414 @param subscriber: JID of the new subscriptions' entity.
415 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
416 @param state: C{'subscribed'} or C{'pending'}
417 @type state: C{str}
418 @param config: Subscription configuration.
419 @param config: C{dict}
420 @return: deferred that fires on subscription.
421 """
422
423
424 def removeSubscription(subscriber):
425 """
426 Remove subscription to this node.
427
428 @param subscriber: JID of the subscriptions' entity.
429 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
430 @return: deferred that fires on removal.
431 """
432
433
434 def isSubscribed(entity):
435 """
436 Returns whether entity has any subscription to this node.
437
438 Only returns C{True} when the subscription state (if present) is
439 C{'subscribed'} for any subscription that matches the bare JID.
440
441 @param subscriber: bare JID of the subscriptions' entity.
442 @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
443 @return: deferred that returns a C{bool}.
444 """
445
446
447 def getAffiliations():
448 """
449 Get affiliations of entities with this node.
450
451 @return: deferred that returns a C{list} of tuples (jid, affiliation),
452 where jid is a L(JID<twisted.words.protocols.jabber.jid.JID>)
453 and affiliation is one of C{'owner'},
454 C{'publisher'}, C{'outcast'}.
455 """
456
457
458
459 class ILeafNode(Interface):
460 """
461 Interface to the class of objects that represent leaf nodes.
462 """
463
464 def storeItems(items, publisher):
465 """
466 Store items in persistent storage for later retrieval.
467
468 @param items: The list of items to be stored. Each item is the
469 L{domish} representation of the XML fragment as defined
470 for C{<item/>} in the
471 C{http://jabber.org/protocol/pubsub} namespace.
472 @type items: C{list} of {domish.Element}
473 @param publisher: JID of the publishing entity.
474 @type publisher: L{JID<twisted.words.protocols.jabber.jid.JID>}
475 @return: deferred that fires upon success.
476 """
477
478
479 def removeItems(itemIdentifiers):
480 """
481 Remove items by id.
482
483 @param itemIdentifiers: C{list} of item ids.
484 @return: deferred that fires with a C{list} of ids of the items that
485 were deleted
486 """
487
488
489 def getItems(maxItems=None):
490 """
491 Get items.
492
493 If C{maxItems} is not given, all items in the node are returned,
494 just like C{getItemsById}. Otherwise, C{maxItems} limits
495 the returned items to a maximum of that number of most recently
496 published items.
497
498 @param maxItems: if given, a natural number (>0) that limits the
499 returned number of items.
500 @return: deferred that fires with a C{list} of found items.
501 """
502
503
504 def getItemsById(itemIdentifiers):
505 """
506 Get items by item id.
507
508 Each item in the returned list is a unicode string that
509 represent the XML of the item as it was published, including the
510 item wrapper with item id.
511
512 @param itemIdentifiers: C{list} of item ids.
513 @return: deferred that fires with a C{list} of found items.
514 """
515
516
517 def purge():
518 """
519 Purge node of all items in persistent storage.
520
521 @return: deferred that fires when the node has been purged.
522 """
523
524
525
526 class IGatewayStorage(Interface):
527
528 def addCallback(service, nodeIdentifier, callback):
529 """
530 Register a callback URI.
531
532 The registered HTTP callback URI will have an Atom Entry documented
533 POSTed to it upon receiving a notification for the given pubsub node.
534
535 @param service: The XMPP entity that holds the node.
536 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
537 @param nodeIdentifier: The identifier of the publish-subscribe node.
538 @type nodeIdentifier: C{unicode}.
539 @param callback: The callback URI to be registered.
540 @type callback: C{str}.
541 @rtype: L{Deferred<twisted.internet.defer.Deferred>}
542 """
543
544 def removeCallback(service, nodeIdentifier, callback):
545 """
546 Remove a registered callback URI.
547
548 The returned deferred will fire with a boolean that signals wether or
549 not this was the last callback unregistered for this node.
550
551 @param service: The XMPP entity that holds the node.
552 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
553 @param nodeIdentifier: The identifier of the publish-subscribe node.
554 @type nodeIdentifier: C{unicode}.
555 @param callback: The callback URI to be unregistered.
556 @type callback: C{str}.
557 @rtype: L{Deferred<twisted.internet.defer.Deferred>}
558 """
559
560 def getCallbacks(service, nodeIdentifier):
561 """
562 Get the callbacks registered for this node.
563
564 Returns a deferred that fires with the set of HTTP callback URIs
565 registered for this node.
566
567 @param service: The XMPP entity that holds the node.
568 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
569 @param nodeIdentifier: The identifier of the publish-subscribe node.
570 @type nodeIdentifier: C{unicode}.
571 @rtype: L{Deferred<twisted.internet.defer.Deferred>}
572 """
573
574
575 def hasCallbacks(service, nodeIdentifier):
576 """
577 Return wether there are callbacks registered for a node.
578
579 @param service: The XMPP entity that holds the node.
580 @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
581 @param nodeIdentifier: The identifier of the publish-subscribe node.
582 @type nodeIdentifier: C{unicode}.
583 @returns: Deferred that fires with a boolean.
584 @rtype: L{Deferred<twisted.internet.defer.Deferred>}
585 """