Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 158 lines (143 sloc) 5.075 kB
f68917a initial support for the messaging layer
Rafael H. Schloming authored
1 #!/usr/bin/python
2 #
3 # Licensed to the Apache Software Foundation (ASF) under one
4 # or more contributor license agreements. See the NOTICE file
5 # distributed with this work for additional information
6 # regarding copyright ownership. The ASF licenses this file
7 # to you under the Apache License, Version 2.0 (the
8 # "License"); you may not use this file except in compliance
9 # with the License. You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing,
14 # software distributed under the License is distributed on an
15 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 # KIND, either express or implied. See the License for the
17 # specific language governing permissions and limitations
18 # under the License.
19 #
20
ee70116 @rhs fixed codec to work with nested descriptors
authored
21 from codec import Value, Described, Primitive
e7c027e @rhs updated to final xml
authored
22 from protocol import Header, DeliveryAnnotations, MessageAnnotations, \
23 Properties, ApplicationProperties, Data, AmqpSequence, AmqpValue, Footer, \
24 PROTOCOL_DECODER, PROTOCOL_ENCODER
f68917a initial support for the messaging layer
Rafael H. Schloming authored
25
328db3e @rhs coerce signed -> unsigned for message-id
authored
26 CONVERSIONS = {
27 "message_id": {long: Primitive("ulong"), int: Primitive("ulong")}
28 }
29
f68917a initial support for the messaging layer
Rafael H. Schloming authored
30 class Message:
31
32 def __init__(self, content=None, delivery_tag=None, **kwargs):
33 self.delivery_tag = delivery_tag
34 self.header = Header()
487d07f @rhs updated to latest xml
authored
35 self.annotations = None
f68917a initial support for the messaging layer
Rafael H. Schloming authored
36 self.properties = Properties()
837ca80 @rhs support for application properties
authored
37 self.application_properties = kwargs.pop("properties", None)
f68917a initial support for the messaging layer
Rafael H. Schloming authored
38 self.content = content
e7c027e @rhs updated to final xml
authored
39 self.footer = Footer({})
f68917a initial support for the messaging layer
Rafael H. Schloming authored
40 for k, v in kwargs.items():
328db3e @rhs coerce signed -> unsigned for message-id
authored
41 if k in CONVERSIONS:
42 mappings = CONVERSIONS[k]
43 t = type(v)
44 if t in mappings:
45 v = Value(mappings[t], v)
f68917a initial support for the messaging layer
Rafael H. Schloming authored
46 for o in (self.header, self.properties, self.footer):
47 if hasattr(o, k):
48 setattr(o, k, v)
49
db3e60b @rhs batch viewing
authored
50 def get(self, key, default=None):
51 if self.application_properties:
52 return self.application_properties.get(key, default)
53 else:
54 return default
55
837ca80 @rhs support for application properties
authored
56 def __getitem__(self, key):
57 if self.application_properties:
58 return self.application_properties[key]
59 else:
60 raise KeyError(key)
61
62 def __setitem__(self, key, value):
63 if not self.application_properties:
64 self.application_properties = {}
65 self.application_properties[key] = value
66
f68917a initial support for the messaging layer
Rafael H. Schloming authored
67 def __repr__(self):
68 args = []
837ca80 @rhs support for application properties
authored
69 for f in ["delivery_tag", ("application_properties", "properties")] + \
70 [f.name for f in Header.FIELDS] + \
f68917a initial support for the messaging layer
Rafael H. Schloming authored
71 [f.name for f in Properties.FIELDS] + ["content"] + \
72 [f.name for f in Footer.FIELDS]:
837ca80 @rhs support for application properties
authored
73 if isinstance(f, tuple):
74 f, a = f
75 else:
76 f, a = f, f
f68917a initial support for the messaging layer
Rafael H. Schloming authored
77 for o in (self, self.header, self.properties, self.footer):
78 if hasattr(o, f):
79 v = getattr(o, f)
80 if v is not None:
837ca80 @rhs support for application properties
authored
81 args.append("%s=%r" % (a, v))
f68917a initial support for the messaging layer
Rafael H. Schloming authored
82 return "Message(%s)" % ", ".join(args)
83
fa1d44d @rhs updates to test proposed transfer changes
authored
84 # XXX: encode: message -> str, decode: transfer -> message
f68917a initial support for the messaging layer
Rafael H. Schloming authored
85
1caf4f9 @rhs proper message frag/defrag
authored
86 def encode(message):
fa1d44d @rhs updates to test proposed transfer changes
authored
87 encoder = PROTOCOL_ENCODER
88 encoded = ""
89 if message.header:
90 encoded += encoder.encode(message.header)
91 if message.properties:
92 encoded += encoder.encode(message.properties)
837ca80 @rhs support for application properties
authored
93 if message.application_properties:
94 encoded += encoder.encode(ApplicationProperties(message.application_properties))
fa1d44d @rhs updates to test proposed transfer changes
authored
95 if message.content is not None:
96 # XXX: should dispatch
97 if isinstance(message.content, str):
e7c027e @rhs updated to final xml
authored
98 encoded += encoder.encode(Data(message.content))
ee70116 @rhs fixed codec to work with nested descriptors
authored
99 elif isinstance(message.content, (list, tuple)):
e7c027e @rhs updated to final xml
authored
100 encoded += encoder.encode(AmqpSequence(message.content))
fa1d44d @rhs updates to test proposed transfer changes
authored
101 else:
e7c027e @rhs updated to final xml
authored
102 encoded += encoder.encode(AmqpValue(message.content))
fa1d44d @rhs updates to test proposed transfer changes
authored
103 if message.footer:
104 encoded += encoder.encode(message.footer)
105 return encoded
f68917a initial support for the messaging layer
Rafael H. Schloming authored
106
fa1d44d @rhs updates to test proposed transfer changes
authored
107 def process_header(msg, header):
108 msg.header = header
109 def process_properties(msg, props):
110 msg.properties = props
111
112 def process_delivery_annotations(msg, ann):
487d07f @rhs updated to latest xml
authored
113 # XXX: we drop these
fa1d44d @rhs updates to test proposed transfer changes
authored
114 print "warning, ignoring delivery annotations", ann
115 def process_message_annotations(msg, ann):
116 msg.annotations = ann
837ca80 @rhs support for application properties
authored
117 def process_application_properties(msg, ap):
118 msg.application_properties = ap.value
fa1d44d @rhs updates to test proposed transfer changes
authored
119 def process_data(msg, v):
1ea49ff @rhs added text section type; fixed handling of multi section data/text bo…
authored
120 if msg.content is None:
121 msg.content = v.value
122 else:
123 msg.content += v.value
fa1d44d @rhs updates to test proposed transfer changes
authored
124 def process_sequence(msg, v):
125 if msg.content is None:
7a269c9 @rhs fixed bug in message decode; updated coordinator to match new content…
authored
126 msg.content = list(v.value)
fa1d44d @rhs updates to test proposed transfer changes
authored
127 else:
128 msg.content.extend(v.value)
fa4bbfb @rhs updated to latest version of spec
authored
129 def process_value(msg, v):
130 msg.content = v.value
fa1d44d @rhs updates to test proposed transfer changes
authored
131 def process_footer(msg, footer):
132 msg.footer = footer
1caf4f9 @rhs proper message frag/defrag
authored
133
134 SECTION_PROCESSORS = {
fa1d44d @rhs updates to test proposed transfer changes
authored
135 Header: process_header,
e7c027e @rhs updated to final xml
authored
136 DeliveryAnnotations: process_delivery_annotations,
137 MessageAnnotations: process_message_annotations,
fa1d44d @rhs updates to test proposed transfer changes
authored
138 Properties: process_properties,
e7c027e @rhs updated to final xml
authored
139 ApplicationProperties: process_application_properties,
140 Data: process_data,
141 AmqpSequence: process_sequence,
142 AmqpValue: process_value,
fa1d44d @rhs updates to test proposed transfer changes
authored
143 Footer: process_footer
1caf4f9 @rhs proper message frag/defrag
authored
144 }
145
146 def decode(transfer):
f68917a initial support for the messaging layer
Rafael H. Schloming authored
147 message = Message()
148 message.delivery_tag = transfer.delivery_tag
fa1d44d @rhs updates to test proposed transfer changes
authored
149 remaining = transfer.payload
1caf4f9 @rhs proper message frag/defrag
authored
150 sections = []
fa1d44d @rhs updates to test proposed transfer changes
authored
151 while remaining:
152 sect, remaining = PROTOCOL_DECODER.decode(remaining)
153 sections.append(sect)
1caf4f9 @rhs proper message frag/defrag
authored
154 while sections:
fa1d44d @rhs updates to test proposed transfer changes
authored
155 sect = sections.pop(0)
156 SECTION_PROCESSORS[sect.__class__](message, sect)
f68917a initial support for the messaging layer
Rafael H. Schloming authored
157 return message
Something went wrong with that request. Please try again.