Package pyamf :: Package flex :: Module messaging

[hide private]
[frames] | no frames]

# Source Code for Module pyamf.flex.messaging

      1  # Copyright (c) 2007-2009 The PyAMF Project.
      2  # See LICENSE for details.
      3
      4  """
      5  Flex Messaging implementation.
      6
      7  This module contains the message classes used with Flex Data Services.
      8
      9  @see: U{RemoteObject on OSFlash (external)
     10  <http://osflash.org/documentation/amf3#remoteobject>}
     11
     12  @since: 0.1.0
     13  """
     14
     15  import pyamf
     16
     17  __all__ = [
     18      'RemotingMessage',
     19      'CommandMessage',
     20      'AcknowledgeMessage',
     21      'ErrorMessage'
     22  ]
     23
     24  NAMESPACE = 'flex.messaging.messages'
     25
     26 -class AbstractMessage(object):
     27      """
     28      Abstract base class for all Flex messages.
     29
     30      Messages have two customizable sections; headers and data. The headers
     31      property provides access to specialized meta information for a specific
     32      message instance. The data property contains the instance specific data
     33      that needs to be delivered and processed by the decoder.
     34
     35      @see: U{AbstractMessage on Livedocs (external)
     36      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/AbstractMessage.html>}
     37
     38      @ivar body: Specific data that needs to be delivered to the remote
     39          destination.
     40      @type body: C{mixed}
     41      @ivar clientId: Indicates which client sent the message.
     42      @type clientId: C{str}
     43      @ivar destination: Message destination.
     44      @type destination: C{str}
     45      @ivar headers: Message headers. Core header names start with DS.
     46      @type headers: C{dict}
     47      @ivar messageId: Unique Message ID.
     48      @type messageId: C{str}
     49      @ivar timeToLive: How long the message should be considered valid and
     50          deliverable.
     51      @type timeToLive: C{int}
     52      @ivar timestamp: Timestamp when the message was generated.
     53      @type timestamp: C{int}
     54      """
     55
     56      #: Each message pushed from the server will contain this header identifying
     57      #: the client that will receive the message.
     58      DESTINATION_CLIENT_ID_HEADER = "DSDstClientId"
     59      #: Messages are tagged with the endpoint id for the channel they are sent
     60      #: over.
     61      ENDPOINT_HEADER = "DSEndpoint"
     62      #: Messages that need to set remote credentials for a destination carry the
     63      #: C{Base64} encoded credentials in this header.
     64      REMOTE_CREDENTIALS_HEADER = "DSRemoteCredentials"
     65      #: The request timeout value is set on outbound messages by services or
     66      #: channels and the value controls how long the responder will wait for an
     67      #: acknowledgement, result or fault response for the message before timing
     68      #: out the request.
     69      REQUEST_TIMEOUT_HEADER = "DSRequestTimeout"
     70
     71 -    def __init__(self, *args, **kwargs):
     72          self.body = kwargs.get('body', None)
     73          self.clientId = kwargs.get('clientId', None)
     74          self.destination = kwargs.get('destination', None)
     75          self.headers = kwargs.get('headers', {})
     76          self.messageId = kwargs.get('messageId', None)
     77          self.timeToLive = kwargs.get('timeToLive', 0)
     78          self.timestamp = kwargs.get('timestamp', 0)
     79
     80 -    def __repr__(self):
     81          m = '<%s ' % self.__class__.__name__
     82
     83          for k, v in self.__dict__.iteritems():
     84              m += ' %s=%r' % (k, v)
     85
     86          return m + " />"
     87
     88  # This class shouldn't be encoded directly but is registered to allow
     89  # inheritable static attrs to work
     90  pyamf.register_class(AbstractMessage, '.'.join([NAMESPACE, 'AbstractMessage']),
     91      attrs=[
     92          'body', 'clientId', 'destination', 'headers', 'messageId',
     93          'timeToLive', 'timestamp'
     94      ], metadata=['amf3', 'static'])
     95
     96 -class AsyncMessage(AbstractMessage):
     97      """
     98      I am the base class for all asynchronous Flex messages.
     99
    100      @see: U{AsyncMessage on Livedocs (external)
    101      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/AsyncMessage.html>}
    102
    103      @ivar correlationId: Correlation id of the message.
    104      @type correlationId: C{str}
    105      """
    106
    107      #: Messages that were sent with a defined subtopic property indicate their
    108      #: target subtopic in this header.
    109      SUBTOPIC_HEADER = "DSSubtopic"
    110
    111 -    def __init__(self, *args, **kwargs):
    112          AbstractMessage.__init__(self, *args, **kwargs)
    113
    114          self.correlationId = kwargs.get('correlationId', None)
    115
    116  pyamf.register_class(AsyncMessage, '.'.join([NAMESPACE, 'AsyncMessage']),
    117      attrs=['correlationId'], metadata=['amf3', 'static'])
    118
    119 -class AcknowledgeMessage(AsyncMessage):
    120      """
    121      I acknowledge the receipt of a message that was sent previously.
    122
    123      Every message sent within the messaging system must receive an
    124      acknowledgement.
    125
    126      @see: U{AcknowledgeMessage on Livedocs (external)
    127      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/AcknowledgeMessage.html>}
    128      """
    129
    130      #: Used to indicate that the acknowledgement is for a message that
    131      #: generated an error.
    132      ERROR_HINT_HEADER = "DSErrorHint"
    133
    134  pyamf.register_class(AcknowledgeMessage, '.'.join([NAMESPACE, 'AcknowledgeMessage']),
    135      attrs=[], metadata=['amf3', 'static'])
    136
    137 -class CommandMessage(AsyncMessage):
    138      """
    139      Provides a mechanism for sending commands related to publish/subscribe
    140      messaging, ping, and cluster operations.
    141
    142      @see: U{CommandMessage on Livedocs (external)
    143      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/CommandMessage.html>}
    144
    145      @ivar operation: The command
    146      @type operation: C{int}
    147      @ivar messageRefType: hmm, not sure about this one.
    148      @type messageRefType: C{str}
    149      """
    150
    151      #: The server message type for authentication commands.
    152      AUTHENTICATION_MESSAGE_REF_TYPE = "flex.messaging.messages.AuthenticationMessage"
    153      #: This is used to test connectivity over the current channel to the remote
    154      #: endpoint.
    155      PING_OPERATION = 5
    156      #: This is used by a remote destination to sync missed or cached messages
    157      #: back to a client as a result of a client issued poll command.
    158      SYNC_OPERATION = 4
    159      #: This is used to request a list of failover endpoint URIs for the remote
    160      #: destination based on cluster membership.
    161      CLUSTER_REQUEST_OPERATION = 7
    162      #: This is used to send credentials to the endpoint so that the user can be
    163      #: logged in over the current channel. The credentials need to be C{Base64}
    164      #: encoded and stored in the body of the message.
    165      LOGIN_OPERATION = 8
    166      #: This is used to log the user out of the current channel, and will
    167      #: invalidate the server session if the channel is HTTP based.
    168      LOGOUT_OPERATION = 9
    169      #: This is used to poll a remote destination for pending, undelivered
    170      #: messages.
    171      POLL_OPERATION = 2
    172      #: Subscribe commands issued by a consumer pass the consumer's C{selector}
    173      #: expression in this header.
    174      SELECTOR_HEADER = "DSSelector"
    175      #: This is used to indicate that the client's session with a remote
    176      #: destination has timed out.
    177      SESSION_INVALIDATE_OPERATION = 10
    178      #: This is used to subscribe to a remote destination.
    179      SUBSCRIBE_OPERATION = 0
    180      #: This is the default operation for new L{CommandMessage} instances.
    181      UNKNOWN_OPERATION = 1000
    182      #: This is used to unsubscribe from a remote destination.
    183      UNSUBSCRIBE_OPERATION = 1
    184      #: This operation is used to indicate that a channel has disconnected.
    185      DISCONNECT_OPERATION = 12
    186
    187 -    def __init__(self, *args, **kwargs):
    188          AsyncMessage.__init__(self, *args, **kwargs)
    189
    190          self.operation = kwargs.get('operation', None)
    191          #: Remote destination belonging to a specific service, based upon
    192          #: whether this message type matches the message type the service
    193          #: handles.
    194          self.messageRefType = kwargs.get('messageRefType', None)
    195
    196  pyamf.register_class(CommandMessage, '.'.join([NAMESPACE, 'CommandMessage']),
    197      attrs=['operation', 'messageRefType'], metadata=['amf3', 'static'])
    198
    199 -class ErrorMessage(AcknowledgeMessage):
    200      """
    201      I am the Flex error message to be returned to the client.
    202
    203      This class is used to report errors within the messaging system.
    204
    205      @see: U{ErrorMessage on Livedocs (external)
    206      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/ErrorMessage.html>}
    207      """
    208
    209      #: If a message may not have been delivered, the faultCode will contain
    210      #: this constant.
    211      MESSAGE_DELIVERY_IN_DOUBT = "Client.Error.DeliveryInDoubt"
    212      #: Header name for the retryable hint header.
    213      #:
    214      #: This is used to indicate that the operation that generated the error may
    215      #: be retryable rather than fatal.
    216      RETRYABLE_HINT_HEADER = "DSRetryableErrorHint"
    217
    218 -    def __init__(self, *args, **kwargs):
    219          AcknowledgeMessage.__init__(self, *args, **kwargs)
    220          #: Extended data that the remote destination has chosen to associate
    221          #: with this error to facilitate custom error processing on the client.
    222          self.extendedData = kwargs.get('extendedData', {})
    223          #: Fault code for the error.
    224          self.faultCode = kwargs.get('faultCode', None)
    225          #: Detailed description of what caused the error.
    226          self.faultDetail = kwargs.get('faultDetail', None)
    227          #: A simple description of the error.
    228          self.faultString = kwargs.get('faultString', None)
    229          #: Should a traceback exist for the error, this property contains the
    230          #: message.
    231          self.rootCause = kwargs.get('rootCause', {})
    232
    233  pyamf.register_class(ErrorMessage, '.'.join([NAMESPACE, 'ErrorMessage']),
    234      attrs=['extendedData', 'faultCode', 'faultDetail', 'faultString', 'rootCause'],
    235      metadata=['amf3', 'static'])
    236
    237 -class RemotingMessage(AbstractMessage):
    238      """
    239      I am used to send RPC requests to a remote endpoint.
    240
    241      @see: U{RemotingMessage on Livedocs (external)
    242      <http://livedocs.adobe.com/flex/201/langref/mx/messaging/messages/RemotingMessage.html>}
    243      """
    244
    245 -    def __init__(self, *args, **kwargs):
    246          AbstractMessage.__init__(self, *args, **kwargs)
    247          #: Name of the remote method/operation that should be called.
    248          self.operation = kwargs.get('operation', None)
    249          #: Name of the service to be called including package name.
    250          #: This property is provided for backwards compatibility.
    251          self.source = kwargs.get('source', None)
    252
    253  pyamf.register_class(RemotingMessage, '.'.join([NAMESPACE, 'RemotingMessage']),
    254      attrs=['operation', 'source'], metadata=['amf3', 'static'])
    255