1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 """
21 The proton module defines a suite of APIs that implement the AMQP 1.0
22 protocol.
23
24 The proton APIs consist of the following classes:
25
26 - L{Messenger} -- A messaging endpoint.
27 - L{Message} -- A class for creating and/or accessing AMQP message content.
28 - L{Data} -- A class for creating and/or accessing arbitrary AMQP encoded
29 data.
30
31 """
32
33 from cproton import *
36 """
37 The root of the proton exception hierarchy. All proton exception
38 classes derive from this exception.
39 """
40 pass
41
43 """
44 A timeout exception indicates that a blocking operation has timed
45 out.
46 """
47 pass
48
50 """
51 The root of the messenger exception hierarchy. All exceptions
52 generated by the messenger class derive from this exception.
53 """
54 pass
55
57 """
58 The MessageException class is the root of the message exception
59 hierarhcy. All exceptions generated by the Message class derive from
60 this exception.
61 """
62 pass
63
64 EXCEPTIONS = {
65 PN_TIMEOUT: Timeout
66 }
69 """
70 The L{Messenger} class defines a high level interface for sending
71 and receiving L{Messages<Message>}. Every L{Messenger} contains a
72 single logical queue of incoming messages and a single logical queue
73 of outgoing messages. These messages in these queues may be destined
74 for, or originate from, a variety of addresses.
75
76 Address Syntax
77 ==============
78
79 An address has the following form::
80
81 [ amqp[s]:// ] [user[:password]@] domain [/[name]]
82
83 Where domain can be one of::
84
85 host | host:port | ip | ip:port | name
86
87 The following are valid examples of addresses:
88
89 - example.org
90 - example.org:1234
91 - amqp://example.org
92 - amqps://example.org
93 - example.org/incoming
94 - amqps://example.org/outgoing
95 - amqps://fred:trustno1@example.org
96 - 127.0.0.1:1234
97 - amqps://127.0.0.1:1234
98
99 Sending & Receiving Messages
100 ============================
101
102 The L{Messenger} class works in conjuction with the L{Message}
103 class. The L{Message} class is a mutable holder of message content.
104 The L{put} method will encode the content in a given L{Message}
105 object into the outgoing message queue leaving that L{Message}
106 object free to be modified or discarded without having any impact on
107 the content in the outgoing queue.
108
109 >>> message = Message()
110 >>> for i in range(3):
111 ... message.address = "amqp://host/queue"
112 ... message.subject = "Hello World %i" % i
113 ... messenger.put(message)
114 >>> messenger.send()
115
116 Similarly, the L{get} method will decode the content in the incoming
117 message queue into the supplied L{Message} object.
118
119 >>> message = Message()
120 >>> messenger.recv(10):
121 >>> while messenger.incoming > 0:
122 ... messenger.get(message)
123 ... print message.subject
124 Hello World 0
125 Hello World 1
126 Hello World 2
127 """
128
130 """
131 Construct a new L{Messenger} with the given name. The name has
132 global scope. If a NULL name is supplied, a L{uuid.UUID} based
133 name will be chosen.
134
135 @type name: string
136 @param name: the name of the messenger or None
137 """
138 self._mng = pn_messenger(name)
139
141 if hasattr(self, "_mng"):
142 pn_messenger_free(self._mng)
143 del self._mng
144
146 if err < 0:
147 exc = EXCEPTIONS.get(err, MessengerException)
148 raise exc("[%s]: %s" % (err, pn_messenger_error(self._mng)))
149 else:
150 return err
151
152 @property
154 """
155 The name of the L{Messenger}.
156 """
157 return pn_messenger_name(self._mng)
158
160 return pn_messenger_get_certificate(self._mng)
161
163 self._check(pn_messenger_set_certificate(self._mng, value))
164
165 certificate = property(_get_certificate, _set_certificate,
166 doc="""
167 Path to a certificate file for the L{Messenger}. This certificate is
168 used when the L{Messenger} accepts or establishes SSL/TLS connections.
169 This property must be specified for the L{Messenger} to accept
170 incoming SSL/TLS connections and to establish client authenticated
171 outgoing SSL/TLS connection. Non client authenticated outgoing SSL/TLS
172 connections do not require this property.
173 """)
174
176 return pn_messenger_get_private_key(self._mng)
177
179 self._check(pn_messenger_set_private_key(self._mng, value))
180
181 private_key = property(_get_private_key, _set_private_key,
182 doc="""
183 Path to a private key file for the L{Messenger's<Messenger>}
184 certificate. This property must be specified for the L{Messenger} to
185 accept incoming SSL/TLS connections and to establish client
186 authenticated outgoing SSL/TLS connection. Non client authenticated
187 SSL/TLS connections do not require this property.
188 """)
189
191 return pn_messenger_get_password(self._mng)
192
194 self._check(pn_messenger_set_password(self._mng, value))
195
196 password = property(_get_password, _set_password,
197 doc="""
198 This property contains the password for the L{Messenger.private_key}
199 file, or None if the file is not encrypted.
200 """)
201
203 return pn_messenger_get_trusted_certificates(self._mng)
204
206 self._check(pn_messenger_set_trusted_certificates(self._mng, value))
207
208 trusted_certificates = property(_get_trusted_certificates,
209 _set_trusted_certificates,
210 doc="""
211 A path do a database of trusted certificates for use in verifying the
212 peer on an SSL/TLS connection. If this property is None, then the peer
213 will not be verified.
214 """)
215
217 return pn_messenger_get_timeout(self._mng)
218
220 self._check(pn_messenger_set_timeout(self._mng, value))
221
222 timeout = property(_get_timeout, _set_timeout,
223 doc="""
224 The timeout property contains the default timeout for blocking
225 operations performed by the L{Messenger}.
226 """)
227
229 """
230 Transitions the L{Messenger} to an active state. A L{Messenger} is
231 initially created in an inactive state. When inactive a
232 L{Messenger} will not send or receive messages from its internal
233 queues. A L{Messenger} must be started before calling L{send} or
234 L{recv}.
235 """
236 self._check(pn_messenger_start(self._mng))
237
239 """
240 Transitions the L{Messenger} to an inactive state. An inactive
241 L{Messenger} will not send or receive messages from its internal
242 queues. A L{Messenger} should be stopped before being discarded to
243 ensure a clean shutdown handshake occurs on any internally managed
244 connections.
245 """
246 self._check(pn_messenger_stop(self._mng))
247
249 """
250 Subscribes the L{Messenger} to messages originating from the
251 specified source. The source is an address as specified in the
252 L{Messenger} introduction with the following addition. If the
253 domain portion of the address begins with the '~' character, the
254 L{Messenger} will interpret the domain as host/port, bind to it,
255 and listen for incoming messages. For example "~0.0.0.0",
256 "amqp://~0.0.0.0", and "amqps://~0.0.0.0" will all bind to any
257 local interface and listen for incoming messages with the last
258 variant only permitting incoming SSL connections.
259
260 @type source: string
261 @param source: the source of messages to subscribe to
262 """
263 self._check(pn_messenger_subscribe(self._mng, source))
264
265 - def put(self, message):
266 """
267 Places the content contained in the message onto the outgoing
268 queue of the L{Messenger}. This method will never block, however
269 it will send any unblocked L{Messages<Message>} in the outgoing
270 queue immediately and leave any blocked L{Messages<Message>}
271 remaining in the outgoing queue. The L{send} call may be used to
272 block until the outgoing queue is empty. The L{outgoing} property
273 may be used to check the depth of the outgoing queue.
274
275 @type message: Message
276 @param message: the message to place in the outgoing queue
277 """
278 self._check(pn_messenger_put(self._mng, message._msg))
279
281 """
282 Blocks until the outgoing queue is empty or the operation times
283 out. The L{timeout} property controls how long a L{Messenger} will
284 block before timing out.
285 """
286 self._check(pn_messenger_send(self._mng))
287
289 """
290 Receives up to I{n} messages into the incoming queue of the
291 L{Messenger}. This method will block until at least one message is
292 available or the operation times out.
293 """
294 self._check(pn_messenger_recv(self._mng, n))
295
296 - def get(self, message):
297 """
298 Moves the message from the head of the incoming message queue into
299 the supplied message object. Any content in the message will be
300 overwritten.
301
302 @type message: Message
303 @param message: the destination message object
304 """
305 self._check(pn_messenger_get(self._mng, message._msg))
306
307 @property
309 """
310 The outgoing queue depth.
311 """
312 return pn_messenger_outgoing(self._mng)
313
314 @property
316 """
317 The incoming queue depth.
318 """
319 return pn_messenger_incoming(self._mng)
320
322 """
323 The L{Message} class is a mutable holder of message content.
324 """
325
326 DATA = PN_DATA
327 TEXT = PN_TEXT
328 AMQP = PN_AMQP
329 JSON = PN_JSON
330
331 DEFAULT_PRIORITY = PN_DEFAULT_PRIORITY
332
334 self._msg = pn_message()
335
337 if hasattr(self, "_msg"):
338 pn_message_free(self._msg)
339 del self._msg
340
342 if err < 0:
343 exc = EXCEPTIONS.get(err, MessageException)
344 raise exc("[%s]: %s" % (err, pn_message_error(self._msg)))
345 else:
346 return err
347
349 """
350 Clears the contents of the L{Message}. All fields will be reset to
351 their default values.
352 """
353 pn_message_clear(self._msg)
354
356 return pn_message_is_durable(self._msg)
357
359 self._check(pn_message_set_durable(self._msg, bool(value)))
360
361 durable = property(_is_durable, _set_durable,
362 doc="""
363 The durable property indicates that the message should be held durably
364 by any intermediaries taking responsibility for the message.
365 """)
366
368 return pn_message_get_priority(self._msg)
369
371 self._check(pn_message_set_priority(self._msg, value))
372
373 priority = property(_get_priority, _set_priority,
374 doc="""
375 The priority of the message.
376 """)
377
379 return pn_message_get_ttl(self._msg)
380
382 self._check(pn_message_set_ttl(self._msg, value))
383
384 ttl = property(_get_ttl, _set_ttl,
385 doc="""
386 The time to live of the message measured in milliseconds. Expired
387 messages may be dropped.
388 """)
389
391 return pn_message_is_first_acquirer(self._msg)
392
394 self._check(pn_message_set_first_acquirer(self._msg, bool(value)))
395
396 first_acquirer = property(_is_first_acquirer, _set_first_acquirer,
397 doc="""
398 True iff the recipient is the first to acquire the message.
399 """)
400
402 return pn_message_get_delivery_count(self._msg)
403
405 self._check(pn_message_set_delivery_count(self._msg, value))
406
407 delivery_count = property(_get_delivery_count, _set_delivery_count,
408 doc="""
409 The number of delivery attempts made for this message.
410 """)
411
412
414 return pn_message_get_id(self._msg)
415
417 self._check(pn_message_set_id(self._msg, value))
418
419 id = property(_get_id, _set_id,
420 doc="""
421 The id of the message.
422 """)
423
425 return pn_message_get_user_id(self._msg)
426
428 self._check(pn_message_set_user_id(self._msg, value))
429
430 user_id = property(_get_user_id, _set_user_id,
431 doc="""
432 The user id of the message creator.
433 """)
434
436 return pn_message_get_address(self._msg)
437
439 self._check(pn_message_set_address(self._msg, value))
440
441 address = property(_get_address, _set_address,
442 doc="""
443 The address of the message.
444 """)
445
447 return pn_message_get_subject(self._msg)
448
450 self._check(pn_message_set_subject(self._msg, value))
451
452 subject = property(_get_subject, _set_subject,
453 doc="""
454 The subject of the message.
455 """)
456
458 return pn_message_get_reply_to(self._msg)
459
461 self._check(pn_message_set_reply_to(self._msg, value))
462
463 reply_to = property(_get_reply_to, _set_reply_to,
464 doc="""
465 The reply-to address for the message.
466 """)
467
468
470 return pn_message_get_correlation_id(self._msg)
471
473 self._check(pn_message_set_correlation_id(self._msg, value))
474
475 correlation_id = property(_get_correlation_id, _set_correlation_id,
476 doc="""
477 The correlation-id for the message.
478 """)
479
481 return pn_message_get_content_type(self._msg)
482
483 - def _set_content_type(self, value):
484 self._check(pn_message_set_content_type(self._msg, value))
485
486 content_type = property(_get_content_type, _set_content_type,
487 doc="""
488 The content-type of the message.
489 """)
490
492 return pn_message_get_content_encoding(self._msg)
493
494 - def _set_content_encoding(self, value):
495 self._check(pn_message_set_content_encoding(self._msg, value))
496
497 content_encoding = property(_get_content_encoding, _set_content_encoding,
498 doc="""
499 The content-encoding of the message.
500 """)
501
503 return pn_message_get_expiry_time(self._msg)
504
506 self._check(pn_message_set_expiry_time(self._msg, value))
507
508 expiry_time = property(_get_expiry_time, _set_expiry_time,
509 doc="""
510 The expiry time of the message.
511 """)
512
514 return pn_message_get_creation_time(self._msg)
515
517 self._check(pn_message_set_creation_time(self._msg, value))
518
519 creation_time = property(_get_creation_time, _set_creation_time,
520 doc="""
521 The creation time of the message.
522 """)
523
525 return pn_message_get_group_id(self._msg)
526
528 self._check(pn_message_set_group_id(self._msg, value))
529
530 group_id = property(_get_group_id, _set_group_id,
531 doc="""
532 The group id of the message.
533 """)
534
536 return pn_message_get_group_sequence(self._msg)
537
539 self._check(pn_message_set_group_sequence(self._msg, value))
540
541 group_sequence = property(_get_group_sequence, _set_group_sequence,
542 doc="""
543 The sequence of the message within its group.
544 """)
545
547 return pn_message_get_reply_to_group_id(self._msg)
548
550 self._check(pn_message_set_reply_to_group_id(self._msg, value))
551
552 reply_to_group_id = property(_get_reply_to_group_id, _set_reply_to_group_id,
553 doc="""
554 The group-id for any replies.
555 """)
556
557
560
563
564 format = property(_get_format, _set_format,
565 doc="""
566 The format of the message.
567 """)
568
570 sz = 16
571 while True:
572 err, data = pn_message_encode(self._msg, sz)
573 if err == PN_OVERFLOW:
574 sz *= 2
575 continue
576 else:
577 self._check(err)
578 return data
579
581 return self._check(pn_message_decode(self._msg, data, len(data)))
582
583 - def load(self, data):
584 self._check(pn_message_load(self._msg, data))
585
587 sz = 16
588 while True:
589 err, data = pn_message_save(self._msg, sz)
590 if err == PN_OVERFLOW:
591 sz *= 2
592 continue
593 else:
594 self._check(err)
595 return data
596
598 """
599 The DataException class is the root of the Data exception hierarchy.
600 All exceptions raised by the Data class extend this exception.
601 """
602 pass
603
605 """
606 The L{Data} class provides an interface for decoding, extracting,
607 creating, and encoding arbitrary AMQP data. A L{Data} object
608 contains a tree of AMQP values. Leaf nodes in this tree correspond
609 to scalars in the AMQP type system such as L{ints<INT>} or
610 L{strings<STRING>}. Non-leaf nodes in this tree correspond to
611 compound values in the AMQP type system such as L{lists<LIST>},
612 L{maps<MAP>}, L{arrays<ARRAY>}, or L{described values<DESCRIBED>}.
613 The root node of the tree is the L{Data} object itself and can have
614 an arbitrary number of children.
615
616 A L{Data} object maintains the notion of the current sibling node
617 and a current parent node. Siblings are ordered within their parent.
618 Values are accessed and/or added by using the L{next}, L{prev},
619 L{enter}, and L{exit} methods to navigate to the desired location in
620 the tree and using the supplied variety of put_*/get_* methods to
621 access or add a value of the desired type.
622
623 The put_* methods will always add a value I{after} the current node
624 in the tree. If the current node has a next sibling the put_* method
625 will overwrite the value on this node. If there is no current node
626 or the current node has no next sibling then one will be added. The
627 put_* methods always set the added/modified node to the current
628 node. The get_* methods read the value of the current node and do
629 not change which node is current.
630
631 The following types of scalar values are supported:
632
633 - L{NULL}
634 - L{BOOL}
635 - L{UBYTE}
636 - L{USHORT}
637 - L{SHORT}
638 - L{UINT}
639 - L{INT}
640 - L{ULONG}
641 - L{LONG}
642 - L{FLOAT}
643 - L{DOUBLE}
644 - L{BINARY}
645 - L{STRING}
646 - L{SYMBOL}
647
648 The following types of compound values are supported:
649
650 - L{DESCRIBED}
651 - L{ARRAY}
652 - L{LIST}
653 - L{MAP}
654 """
655
656 NULL = PN_NULL; "A null value."
657 BOOL = PN_BOOL; "A boolean value."
658 UBYTE = PN_UBYTE; "An unsigned byte value."
659 BYTE = PN_BYTE; "A signed byte value."
660 USHORT = PN_USHORT; "An unsigned short value."
661 SHORT = PN_SHORT; "A short value."
662 UINT = PN_UINT; "An unsigned int value."
663 INT = PN_INT; "A signed int value."
664 CHAR = PN_CHAR; "A character value."
665 ULONG = PN_ULONG; "An unsigned long value."
666 LONG = PN_LONG; "A signed long value."
667 TIMESTAMP = PN_TIMESTAMP; "A timestamp value."
668 FLOAT = PN_FLOAT; "A float value."
669 DOUBLE = PN_DOUBLE; "A double value."
670 BINARY = PN_BINARY; "A binary string."
671 STRING = PN_STRING; "A unicode string."
672 SYMBOL = PN_SYMBOL; "A symbolic string."
673 DESCRIBED = PN_DESCRIPTOR; "A described value."
674 ARRAY = PN_ARRAY; "An array value."
675 LIST = PN_LIST; "A list value."
676 MAP = PN_MAP; "A map value."
677
679 self._data = pn_data(capacity)
680
682 if hasattr(self, "_data"):
683 pn_data_free(self._data)
684 del self._data
685
687 if err < 0:
688 exc = EXCEPTIONS.get(err, DataException)
689 raise exc("[%s]: %s" % (err, "xxx"))
690 else:
691 return err
692
694 """
695 Clears current node and sets the parent to the root node.
696 """
697 pn_data_rewind(self._data)
698
700 """
701 Advances the current node to its next sibling and returns its
702 type. If there is no next sibling the current node remains
703 unchanged and None is returned.
704 """
705 found, dtype = pn_data_next(self._data)
706 if found:
707 return dtype
708 else:
709 return None
710
712 """
713 Advances the current node to its previous sibling and returns its
714 type. If there is no previous sibling the current node remains
715 unchanged and None is returned.
716 """
717 found, dtype = pn_data_prev(self._data)
718 if found:
719 return dtype
720 else:
721 return None
722
724 """
725 Sets the parent node to the current node and clears the current node.
726 """
727 return pn_data_enter(self._data)
728
730 """
731 Sets the current node to the parent node and the parent node to
732 its own parent.
733 """
734 return pn_data_exit(self._data)
735
737 """
738 Returns a representation of the data encoded in AMQP format.
739 """
740 size = 1024
741 while True:
742 cd, enc = pn_data_encode(self._data, size)
743 if cd == PN_OVERFLOW:
744 size *= 2
745 elif cd >= 0:
746 return enc
747 else:
748 self._check(cd)
749
751 """
752 Decodes the first value from supplied AMQP data and returns the
753 number of bytes consumed.
754
755 @type encoded: binary
756 @param encoded: AMQP encoded binary data
757 """
758 return self._check(pn_data_decode(self._data, encoded))
759
761 """
762 Puts a list value. Elements may be filled by entering the list
763 node and putting element values.
764
765 >>> data = Data()
766 >>> data.put_list()
767 >>> data.enter()
768 >>> data.put_int(1)
769 >>> data.put_int(2)
770 >>> data.put_int(3)
771 >>> data.exit()
772 """
773 self._check(pn_data_put_list(self._data))
774
776 """
777 Puts a map value. Elements may be filled by entering the map node
778 and putting alternating key value pairs.
779
780 >>> data = Data()
781 >>> data.put_map()
782 >>> data.enter()
783 >>> data.put_string("key")
784 >>> data.put_string("value")
785 >>> data.exit()
786 """
787 self._check(pn_data_put_map(self._data))
788
789 - def put_array(self, described, element_type):
790 """
791 Puts an array value. Elements may be filled by entering the array
792 node and putting the element values. The values must all be of the
793 specified array element type. If an array is described then the
794 first child value of the array is the descriptor and may be of any
795 type.
796
797 >>> data = Data()
798 >>>
799 >>> data.put_array(False, Data.INT)
800 >>> data.enter()
801 >>> data.put_int(1)
802 >>> data.put_int(2)
803 >>> data.put_int(3)
804 >>> data.exit()
805 >>>
806 >>> data.put_array(True, Data.DOUBLE)
807 >>> data.enter()
808 >>> data.put_symbol("array-descriptor")
809 >>> data.enter()
810 >>> data.put_double(1.1)
811 >>> data.put_double(1.2)
812 >>> data.put_double(1.3)
813 >>> data.exit()
814
815 @type described: bool
816 @param described: specifies whether the array is described
817 @type element_type: int
818 @param element_type: the type of the array elements
819 """
820 self._check(pn_data_put_array(self._data, described, element_type))
821
823 """
824 Puts a described value. A described node has two children, the
825 descriptor and the value. These are specified by entering the node
826 and putting the desired values.
827
828 >>> data = Data()
829 >>> data.put_described()
830 >>> data.enter()
831 >>> data.put_symbol("value-descriptor")
832 >>> data.put_string("the value")
833 >>> data.exit()
834 """
835 self._check(pn_data_put_described(self._data))
836
838 """
839 Puts a null value.
840 """
841 self._check(pn_data_put_null(self._data))
842
844 """
845 Puts a boolean value.
846
847 @param b: a boolean value
848 """
849 self._check(pn_data_put_bool(self._data, b))
850
852 """
853 Puts an unsigned byte value.
854
855 @param ub: an integral value
856 """
857 self._check(pn_data_put_ubyte(self._data, ub))
858
860 """
861 Puts a signed byte value.
862
863 @param b: an integral value
864 """
865 self._check(pn_data_put_byte(self._data, b))
866
868 """
869 Puts an unsigned short value.
870
871 @param us: an integral value.
872 """
873 self._check(pn_data_put_ushort(self._data, us))
874
876 """
877 Puts a signed short value.
878
879 @param s: an integral value
880 """
881 self._check(pn_data_put_short(self._data, s))
882
884 """
885 Puts an unsigned int value.
886
887 @param ui: an integral value
888 """
889 self._check(pn_data_put_uint(self._data, ui))
890
892 """
893 Puts a signed int value.
894
895 @param i: an integral value
896 """
897 self._check(pn_data_put_int(self._data, i))
898
900 """
901 Puts a char value.
902
903 @param c: a single character
904 """
905 self._check(pn_data_put_char(self._data, ord(c)))
906
908 """
909 Puts an unsigned long value.
910
911 @param ul: an integral value
912 """
913 self._check(pn_data_put_ulong(self._data, ul))
914
916 """
917 Puts a signed long value.
918
919 @param l: an integral value
920 """
921 self._check(pn_data_put_long(self._data, l))
922
924 """
925 Puts a timestamp value.
926
927 @param t: an integral value
928 """
929 self._check(pn_data_put_timestamp(self._data, t))
930
932 """
933 Puts a float value.
934
935 @param f: a floating point value
936 """
937 self._check(pn_data_put_float(self._data, f))
938
940 """
941 Puts a double value.
942
943 @param d: a floating point value.
944 """
945 self._check(pn_data_put_double(self._data, d))
946
948 """
949 Puts a binary value.
950
951 @type b: binary
952 @param b: a binary value
953 """
954 self._check(pn_data_put_binary(self._data, b))
955
957 """
958 Puts a unicode value.
959
960 @type s: unicode
961 @param s: a unicode value
962 """
963 self._check(pn_data_put_string(self._data, s))
964
966 """
967 Puts a symbolic value.
968
969 @type s: string
970 @param s: the symbol name
971 """
972 self._check(pn_data_put_symbol(self._data, s))
973
975 """
976 If the current node is a list, return the number of elements,
977 otherwise raise an error. List elements can be accessed by
978 entering the list.
979
980 >>> count = data.get_list()
981 >>> data.enter()
982 >>> for i in range(count):
983 ... type = data.next()
984 ... if type == Data.STRING:
985 ... print data.get_string()
986 ... elif type == ...:
987 ... ...
988 >>> data.exit()
989 """
990 err, count = pn_data_get_list(self._data)
991 self._check(err)
992 return count
993
995 """
996 If the current node is a map, return the number of child elements,
997 otherwise raise an error. Key value pairs can be accessed by
998 entering the map.
999
1000 >>> count = data.get_map()
1001 >>> data.enter()
1002 >>> for i in range(count/2):
1003 ... type = data.next()
1004 ... if type == Data.STRING:
1005 ... print data.get_string()
1006 ... elif type == ...:
1007 ... ...
1008 >>> data.exit()
1009 """
1010 err, count = pn_data_get_map(self._data)
1011 self._check(err)
1012 return count
1013
1015 """
1016 If the current node is an array, return a tuple of the element
1017 count, a boolean indicating whether the array is described, and
1018 the type of each element. Array data can be accessed by entering
1019 the array.
1020
1021 >>> # read an array of strings with a symbolic descriptor
1022 >>> count, described, type = data.get_array()
1023 >>> data.enter()
1024 >>> data.next()
1025 >>> print "Descriptor:", data.get_symbol()
1026 >>> for i in range(count):
1027 ... data.next()
1028 ... print "Element:", data.get_string()
1029 >>> data.exit()
1030 """
1031 err, count, described, type = pn_data_get_array(self._data)
1032 self._check(err)
1033 return count, described, type
1034
1036 """
1037 Checks if the current node is a described value, raises an
1038 exception otherwise. The descriptor and value may be accessed by
1039 entering the described value.
1040
1041 >>> # read a symbolically described string
1042 >>> data.get_described() # will error if the current node is not described
1043 >>> data.enter()
1044 >>> print data.get_symbol()
1045 >>> print data.get_string()
1046 >>> data.exit()
1047 """
1048 self._check(pn_data_get_described(self._data))
1049
1051 """
1052 Checks if the current node is a null, raises an exception
1053 otherwise.
1054 """
1055 self._check(pn_data_get_null(self._data))
1056
1058 """
1059 If the current node is a boolean, returns its value, raises an
1060 exception otherwise.
1061 """
1062 err, b = pn_data_get_bool(self._data)
1063 self._check(err)
1064 return b
1065
1067 """
1068 If the current node is an unsigned byte, returns its value, raises
1069 an exception otherwise.
1070 """
1071 err, value = pn_data_get_ubyte(self._data)
1072 self._check(err)
1073 return value
1074
1076 """
1077 If the current node is a signed byte, returns its value, raises an
1078 exception otherwise.
1079 """
1080 err, value = pn_data_get_byte(self._data)
1081 self._check(err)
1082 return value
1083
1085 """
1086 If the current node is an unsigned short, returns its value,
1087 raises an exception otherwise.
1088 """
1089 err, value = pn_data_get_ushort(self._data)
1090 self._check(err)
1091 return value
1092
1094 """
1095 If the current node is a signed short, returns its value, raises
1096 an exception otherwise.
1097 """
1098 err, value = pn_data_get_short(self._data)
1099 self._check(err)
1100 return value
1101
1103 """
1104 If the current node is an unsigned int, returns its value, raises
1105 an exception otherwise.
1106 """
1107 err, value = pn_data_get_uint(self._data)
1108 self._check(err)
1109 return value
1110
1112 """
1113 If the current node is a signed int, returns its value, raises an
1114 exception otherwise.
1115 """
1116 err, value = pn_data_get_int(self._data)
1117 self._check(err)
1118 return value
1119
1121 """
1122 If the current node is a char, returns its value, raises an
1123 exception otherwise.
1124 """
1125 err, value = pn_data_get_char(self._data)
1126 self._check(err)
1127 return unichr(value)
1128
1130 """
1131 If the current node is an unsigned long, returns its value, raises
1132 an exception otherwise.
1133 """
1134 err, value = pn_data_get_ulong(self._data)
1135 self._check(err)
1136 return value
1137
1139 """
1140 If the current node is an signed long, returns its value, raises
1141 an exception otherwise.
1142 """
1143 err, value = pn_data_get_long(self._data)
1144 self._check(err)
1145 return value
1146
1148 """
1149 If the current node is a timestamp, returns its value, raises
1150 an exception otherwise.
1151 """
1152 err, value = pn_data_get_timestamp(self._data)
1153 self._check(err)
1154 return value
1155
1157 """
1158 If the current node is a float, returns its value, raises an
1159 exception otherwise.
1160 """
1161 err, value = pn_data_get_float(self._data)
1162 self._check(err)
1163 return value
1164
1166 """
1167 If the current node is a double, returns its value, raises an
1168 exception otherwise.
1169 """
1170 err, value = pn_data_get_double(self._data)
1171 self._check(err)
1172 return value
1173
1175 """
1176 If the current node is binary, returns its value, raises an
1177 exception otherwise.
1178 """
1179 err, value = pn_data_get_binary(self._data)
1180 self._check(err)
1181 return value
1182
1184 """
1185 If the current node is a string, returns its value, raises an
1186 exception otherwise.
1187 """
1188 err, value = pn_data_get_string(self._data)
1189 self._check(err)
1190 return value
1191
1193 """
1194 If the current node is a symbol, returns its value, raises an
1195 exception otherwise.
1196 """
1197 err, value = pn_data_get_symbol(self._data)
1198 self._check(err)
1199 return value
1200
1202 pn_data_dump(self._data)
1203
1206
1215
1217 if not conn: return None
1218 ctx = pn_connection_get_context(conn)
1219 if ctx: return ctx
1220 wrapper = Connection(_conn=conn)
1221 return wrapper
1222
1224
1226 if _conn:
1227 self._conn = _conn
1228 else:
1229 self._conn = pn_connection()
1230 pn_connection_set_context(self._conn, self)
1231
1233 if hasattr(self, "_conn"):
1234 pn_connection_free(self._conn)
1235 del self._conn
1236
1238 if err < 0:
1239 exc = EXCEPTIONS.get(err, ConnectionException)
1240 raise exc("[%s]: %s" % (err, pn_connection_error(self._conn)))
1241 else:
1242 return err
1243
1245 return pn_connection_get_container(self._conn)
1247 return pn_connection_set_container(self._conn, name)
1248
1249 container = property(_get_container, _set_container)
1250
1252 return pn_connection_get_hostname(self._conn)
1254 return pn_connection_set_hostname(self._conn, name)
1255
1256 hostname = property(_get_hostname, _set_hostname)
1257
1258 @property
1260 return pn_connection_remote_container(self._conn)
1261
1262 @property
1264 return pn_connection_remote_hostname(self._conn)
1265
1267 pn_connection_open(self._conn)
1268
1270 pn_connection_close(self._conn)
1271
1272 @property
1274 return pn_connection_state(self._conn)
1275
1276 @property
1278 return pn_connection_writable(self._conn)
1279
1281 return wrap_session(pn_session(self._conn))
1282
1284 return wrap_session(pn_session_head(self._conn, mask))
1285
1287 return wrap_link(pn_link_head(self._conn, mask))
1288
1289 @property
1291 return wrap_delivery(pn_work_head(self._conn))
1292
1295
1297 if ssn is None: return None
1298 ctx = pn_session_get_context(ssn)
1299 if ctx:
1300 return ctx
1301 else:
1302 wrapper = Session(ssn)
1303 pn_session_set_context(ssn, wrapper)
1304 return wrapper
1305
1307
1310
1312 if hasattr(self, "_ssn"):
1313 pn_session_free(self._ssn)
1314 del self._ssn
1315
1317 pn_session_open(self._ssn)
1318
1320 pn_session_close(self._ssn)
1321
1322 @property
1324 return pn_session_state(self._ssn)
1325
1326 @property
1328 return wrap_connection(pn_session_connection(self._ssn))
1329
1331 return wrap_link(pn_sender(self._ssn, name))
1332
1334 return wrap_link(pn_receiver(self._ssn, name))
1335
1338
1340 if link is None: return None
1341 ctx = pn_link_get_context(link)
1342 if ctx:
1343 return ctx
1344 else:
1345 if pn_link_is_sender(link):
1346 wrapper = Sender(link)
1347 else:
1348 wrapper = Receiver(link)
1349 pn_link_set_context(link, wrapper)
1350 return wrapper
1351
1352 -class Link(Endpoint):
1353
1356
1358 if hasattr(self, "_link"):
1359 pn_link_free(self._link)
1360 del self._link
1361
1363 if err < 0:
1364 exc = EXCEPTIONS.get(err, LinkException)
1365 raise exc("[%s]: %s" % (err, pn_link_error(self._link)))
1366 else:
1367 return err
1368
1370 pn_link_open(self._link)
1371
1373 pn_link_close(self._link)
1374
1375 @property
1377 return pn_link_state(self._link)
1378
1380 pn_link_set_source(self._link, source)
1382 return pn_link_get_source(self._link)
1383 source = property(_get_source, _set_source)
1384
1386 pn_link_set_target(self._link, target)
1388 return pn_link_get_target(self._link)
1389 target = property(_get_target, _set_target)
1390
1391 @property
1393 return pn_link_remote_source(self._link)
1394 @property
1396 return pn_link_remote_target(self._link)
1397
1398 @property
1400 return wrap_session(pn_link_session(self._link))
1401
1403 return wrap_delivery(pn_delivery(self._link, tag))
1404
1405 @property
1407 return wrap_delivery(pn_link_current(self._link))
1408
1410 return pn_link_advance(self._link)
1411
1412 @property
1414 return pn_link_unsettled(self._link)
1415
1416 @property
1418 return pn_link_credit(self._link)
1419
1420 @property
1422 return pn_link_available(self._link)
1423
1424 @property
1426 return pn_link_queued(self._link)
1427
1428 - def next(self, mask):
1429 return wrap_link(pn_link_next(self._link, mask))
1430
1432
1434 pn_link_offered(self._link, n)
1435
1436 - def send(self, bytes):
1437 return self._check(pn_link_send(self._link, bytes))
1438
1440 pn_link_drained(self._link)
1441
1443
1444 - def flow(self, n):
1445 pn_link_flow(self._link, n)
1446
1447 - def recv(self, limit):
1448 n, bytes = pn_link_recv(self._link, limit)
1449 if n == PN_EOS:
1450 return None
1451 else:
1452 self._check(n)
1453 return bytes
1454
1456 pn_link_drain(self._link, n)
1457
1459 if not dlv: return None
1460 ctx = pn_delivery_get_context(dlv)
1461 if ctx: return ctx
1462 wrapper = Delivery(dlv)
1463 pn_delivery_set_context(dlv, wrapper)
1464 return wrapper
1465
1467
1468 ACCEPTED = PN_ACCEPTED
1469
1472
1473 @property
1475 return pn_delivery_tag(self._dlv)
1476
1477 @property
1479 return pn_delivery_writable(self._dlv)
1480
1481 @property
1483 return pn_delivery_readable(self._dlv)
1484
1485 @property
1487 return pn_delivery_updated(self._dlv)
1488
1490 pn_delivery_update(self._dlv, state)
1491
1492 @property
1494 return pn_delivery_local_state(self._dlv)
1495
1496 @property
1498 return pn_delivery_remote_state(self._dlv)
1499
1500 @property
1502 return pn_delivery_settled(self._dlv)
1503
1505 pn_delivery_settle(self._dlv)
1506
1507 @property
1509 return wrap_delivery(pn_work_next(self._dlv))
1510
1513
1515
1516 TRACE_DRV = PN_TRACE_DRV
1517 TRACE_FRM = PN_TRACE_FRM
1518 TRACE_RAW = PN_TRACE_RAW
1519
1521 self._trans = pn_transport()
1522
1524 if hasattr(self, "_trans"):
1525 pn_transport_free(self._trans)
1526 del self._trans
1527
1529 if err < 0:
1530 exc = EXCEPTIONS.get(err, TransportException)
1531 raise exc("[%s]: %s" % (err, pn_error_text(pn_transport_error(self._trans))))
1532 else:
1533 return err
1534
1535 - def bind(self, connection):
1536 self._check(pn_transport_bind(self._trans, connection._conn))
1537
1539 pn_transport_trace(self._trans, n)
1540
1541 - def tick(self, now):
1542 return pn_transport_tick(self._trans, now)
1543
1545 cd, out = pn_transport_output(self._trans, n)
1546 if cd == PN_EOS:
1547 return None
1548 else:
1549 self._check(cd)
1550 return out
1551
1558
1561
1562 -class SASL(object):
1563
1564 OK = PN_SASL_OK
1565 AUTH = PN_SASL_AUTH
1566
1568 self._sasl = pn_sasl(transport._trans)
1569
1571 if err < 0:
1572 exc = EXCEPTIONS.get(err, SASLException)
1573 raise exc("[%s]" % (err))
1574 else:
1575 return err
1576
1578 pn_sasl_mechanisms(self._sasl, mechs)
1579
1581 pn_sasl_client(self._sasl)
1582
1584 pn_sasl_server(self._sasl)
1585
1586 - def plain(self, user, password):
1587 pn_sasl_plain(self._sasl, user, password)
1588
1589 - def send(self, data):
1590 self._check(pn_sasl_send(self._sasl, data, len(data)))
1591
1593 sz = 16
1594 while True:
1595 n, data = pn_sasl_recv(self._sasl, sz)
1596 if n == PN_OVERFLOW:
1597 sz *= 2
1598 continue
1599 elif n == PN_EOS:
1600 return None
1601 else:
1602 self._check(n)
1603 return data
1604
1605 @property
1607 outcome = pn_sasl_outcome(self._sasl)
1608 if outcome == PN_SASL_NONE:
1609 return None
1610 else:
1611 return outcome
1612
1613 - def done(self, outcome):
1614 pn_sasl_done(self._sasl, outcome)
1615
1617
1619 self._ssl = pn_ssl(transport._trans)
1620
1621 __all__ = ["Messenger", "Message", "ProtonException", "MessengerException",
1622 "MessageException", "Timeout", "Data", "Endpoint", "Connection",
1623 "Session", "Link", "Sender", "Receiver", "Delivery", "Transport",
1624 "TransportException", "SASL", "SSL", "PN_SESSION_WINDOW"]
1625