Mercurial > libervia-pubsub
annotate idavoll/backend.py @ 23:884268687229
Simplify call chain by mapping incoming requests directly to method
calls in pubsub.py, and providing a exception handler for all backend
calls.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Thu, 07 Oct 2004 15:57:05 +0000 |
parents | eddea65d1032 |
children | 4f3bbefc6fad |
rev | line source |
---|---|
1 | 1 from twisted.application import service |
2 from twisted.python import components, failure | |
3 from twisted.internet import defer, reactor | |
15 | 4 from twisted.protocols.jabber import jid |
1 | 5 |
6 class IBackendService(components.Interface): | |
7 """ Interface to a backend service of a pubsub service """ | |
8 | |
2 | 9 def do_publish(self, node, publisher, item): |
10 """ Returns a deferred that returns """ | |
11 | |
1 | 12 class BackendException(Exception): |
13 def __init__(self, msg = ''): | |
14 self.msg = msg | |
15 | |
16 def __str__(self): | |
17 return self.msg | |
18 | |
19 class NodeNotFound(BackendException): | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
20 def __init__(self, msg = 'Node not found'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
21 BackendException.__init__(self, msg) |
1 | 22 |
23 class NotAuthorized(BackendException): | |
24 pass | |
25 | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
26 class PayloadExpected(BackendException): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
27 def __init__(self, msg = 'Payload expected'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
28 BackendException.__init__(self, msg) |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
29 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
30 class NoPayloadAllowed(BackendException): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
31 def __init__(self, msg = 'No payload allowed'): |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
32 BackendException.__init__(self, msg) |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
33 |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
34 class NoInstantNodes(BackendException): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
35 pass |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
36 |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
37 class NodeExists(BackendException): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
38 pass |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
39 |
15 | 40 class Subscription: |
41 def __init__(self, state): | |
42 self.state = state | |
43 | |
44 class NodeConfiguration: | |
45 def __init__(self): | |
46 self.persist_items = False | |
47 self.deliver_payloads = False | |
48 | |
49 class Node: | |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
50 def __init__(self, id): |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
51 self.id = id |
15 | 52 self.configuration = NodeConfiguration() |
53 self.subscriptions = {} | |
54 self.affiliations = {} | |
55 self.items = {} | |
56 | |
1 | 57 class MemoryBackendService(service.Service): |
58 | |
59 __implements__ = IBackendService, | |
60 | |
61 def __init__(self): | |
15 | 62 self.nodes = {} |
1 | 63 |
15 | 64 node = Node("ralphm/mood/ralphm@ik.nu") |
65 node.subscriptions["ralphm@doe.ik.nu"] = Subscription("subscribed") | |
18 | 66 node.subscriptions["notify@ik.nu/mood_monitor"] = Subscription("subscribed") |
15 | 67 node.affiliations["ralphm@ik.nu"] = "owner" |
68 node.affiliations["ralphm@doe.ik.nu"] = "publisher" | |
69 node.configuration.persist_items = True | |
70 node.configuration.deliver_payloads = True | |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
71 self.nodes[node.id] = node |
15 | 72 |
73 def do_publish(self, node_id, publisher, items): | |
1 | 74 try: |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
75 node = self.nodes[node_id] |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
76 persist_items = node.configuration.persist_items |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
77 deliver_payloads = node.configuration.deliver_payloads |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
78 except KeyError: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
79 raise NodeNotFound |
1 | 80 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
81 try: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
82 if node.affiliations[publisher] not in ['owner', 'publisher']: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
83 raise NotAuthorized |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
84 except KeyError: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
85 raise NotAuthorized() |
2 | 86 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
87 if items and not persist_items and not deliver_payloads: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
88 raise NoPayloadAllowed |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
89 elif not items and (persist_items or deliver_payloads): |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
90 raise PayloadExpected |
2 | 91 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
92 print "publish by %s to %s" % (publisher, node_id) |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
93 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
94 if persist_items or deliver_payloads: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
95 for item in items: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
96 if item["id"] is None: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
97 item["id"] = 'random' # FIXME |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
98 |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
99 if persist_items: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
100 self.storeItems(node_id, publisher, items) |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
101 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
102 if items and not deliver_payloads: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
103 for item in items: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
104 item.children = [] |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
105 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
106 recipients = self.get_subscribers(node_id) |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
107 recipients.addCallback(self.magic_filter, node_id, items) |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
108 recipients.addCallback(self.pubsub_service.do_notification, node_id) |
2 | 109 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
110 return defer.succeed(None) |
1 | 111 |
15 | 112 def do_subscribe(self, node_id, subscriber, requestor): |
113 # expect subscriber and requestor to be a jid.JID | |
114 try: | |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
115 node = self.nodes[node_id] |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
116 except KeyError: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
117 raise NodeNotFound |
15 | 118 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
119 affiliation = node.affiliations.get(requestor.full(), 'none') |
15 | 120 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
121 if affiliation == 'banned': |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
122 raise NotAuthorized |
15 | 123 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
124 print subscriber.full() |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
125 print subscriber.userhostJID().full() |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
126 print requestor.full() |
15 | 127 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
128 if subscriber.userhostJID() != requestor: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
129 raise NotAuthorized |
15 | 130 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
131 try: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
132 subscription = node.subscriptions[subscriber.full()] |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
133 except KeyError: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
134 subscription = Subscription('subscribed') |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
135 node.subscriptions[subscriber.full()] = subscription |
15 | 136 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
137 print node.subscriptions |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
138 |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
139 return defer.succeed({ |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
140 'affiliation': affiliation, |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
141 'node': node_id, |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
142 'jid': subscriber, |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
143 'subscription': subscription.state}) |
15 | 144 |
145 def magic_filter(self, subscribers, node_id, items): | |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
146 list = {} |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
147 for subscriber in subscribers: |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
148 list[subscriber] = items |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
149 |
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
150 return list |
2 | 151 |
15 | 152 def get_subscribers(self, node_id): |
1 | 153 d = defer.Deferred() |
154 try: | |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
155 return defer.succeed(self.nodes[node_id].subscriptions.keys()) |
1 | 156 except: |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
157 return defer.fail() |
1 | 158 |
15 | 159 def storeItems(self, node_id, publisher, items): |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
160 for item in items: |
15 | 161 self.nodes[node_id].items[item["id"]] = item |
5
05a5d412e1b1
Added PayloadExpected and NoPayloadAllowed exceptions.
Ralph Meijer <ralphm@ik.nu>
parents:
2
diff
changeset
|
162 |
15 | 163 print self.nodes[node_id].items |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
164 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
165 def create_node(self, node_id, owner): |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
166 result = {} |
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
167 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
168 if not node_id: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
169 raise NoInstantNodes |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
170 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
171 if node_id in self.nodes: |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
172 raise NodeExists |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
173 |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
174 node = Node(node_id) |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
175 node.affiliations[owner.full()] = 'owner' |
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
176 self.nodes[node_id] = node |
20
eddea65d1032
Added two exceptions: NoInstantNodes and NodeExists.
Ralph Meijer <ralphm@ik.nu>
parents:
18
diff
changeset
|
177 |
23
884268687229
Simplify call chain by mapping incoming requests directly to method
Ralph Meijer <ralphm@ik.nu>
parents:
20
diff
changeset
|
178 return defer.succeed({'node_id': node.id}) |