def send(self, msg):
         if self._log:
            bytes, isbinary = self._serializer.serialize(msg)
            print("Send: {}".format(bytes))

         reply = None

         if isinstance(msg, message.Publish):
            if msg.topic.startswith(u'com.myapp'):
               if msg.acknowledge:
                  reply = message.Published(msg.request, util.id())
            elif len(msg.topic) == 0:
               reply = message.Error(message.Publish.MESSAGE_TYPE, msg.request, u'wamp.error.invalid_topic')
            else:
               reply = message.Error(message.Publish.MESSAGE_TYPE, msg.request, u'wamp.error.not_authorized')

         elif isinstance(msg, message.Call):
            if msg.procedure == u'com.myapp.procedure1':
               reply = message.Result(msg.request, args = [100])
            elif msg.procedure == u'com.myapp.procedure2':
               reply = message.Result(msg.request, args = [1, 2, 3])
            elif msg.procedure == u'com.myapp.procedure3':
               reply = message.Result(msg.request, args = [1, 2, 3], kwargs = {u'foo': u'bar', u'baz': 23})

            elif msg.procedure.startswith(u'com.myapp.myproc'):
               registration = self._registrations[msg.procedure]
               request = util.id()
               self._invocations[request] = msg.request
               reply = message.Invocation(request, registration, args = msg.args, kwargs = msg.kwargs)
            else:
               reply = message.Error(message.Call.MESSAGE_TYPE, msg.request, u'wamp.error.no_such_procedure')

         elif isinstance(msg, message.Yield):
            if self._invocations.has_key(msg.request):
               request = self._invocations[msg.request]
               reply = message.Result(request, args = msg.args, kwargs = msg.kwargs)

         elif isinstance(msg, message.Subscribe):
            reply = message.Subscribed(msg.request, util.id())

         elif isinstance(msg, message.Unsubscribe):
            reply = message.Unsubscribed(msg.request)

         elif isinstance(msg, message.Register):
            registration = util.id()
            self._registrations[msg.procedure] = registration
            reply = message.Registered(msg.request, registration)

         elif isinstance(msg, message.Unregister):
            reply = message.Unregistered(msg.request)

         if reply:
            if self._log:
               bytes, isbinary = self._serializer.serialize(reply)
               print("Receive: {}".format(bytes))
            self._handler.onMessage(reply)
Exemple #2
0
    def __init__(self, uri, ordered=False, extra=None):
        """

        :param uri: The URI (or URI pattern) for this observation.
        :type uri: unicode
        """
        # URI (or URI pattern) this observation is created for
        self.uri = uri

        # flag indicating whether observers should be maintained
        # in an ordered set or a regular, unordered set
        self.ordered = ordered

        # arbitrary, opaque extra data attached to the observation
        self.extra = extra

        # generate a new ID for the observation
        self.id = util.id()

        # UTC timestamp this observation was created
        self.created = util.utcnow()

        # set of observers
        if self.ordered:
            self.observers = OrderedSet()
        else:
            self.observers = set()

        # arbitrary, opaque extra data attached to the observers of this observation
        self.observers_extra = {}
Exemple #3
0
    def _unsubscribe(self, subscription):
        """
        Called from :meth:`autobahn.wamp.protocol.Subscription.unsubscribe`
        """
        assert (isinstance(subscription, Subscription))
        assert subscription.active
        assert (subscription.id in self._subscriptions)
        assert (subscription in self._subscriptions[subscription.id])

        if not self._transport:
            raise exception.TransportLost()

        # remove handler subscription and mark as inactive
        self._subscriptions[subscription.id].remove(subscription)
        subscription.active = False

        # number of handler subscriptions left ..
        scount = len(self._subscriptions[subscription.id])

        if scount == 0:
            # if the last handler was removed, unsubscribe from broker ..
            request_id = util.id()

            on_reply = txaio.create_future()
            self._unsubscribe_reqs[request_id] = UnsubscribeRequest(
                request_id, on_reply, subscription.id)

            msg = message.Unsubscribe(request_id, subscription.id)

            self._transport.send(msg)
            return on_reply
        else:
            # there are still handlers active on the subscription!
            return txaio.create_future_success(scount)
Exemple #4
0
   def call(self, procedure, *args, **kwargs):
      """
      Implements :func:`autobahn.wamp.interfaces.ICaller.call`
      """
      if six.PY2 and type(procedure) == str:
         procedure = six.u(procedure)
      assert(isinstance(procedure, six.text_type))

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      if 'options' in kwargs and isinstance(kwargs['options'], types.CallOptions):
         opts = kwargs.pop('options')
         msg = message.Call(request, procedure, args = args, kwargs = kwargs, **opts.options)
      else:
         opts = None
         msg = message.Call(request, procedure, args = args, kwargs = kwargs)

      ## FIXME
      #def canceller(_d):
      #   cancel_msg = message.Cancel(request)
      #   self._transport.send(cancel_msg)
      #d = Deferred(canceller)
      d = self._create_future()
      self._call_reqs[request] = d, opts

      self._transport.send(msg)
      return d
Exemple #5
0
            def process_will(res):

                akw = mqtt_payload_transform(
                    self._wamp_session._router._mqtt_payload_format,
                    packet.will_message)

                if not akw:
                    # Drop it I guess :(
                    return res

                args, kwargs = akw

                msg = message.Call(
                    request=util.id(),
                    procedure=u"wamp.session.add_testament",
                    args=[
                        u".".join(tokenise_mqtt_topic(packet.will_topic)),
                        args, kwargs, {
                            "retain": bool(packet.flags.will_retain)
                        }
                    ])

                self._wamp_session.onMessage(msg)

                return res
Exemple #6
0
   def publish(self, topic, *args, **kwargs):
      """
      Implements :func:`autobahn.wamp.interfaces.IPublisher.publish`
      """
      if six.PY2 and type(topic) == str:
         topic = six.u(topic)
      assert(type(topic) == six.text_type)

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      if 'options' in kwargs and isinstance(kwargs['options'], types.PublishOptions):
         opts = kwargs.pop('options')
         msg = message.Publish(request, topic, args = args, kwargs = kwargs, **opts.options)
      else:
         opts = None
         msg = message.Publish(request, topic, args = args, kwargs = kwargs)

      if opts and opts.options['acknowledge'] == True:
         d = self._create_future()
         self._publish_reqs[request] = d, opts
         self._transport.send(msg)
         return d
      else:
         self._transport.send(msg)
         return
   def processRegister(self, session, register):
      """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processRegister`
      """
      assert(session in self._session_to_registrations)

      ## check topic URI
      ##
      if self._option_uri_strict and not _URI_PAT_STRICT.match(register.procedure):

         reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.INVALID_URI)

      else:

         if not register.procedure in self._procs_to_regs:
            registration_id = util.id()
            self._procs_to_regs[register.procedure] = (registration_id, session)
            self._regs_to_procs[registration_id] = register.procedure

            self._session_to_registrations[session].add(registration_id)

            reply = message.Registered(register.request, registration_id)
         else:
            reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.PROCEDURE_ALREADY_EXISTS)

      session._transport.send(reply)
Exemple #8
0
   def processCall(self, session, call):
      """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processCall`
      """
      assert(session in self._session_to_registrations)

      if call.procedure in self._procs_to_regs:
         registration_id, endpoint_session = self._procs_to_regs[call.procedure]

         request_id = util.id()

         if call.discloseMe:
            caller = session._session_id
         else:
            caller = None

         invocation = message.Invocation(request_id,
                                         registration_id,
                                         args = call.args,
                                         kwargs = call.kwargs,
                                         timeout = call.timeout,
                                         receive_progress = call.receive_progress,
                                         caller = caller)

         self._invocations[request_id] = (call, session)
         endpoint_session._transport.send(invocation)
      else:
         reply = message.Error(message.Call.MESSAGE_TYPE, call.request, 'wamp.error.no_such_procedure')
         session._transport.send(reply)
Exemple #9
0
         def on_authorize_success(authorized):
            if not authorized:

               reply = message.Error(message.Subscribe.MESSAGE_TYPE, subscribe.request, ApplicationError.NOT_AUTHORIZED, ["session is not authorized to subscribe to topic '{0}'".format(subscribe.topic)])

            else:

               if not subscribe.topic in self._topic_to_sessions:
                  subscription = util.id()
                  self._topic_to_sessions[subscribe.topic] = (subscription, set())

               subscription, subscribers = self._topic_to_sessions[subscribe.topic]

               if not session in subscribers:
                  subscribers.add(session)

               if not subscription in self._subscription_to_sessions:
                  self._subscription_to_sessions[subscription] = (subscribe.topic, set())

               _, subscribers = self._subscription_to_sessions[subscription]
               if not session in subscribers:
                  subscribers.add(session)

               if not subscription in self._session_to_subscriptions[session]:
                  self._session_to_subscriptions[session].add(subscription)

               reply = message.Subscribed(subscribe.request, subscription)

            session._transport.send(reply)
    def _unsubscribe(self, subscription):
        """
        Called from :meth:`autobahn.wamp.protocol.Subscription.unsubscribe`
        """
        assert(isinstance(subscription, Subscription))
        assert subscription.active
        assert(subscription.id in self._subscriptions)
        assert(subscription in self._subscriptions[subscription.id])

        if not self._transport:
            raise exception.TransportLost()

        # remove handler subscription and mark as inactive
        self._subscriptions[subscription.id].remove(subscription)
        subscription.active = False

        # number of handler subscriptions left ..
        scount = len(self._subscriptions[subscription.id])

        if scount == 0:
            # if the last handler was removed, unsubscribe from broker ..
            request_id = util.id()

            on_reply = txaio.create_future()
            self._unsubscribe_reqs[request_id] = UnsubscribeRequest(request_id, on_reply, subscription.id)

            msg = message.Unsubscribe(request_id, subscription.id)

            self._transport.send(msg)
            return on_reply
        else:
            # there are still handlers active on the subscription!
            return txaio.create_future_success(scount)
Exemple #11
0
    def __init__(self, uri, ordered=False, extra=None):
        """

        :param uri: The URI (or URI pattern) for this observation.
        :type uri: unicode
        """
        # URI (or URI pattern) this observation is created for
        self.uri = uri

        # flag indicating whether observers should be maintained
        # in an ordered set or a regular, unordered set
        self.ordered = ordered

        # arbitrary, opaque extra data attached to the observation
        self.extra = extra

        # generate a new ID for the observation
        self.id = util.id()

        # UTC timestamp this observation was created
        self.created = util.utcnow()

        # set of observers
        if self.ordered:
            self.observers = OrderedSet()
        else:
            self.observers = set()
            def on_authorize(authorized):
               if authorized:
                  registration_id, endpoint_session, discloseCaller = self._procs_to_regs[call.procedure]

                  request_id = util.id()

                  if discloseCaller or call.discloseMe:
                     caller = session._session_id
                     authid = session._authid
                     authrole = session._authrole
                     authmethod = session._authmethod
                  else:
                     caller = None
                     authid = None
                     authrole = None
                     authmethod = None

                  invocation = message.Invocation(request_id,
                                                  registration_id,
                                                  args = call.args,
                                                  kwargs = call.kwargs,
                                                  timeout = call.timeout,
                                                  receive_progress = call.receive_progress,
                                                  caller = caller,
                                                  authid = authid,
                                                  authrole = authrole,
                                                  authmethod = authmethod)

                  self._invocations[request_id] = (call, session)
                  endpoint_session._transport.send(invocation)
               else:
                  reply = message.Error(message.Call.MESSAGE_TYPE, call.request, ApplicationError.NOT_AUTHORIZED, ["session is not authorized to call procedure '{}'".format(call.procedure)])
                  session._transport.send(reply)                 
Exemple #13
0
   def call(self, procedure, *args, **kwargs):
      """
      Implements :func:`autobahn.wamp.interfaces.ICaller.call`
      """
      assert(type(procedure) in (str, unicode))

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      if 'options' in kwargs and isinstance(kwargs['options'], types.CallOptions):
         opts = kwargs.pop('options')
         msg = message.Call(request, procedure, args = args, kwargs = kwargs, **opts.options)
      else:
         opts = None
         msg = message.Call(request, procedure, args = args, kwargs = kwargs)

      def canceller(_d):
         cancel_msg = message.Cancel(request)
         self._transport.send(cancel_msg)

      d = Deferred(canceller)
      self._call_reqs[request] = d, opts

      self._transport.send(msg)
      return d
Exemple #14
0
   def publish(self, topic, *args, **kwargs):
      """
      Implements :func:`autobahn.wamp.interfaces.IPublisher.publish`
      """
      if six.PY2 and type(topic) == str:
         topic = six.u(topic)
      assert(type(topic) == six.text_type)

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      if 'options' in kwargs and isinstance(kwargs['options'], types.PublishOptions):
         opts = kwargs.pop('options')
         msg = message.Publish(request, topic, args = args, kwargs = kwargs, **opts.options)
      else:
         opts = None
         msg = message.Publish(request, topic, args = args, kwargs = kwargs)

      if opts and opts.options['acknowledge'] == True:
         d = self._create_future()
         self._publish_reqs[request] = d, opts
         self._transport.send(msg)
         return d
      else:
         self._transport.send(msg)
         return
Exemple #15
0
    def _publish(self, event, acknowledge=None):
        """
        Given a MQTT event, create a WAMP Publish message and
        forward that on the forwarding WAMP session.
        """
        try:
            payload_format, mapped_topic, options = yield self.factory.transform_mqtt(event.topic_name, event.payload)
        except:
            self.log.failure()
            return

        request = util.id()

        msg = message.Publish(
            request=request,
            topic=mapped_topic,
            exclude_me=False,
            acknowledge=acknowledge,
            retain=event.retain,
            **options)

        self._wamp_session.onMessage(msg)

        if event.qos_level > 0:
            self._request_to_packetid[request] = event.packet_identifier

        returnValue(0)
Exemple #16
0
   def call(self, procedure, *args, **kwargs):
      """
      Implements :func:`autobahn.wamp.interfaces.ICaller.call`
      """
      if six.PY2 and type(procedure) == str:
         procedure = six.u(procedure)
      assert(isinstance(procedure, six.text_type))

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      if 'options' in kwargs and isinstance(kwargs['options'], types.CallOptions):
         opts = kwargs.pop('options')
         msg = message.Call(request, procedure, args = args, kwargs = kwargs, **opts.options)
      else:
         opts = None
         msg = message.Call(request, procedure, args = args, kwargs = kwargs)

      ## FIXME
      #def canceller(_d):
      #   cancel_msg = message.Cancel(request)
      #   self._transport.send(cancel_msg)
      #d = Deferred(canceller)
      d = self._create_future()
      self._call_reqs[request] = d, opts

      self._transport.send(msg)
      return d
Exemple #17
0
            def process_will(res):

                self.log.info()

                payload_format, mapped_topic, options = yield self.factory.transform_mqtt(packet.will_topic, packet.will_message)

                request = util.id()

                msg = message.Call(
                    request=request,
                    procedure=u"wamp.session.add_testament",
                    args=[
                        mapped_topic,
                        options.get('args', None),
                        options.get('kwargs', None),
                        {
                            # specifiy "retain" for when the testament (last will)
                            # will be auto-published by the broker later
                            u'retain': bool(packet.flags.will_retain)
                        }
                    ])

                self._wamp_session.onMessage(msg)

                returnValue(res)
Exemple #18
0
   def processSubscribe(self, session, subscribe):
      """
      Implements :func:`autobahn.wamp.interfaces.IBroker.processSubscribe`
      """
      assert(session in self._session_to_subscriptions)

      if True:

         if not subscribe.topic in self._topic_to_sessions:
            subscription = util.id()
            self._topic_to_sessions[subscribe.topic] = (subscription, set())

         subscription, subscribers = self._topic_to_sessions[subscribe.topic]

         if not session in subscribers:
            subscribers.add(session)

         if not subscription in self._subscription_to_sessions:
            self._subscription_to_sessions[subscription] = (subscribe.topic, set())

         _, subscribers = self._subscription_to_sessions[subscription]
         if not session in subscribers:
            subscribers.add(session)

         if not subscription in self._session_to_subscriptions[session]:
            self._session_to_subscriptions[session].add(subscription)

         reply = message.Subscribed(subscribe.request, subscription)

      else:
         reply = message.Error(message.Subscribe.MESSAGE_TYPE, subscribe.request, ApplicationError.INVALID_TOPIC)

      session._transport.send(reply)
Exemple #19
0
                def _get_retained_event():

                    if subscription.extra.retained_events:
                        retained_events = list(subscription.extra.retained_events)
                        retained_events.reverse()

                        for publish in retained_events:
                            authorised = False

                            if not publish.exclude and not publish.eligible:
                                authorised = True
                            elif session._session_id in publish.eligible and session._session_id not in publish.exclude:
                                authorised = True

                            if authorised:
                                publication = util.id()

                                if publish.payload:
                                    msg = message.Event(subscription.id,
                                                        publication,
                                                        payload=publish.payload,
                                                        retained=True,
                                                        enc_algo=publish.enc_algo,
                                                        enc_key=publish.enc_key,
                                                        enc_serializer=publish.enc_serializer)
                                else:
                                    msg = message.Event(subscription.id,
                                                        publication,
                                                        args=publish.args,
                                                        kwargs=publish.kwargs,
                                                        retained=True)

                                return [msg]
                    return []
Exemple #20
0
   def processRegister(self, session, register):
      """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processRegister`
      """
      assert(session in self._session_to_registrations)

      ## check procedure URI
      ##
      if (not self._option_uri_strict and not  _URI_PAT_LOOSE_NON_EMPTY.match(register.procedure)) or \
         (    self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(register.procedure)):

         reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.INVALID_URI, ["register for invalid procedure URI '{}'".format(register.procedure)])

      else:

         if not register.procedure in self._procs_to_regs:
            registration_id = util.id()
            self._procs_to_regs[register.procedure] = (registration_id, session, register.discloseCaller)
            self._regs_to_procs[registration_id] = register.procedure

            self._session_to_registrations[session].add(registration_id)

            reply = message.Registered(register.request, registration_id)
         else:
            reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.PROCEDURE_ALREADY_EXISTS, ["register for already registered procedure URI '{}'".format(register.procedure)])

      session._transport.send(reply)
Exemple #21
0
   def onMessage(self, msg):
      """
      Implements :func:`autobahn.wamp.interfaces.ITransportHandler.onMessage`
      """
      if self._session_id is None:

         ## the first message MUST be HELLO
         if isinstance(msg, message.Hello):

            self._session_id = util.id()
            self._goodbye_sent = False

            self._router = self._router_factory.get(msg.realm)
            if not self._router:
               raise Exception("no such realm")

            roles = []

            self._router.attach(self)

            roles.append(role.RoleBrokerFeatures())
            roles.append(role.RoleDealerFeatures())

            msg = message.Welcome(self._session_id, roles)
            self._transport.send(msg)


            self.onJoin(SessionDetails(self._session_id))
         else:
            raise ProtocolError("Received {} message, and session is not yet established".format(msg.__class__))

      else:

         if isinstance(msg, message.Hello):
            raise ProtocolError("HELLO message received, while session is already established")

         elif isinstance(msg, message.Goodbye):
            if not self._goodbye_sent:
               ## the peer wants to close: send GOODBYE reply
               reply = message.Goodbye()
               self._transport.send(reply)

            ## fire callback and close the transport
            self.onLeave(types.CloseDetails(msg.reason, msg.message))

            self._router.detach(self)

            self._session_id = None

            #self._transport.close()

         elif isinstance(msg, message.Heartbeat):

            pass ## FIXME

         else:

            self._router.process(self, msg)
    def processCall(self, session, call):
        """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processCall`
      """
        assert (session in self._session_to_registrations)

        ## check procedure URI
        ##
        if (not self._option_uri_strict and not  _URI_PAT_LOOSE_NON_EMPTY.match(call.procedure)) or \
           (    self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(call.procedure)):

            reply = message.Error(
                message.Register.MESSAGE_TYPE, call.request,
                ApplicationError.INVALID_URI, [
                    "call with invalid procedure URI '{}'".format(
                        call.procedure)
                ])
            session._transport.send(reply)

        else:

            if call.procedure in self._procs_to_regs:
                registration_id, endpoint_session, discloseCaller = self._procs_to_regs[
                    call.procedure]

                request_id = util.id()

                if discloseCaller or call.discloseMe:
                    caller = session._session_id
                    authid = session._authid
                    authrole = session._authrole
                    authmethod = session._authmethod
                else:
                    caller = None
                    authid = None
                    authrole = None
                    authmethod = None

                invocation = message.Invocation(
                    request_id,
                    registration_id,
                    args=call.args,
                    kwargs=call.kwargs,
                    timeout=call.timeout,
                    receive_progress=call.receive_progress,
                    caller=caller,
                    authid=authid,
                    authrole=authrole,
                    authmethod=authmethod)

                self._invocations[request_id] = (call, session)
                endpoint_session._transport.send(invocation)
            else:
                reply = message.Error(
                    message.Call.MESSAGE_TYPE, call.request,
                    ApplicationError.NO_SUCH_PROCEDURE,
                    ["no procedure '{}' registered".format(call.procedure)])
                session._transport.send(reply)
Exemple #23
0
   def send(self, msg):
      """
      Implements :func:`autobahn.wamp.interfaces.ITransport.send`
      """
      if isinstance(msg, message.Hello):

         self._router = self._routerFactory.get(msg.realm)

         ## fake session ID assignment (normally done in WAMP opening handshake)
         self._session._session_id = util.id()

         ## add app session to router
         self._router.attach(self._session)

         ## fake app session open
         ##
         self._session.onJoin(SessionDetails(self._session._session_id))


      ## app-to-router
      ##
      elif isinstance(msg, message.Publish) or \
         isinstance(msg, message.Subscribe) or \
         isinstance(msg, message.Unsubscribe) or \
         isinstance(msg, message.Call) or \
         isinstance(msg, message.Yield) or \
         isinstance(msg, message.Register) or \
         isinstance(msg, message.Unregister) or \
         isinstance(msg, message.Cancel) or \
         (isinstance(msg, message.Error) and msg.request_type == message.Invocation.MESSAGE_TYPE):

         ## deliver message to router
         ##
         self._router.process(self._session, msg)

      ## router-to-app
      ##
      elif isinstance(msg, message.Event) or \
           isinstance(msg, message.Invocation) or \
           isinstance(msg, message.Result) or \
           isinstance(msg, message.Published) or \
           isinstance(msg, message.Subscribed) or \
           isinstance(msg, message.Unsubscribed) or \
           isinstance(msg, message.Registered) or \
           isinstance(msg, message.Unregistered) or \
          (isinstance(msg, message.Error) and msg.request_type == message.Call.MESSAGE_TYPE):

         ## deliver message to app session
         ##
         self._session.onMessage(msg)

      else:
         ## should not arrive here
         ##
         raise Exception("WampRouterAppSession.send: unhandled message {}".format(msg))
Exemple #24
0
                def _get_retained_event():

                    if subscription.extra.retained_events:
                        retained_events = list(
                            subscription.extra.retained_events)
                        retained_events.reverse()

                        for retained_event in retained_events:
                            authorized = False

                            if not retained_event.publish.exclude and not retained_event.publish.eligible:
                                authorized = True
                            elif session._session_id in retained_event.publish.eligible and session._session_id not in retained_event.publish.exclude:
                                authorized = True

                            if authorized:
                                publication = util.id()

                                if retained_event.publish.payload:
                                    msg = message.Event(
                                        subscription.id,
                                        publication,
                                        payload=retained_event.publish.payload,
                                        enc_algo=retained_event.publish.
                                        enc_algo,
                                        enc_key=retained_event.publish.enc_key,
                                        enc_serializer=retained_event.publish.
                                        enc_serializer,
                                        publisher=retained_event.publisher,
                                        publisher_authid=retained_event.
                                        publisher_authid,
                                        publisher_authrole=retained_event.
                                        publisher_authrole,
                                        retained=True)
                                else:
                                    msg = message.Event(
                                        subscription.id,
                                        publication,
                                        args=retained_event.publish.args,
                                        kwargs=retained_event.publish.kwargs,
                                        publisher=retained_event.publisher,
                                        publisher_authid=retained_event.
                                        publisher_authid,
                                        publisher_authrole=retained_event.
                                        publisher_authrole,
                                        retained=True)

                                msg.correlation_id = subscribe.correlation_id
                                msg.correlation_uri = subscribe.topic
                                msg.correlation_is_anchor = False
                                msg.correlation_is_last = False

                                return [msg]
                    return []
Exemple #25
0
         def welcome(realm, authid = None):
            self._session_id = util.id()
            self._goodbye_sent = False

            self._router = self._router_factory.get(realm)
            if not self._router:
               raise Exception("no such realm")

            roles = self._router.attach(self)
            msg = message.Welcome(self._session_id, roles, authid)
            self._transport.send(msg)

            self.onJoin(SessionDetails(self._session_id))
Exemple #26
0
      def _register(obj, endpoint, procedure, options):
         request = util.id()

         d = self._create_future()
         self._register_reqs[request] = (d, obj, endpoint, procedure, options)

         if options is not None:
            msg = message.Register(request, procedure, **options.options)
         else:
            msg = message.Register(request, procedure)

         self._transport.send(msg)
         return d
        def _subscribe(obj, fn, topic, options):
            request_id = util.id()
            on_reply = txaio.create_future()
            handler_obj = Handler(fn, obj, options.details_arg if options else None)
            self._subscribe_reqs[request_id] = SubscribeRequest(request_id, on_reply, handler_obj)

            if options:
                msg = message.Subscribe(request_id, topic, **options.message_attr())
            else:
                msg = message.Subscribe(request_id, topic)

            self._transport.send(msg)
            return on_reply
Exemple #28
0
      def _subscribe(obj, handler, topic, options):
         request = util.id()

         d = self._create_future()
         self._subscribe_reqs[request] = (d, obj, handler, topic, options)

         if options is not None:
            msg = message.Subscribe(request, topic, **options.options)
         else:
            msg = message.Subscribe(request, topic)

         self._transport.send(msg)
         return d
        def _register(obj, fn, procedure, options):
            request_id = util.id()
            on_reply = txaio.create_future()
            endpoint_obj = Endpoint(fn, obj, options.details_arg if options else None)
            self._register_reqs[request_id] = RegisterRequest(request_id, on_reply, procedure, endpoint_obj)

            if options:
                msg = message.Register(request_id, procedure, **options.message_attr())
            else:
                msg = message.Register(request_id, procedure)

            self._transport.send(msg)
            return on_reply
Exemple #30
0
            def on_authorize_success(authorized):
               if authorized:
                  registration_id = util.id()
                  self._procs_to_regs[register.procedure] = (registration_id, session, register.discloseCaller, register.discloseCallerTransport)
                  self._regs_to_procs[registration_id] = register.procedure

                  self._session_to_registrations[session].add(registration_id)

                  reply = message.Registered(register.request, registration_id)
               else:
                  reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.NOT_AUTHORIZED, ["session is not authorized to register procedure '{0}'".format(register.procedure)])

               session._transport.send(reply)
            def on_authorize(authorized):
               if authorized:
                  registration_id = util.id()
                  self._procs_to_regs[register.procedure] = (registration_id, session, register.discloseCaller)
                  self._regs_to_procs[registration_id] = register.procedure

                  self._session_to_registrations[session].add(registration_id)

                  reply = message.Registered(register.request, registration_id)
               else:
                  reply = message.Error(message.Register.MESSAGE_TYPE, register.request, ApplicationError.NOT_AUTHORIZED, ["session is not authorized to register procedure URI '{}'".format(register.procedure)])

               session._transport.send(reply)
Exemple #32
0
      def _register(obj, endpoint, procedure, options):
         request = util.id()

         d = self._create_future()
         self._register_reqs[request] = (d, obj, endpoint, procedure, options)

         if options is not None:
            msg = message.Register(request, procedure, **options.options)
         else:
            msg = message.Register(request, procedure)

         self._transport.send(msg)
         return d
Exemple #33
0
      def _subscribe(obj, handler, topic, options):
         request = util.id()

         d = self._create_future()
         self._subscribe_reqs[request] = (d, obj, handler, topic, options)

         if options is not None:
            msg = message.Subscribe(request, topic, **options.options)
         else:
            msg = message.Subscribe(request, topic)

         self._transport.send(msg)
         return d
Exemple #34
0
    def session_add_testament(self,
                              topic,
                              args,
                              kwargs,
                              publish_options=None,
                              scope=u"destroyed",
                              details=None):
        """
        Add a testament to the current session.

        :param topic: The topic to publish the testament to.
        :type topic: str

        :param args: A list of arguments for the publish.
        :type args: list or tuple

        :param kwargs: A dict of keyword arguments for the publish.
        :type kwargs: dict

        :param publish_options: The publish options for the publish.
        :type publish_options: None or dict

        :param scope: The scope of the testament, either "detached" or
            "destroyed".
        :type scope: str

        :returns: The publication ID.
        :rtype: int
        """
        session = self._router._session_id_to_session[details.caller]

        if scope not in [u"destroyed", u"detached"]:
            raise ApplicationError(u"wamp.error.testament_error",
                                   u"scope must be destroyed or detached")

        pub_id = util.id()

        # Get the publish options, remove some explicit keys
        publish_options = publish_options or {}
        publish_options.pop("acknowledge", None)
        publish_options.pop("exclude_me", None)

        pub = message.Publish(request=pub_id,
                              topic=topic,
                              args=args,
                              kwargs=kwargs,
                              **publish_options)

        session._testaments[scope].append(pub)

        return pub_id
Exemple #35
0
    def call(self, procedure, *args, **kwargs):
        """
        Implements :func:`autobahn.wamp.interfaces.ICaller.call`
        """
        if six.PY2 and type(procedure) == str:
            procedure = six.u(procedure)
        assert (isinstance(procedure, six.text_type))

        if not self._transport:
            raise exception.TransportLost()

        request_id = util.id()

        if 'options' in kwargs and isinstance(kwargs['options'],
                                              types.CallOptions):
            options = kwargs.pop('options')
            msg = message.Call(request_id,
                               procedure,
                               args=args,
                               kwargs=kwargs,
                               **options.message_attr())
        else:
            options = None
            msg = message.Call(request_id, procedure, args=args, kwargs=kwargs)

        # FIXME
        # def canceller(_d):
        #   cancel_msg = message.Cancel(request)
        #   self._transport.send(cancel_msg)
        # d = Deferred(canceller)

        on_reply = self._create_future()
        self._call_reqs[request_id] = CallRequest(request_id, on_reply,
                                                  options)

        try:
            # Notes:
            #
            # * this might raise autobahn.wamp.exception.SerializationError
            #   when the user payload cannot be serialized
            # * we have to setup a PublishRequest() in _publish_reqs _before_
            #   calling transpor.send(), because a mock- or side-by-side transport
            #   will immediately lead on an incoming WAMP message in onMessage()
            #
            self._transport.send(msg)
        except Exception as e:
            if request_id in self._call_reqs:
                del self._call_reqs[request_id]
            raise e

        return on_reply
Exemple #36
0
    def publish(self, topic, *args, **kwargs):
        """
        Implements :func:`autobahn.wamp.interfaces.IPublisher.publish`
        """
        if six.PY2 and type(topic) == str:
            topic = six.u(topic)
        assert (type(topic) == six.text_type)

        if not self._transport:
            raise exception.TransportLost()

        request_id = util.id()

        if 'options' in kwargs and isinstance(kwargs['options'],
                                              types.PublishOptions):
            options = kwargs.pop('options')
            msg = message.Publish(request_id,
                                  topic,
                                  args=args,
                                  kwargs=kwargs,
                                  **options.message_attr())
        else:
            options = None
            msg = message.Publish(request_id, topic, args=args, kwargs=kwargs)

        if options and options.acknowledge:
            # only acknowledged publications expect a reply ..
            on_reply = self._create_future()
            self._publish_reqs[request_id] = PublishRequest(
                request_id, on_reply)
        else:
            on_reply = None

        try:
            # Notes:
            #
            # * this might raise autobahn.wamp.exception.SerializationError
            #   when the user payload cannot be serialized
            # * we have to setup a PublishRequest() in _publish_reqs _before_
            #   calling transpor.send(), because a mock- or side-by-side transport
            #   will immediately lead on an incoming WAMP message in onMessage()
            #
            self._transport.send(msg)
        except Exception as e:
            if request_id in self._publish_reqs:
                del self._publish_reqs[request_id]
            raise e

        return on_reply
Exemple #37
0
    def __init__(self, handler):
        self._log = False
        self._handler = handler
        self._serializer = serializer.JsonSerializer()
        self._registrations = {}
        self._invocations = {}
        self._subscription_topics = {}
        self._my_session_id = util.id()

        self._handler.onOpen(self)

        roles = {u'broker': role.RoleBrokerFeatures(), u'dealer': role.RoleDealerFeatures()}

        msg = message.Welcome(self._my_session_id, roles)
        self._handler.onMessage(msg)
Exemple #38
0
   def processCall(self, session, call):
      """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processCall`
      """
      assert(session in self._session_to_registrations)

      ## check procedure URI
      ##
      if (not self._option_uri_strict and not  _URI_PAT_LOOSE_NON_EMPTY.match(call.procedure)) or \
         (    self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(call.procedure)):

         reply = message.Error(message.Register.MESSAGE_TYPE, call.request, ApplicationError.INVALID_URI, ["call with invalid procedure URI '{}'".format(call.procedure)])
         session._transport.send(reply)

      else:

         if call.procedure in self._procs_to_regs:
            registration_id, endpoint_session, discloseCaller = self._procs_to_regs[call.procedure]

            request_id = util.id()

            if discloseCaller or call.discloseMe:
               caller = session._session_id
               authid = session._authid
               authrole = session._authrole
               authmethod = session._authmethod
            else:
               caller = None
               authid = None
               authrole = None
               authmethod = None

            invocation = message.Invocation(request_id,
                                            registration_id,
                                            args = call.args,
                                            kwargs = call.kwargs,
                                            timeout = call.timeout,
                                            receive_progress = call.receive_progress,
                                            caller = caller,
                                            authid = authid,
                                            authrole = authrole,
                                            authmethod = authmethod)

            self._invocations[request_id] = (call, session)
            endpoint_session._transport.send(invocation)
         else:
            reply = message.Error(message.Call.MESSAGE_TYPE, call.request, ApplicationError.NO_SUCH_PROCEDURE, ["no procedure '{}' registered".format(call.procedure)])
            session._transport.send(reply)
Exemple #39
0
    def _publish(self, event, options):

        request = util.id()
        msg = message.Publish(request=request,
                              topic=u".".join(
                                  tokenise_mqtt_topic(event.topic_name)),
                              payload=event.payload,
                              **options.message_attr())
        msg._mqtt_publish = True

        self._wamp_session.onMessage(msg)

        if event.qos_level > 0:
            self._request_to_packetid[request] = event.packet_identifier

        return succeed(0)
Exemple #40
0
        def _subscribe(obj, fn, topic, options):
            request_id = util.id()
            on_reply = self._create_future()
            handler_obj = Handler(fn, obj,
                                  options.details_arg if options else None)
            self._subscribe_reqs[request_id] = SubscribeRequest(
                request_id, on_reply, handler_obj)

            if options:
                msg = message.Subscribe(request_id, topic,
                                        **options.message_attr())
            else:
                msg = message.Subscribe(request_id, topic)

            self._transport.send(msg)
            return on_reply
Exemple #41
0
        def _register(obj, fn, procedure, options):
            request_id = util.id()
            on_reply = self._create_future()
            endpoint_obj = Endpoint(fn, obj,
                                    options.details_arg if options else None)
            self._register_reqs[request_id] = RegisterRequest(
                request_id, on_reply, procedure, endpoint_obj)

            if options:
                msg = message.Register(request_id, procedure,
                                       **options.message_attr())
            else:
                msg = message.Register(request_id, procedure)

            self._transport.send(msg)
            return on_reply
Exemple #42
0
                def on_authorize_success(authorized):
                    if authorized:
                        registration_id, endpoint_session, discloseCaller, discloseCallerTransport = self._procs_to_regs[
                            call.procedure]

                        request_id = util.id()

                        if discloseCaller or call.discloseMe:
                            caller = session._session_id
                            caller_transport = None
                            authid = session._authid
                            authrole = session._authrole
                            authmethod = session._authmethod
                            if discloseCallerTransport and hasattr(
                                    session._transport, '_transport_info'):
                                caller_transport = session._transport._transport_info
                        else:
                            caller = None
                            caller_transport = None
                            authid = None
                            authrole = None
                            authmethod = None

                        invocation = message.Invocation(
                            request_id,
                            registration_id,
                            args=call.args,
                            kwargs=call.kwargs,
                            timeout=call.timeout,
                            receive_progress=call.receive_progress,
                            caller=caller,
                            caller_transport=caller_transport,
                            authid=authid,
                            authrole=authrole,
                            authmethod=authmethod)

                        self._invocations[request_id] = (call, session)
                        endpoint_session._transport.send(invocation)
                    else:
                        reply = message.Error(
                            message.Call.MESSAGE_TYPE, call.request,
                            ApplicationError.NOT_AUTHORIZED, [
                                "session is not authorized to call procedure '{0}'"
                                .format(call.procedure)
                            ])
                        session._transport.send(reply)
Exemple #43
0
    def test_non_depleting(self):
        res = {}

        with open('/dev/urandom', 'rb') as rng:
            for i in range(1000):
                for j in range(100):

                    # "reseed" (seems pointless, but ..)
                    random.seed()

                    # random UUIDs
                    v1 = uuid.uuid4()  # noqa

                    # stdlib random
                    v2 = random.random()  # noqa
                    v3 = random.getrandbits(32)  # noqa
                    v4 = random.randint(0, 9007199254740992)  # noqa
                    v5 = random.normalvariate(10, 100)  # noqa
                    v6 = random.choice(range(100))  # noqa

                    # PyNaCl
                    v7 = utils.random(public.Box.NONCE_SIZE)  # noqa

                    # Autobahn utils
                    v8 = util.generate_token(4, 4)  # noqa
                    v9 = util.id()  # noqa
                    v10 = util.rid()  # noqa
                    v11 = util.newid()  # noqa

                # direct procfs access to PRNG
                d = rng.read(1000)  # noqa

                # check available entropy
                with open('/proc/sys/kernel/random/entropy_avail', 'r') as ent:
                    ea = int(ent.read()) // 100
                    if ea not in res:
                        res[ea] = 0
                    res[ea] += 1

        skeys = sorted(res.keys())

        print('\nsystem entropy depletion stats:')
        for k in skeys:
            print('{}: {}'.format(k, res[k]))

        self.assertTrue(skeys[0] > 0)
Exemple #44
0
    def processSubscribe(self, session, subscribe):
        """
      Implements :func:`autobahn.wamp.interfaces.IBroker.processSubscribe`
      """
        assert (session in self._session_to_subscriptions)

        ## check topic URI
        ##
        if (not self._option_uri_strict and not  _URI_PAT_LOOSE_NON_EMPTY.match(subscribe.topic)) or \
           (    self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(subscribe.topic)):

            reply = message.Error(
                message.Subscribe.MESSAGE_TYPE, subscribe.request,
                ApplicationError.INVALID_URI, [
                    "subscribe for invalid topic URI '{}'".format(
                        subscribe.topic)
                ])

        else:

            if not subscribe.topic in self._topic_to_sessions:
                subscription = util.id()
                self._topic_to_sessions[subscribe.topic] = (subscription,
                                                            set())

            subscription, subscribers = self._topic_to_sessions[
                subscribe.topic]

            if not session in subscribers:
                subscribers.add(session)

            if not subscription in self._subscription_to_sessions:
                self._subscription_to_sessions[subscription] = (
                    subscribe.topic, set())

            _, subscribers = self._subscription_to_sessions[subscription]
            if not session in subscribers:
                subscribers.add(session)

            if not subscription in self._session_to_subscriptions[session]:
                self._session_to_subscriptions[session].add(subscription)

            reply = message.Subscribed(subscribe.request, subscription)

        session._transport.send(reply)
    def call(self, procedure, *args, **kwargs):
        """
        Implements :func:`autobahn.wamp.interfaces.ICaller.call`
        """
        if six.PY2 and type(procedure) == str:
            procedure = six.u(procedure)
        assert(isinstance(procedure, six.text_type))

        if not self._transport:
            raise exception.TransportLost()

        request_id = util.id()

        if 'options' in kwargs and isinstance(kwargs['options'], types.CallOptions):
            options = kwargs.pop('options')
            msg = message.Call(request_id, procedure, args=args, kwargs=kwargs, **options.message_attr())
        else:
            options = None
            msg = message.Call(request_id, procedure, args=args, kwargs=kwargs)

        # FIXME
        # def canceller(_d):
        #   cancel_msg = message.Cancel(request)
        #   self._transport.send(cancel_msg)
        # d = Deferred(canceller)

        on_reply = txaio.create_future()
        self._call_reqs[request_id] = CallRequest(request_id, on_reply, options)

        try:
            # Notes:
            #
            # * this might raise autobahn.wamp.exception.SerializationError
            #   when the user payload cannot be serialized
            # * we have to setup a PublishRequest() in _publish_reqs _before_
            #   calling transpor.send(), because a mock- or side-by-side transport
            #   will immediately lead on an incoming WAMP message in onMessage()
            #
            self._transport.send(msg)
        except Exception as e:
            if request_id in self._call_reqs:
                del self._call_reqs[request_id]
            raise e

        return on_reply
Exemple #46
0
    def session_add_testament(self, topic, args, kwargs, publish_options=None, scope=u"destroyed", details=None):
        """
        Add a testament to the current session.

        :param topic: The topic to publish the testament to.
        :type topic: str

        :param args: A list of arguments for the publish.
        :type args: list or tuple

        :param kwargs: A dict of keyword arguments for the publish.
        :type kwargs: dict

        :param publish_options: The publish options for the publish.
        :type publish_options: None or dict

        :param scope: The scope of the testament, either "detatched" or
            "destroyed".
        :type scope: str

        :returns: The publication ID.
        :rtype: int
        """
        session = self._router._session_id_to_session[details.caller]

        if scope not in [u"destroyed", u"detatched"]:
            raise ApplicationError(u"wamp.error.testament_error", u"scope must be destroyed or detatched")

        pub_id = util.id()

        # Get the publish options, remove some explicit keys
        publish_options = publish_options or {}
        publish_options.pop("acknowledge", None)
        publish_options.pop("exclude_me", None)

        pub = message.Publish(
            request=pub_id,
            topic=topic,
            args=args,
            kwargs=kwargs,
            **publish_options)

        session._testaments[scope].append(pub)

        return pub_id
Exemple #47
0
                def _get_retained_event():

                    if subscription.extra.retained_events:
                        retained_events = list(subscription.extra.retained_events)
                        retained_events.reverse()

                        for retained_event in retained_events:
                            authorized = False

                            if not retained_event.publish.exclude and not retained_event.publish.eligible:
                                authorized = True
                            elif session._session_id in retained_event.publish.eligible and session._session_id not in retained_event.publish.exclude:
                                authorized = True

                            if authorized:
                                publication = util.id()

                                if retained_event.publish.payload:
                                    msg = message.Event(subscription.id,
                                                        publication,
                                                        payload=retained_event.publish.payload,
                                                        enc_algo=retained_event.publish.enc_algo,
                                                        enc_key=retained_event.publish.enc_key,
                                                        enc_serializer=retained_event.publish.enc_serializer,
                                                        publisher=retained_event.publisher,
                                                        publisher_authid=retained_event.publisher_authid,
                                                        publisher_authrole=retained_event.publisher_authrole,
                                                        retained=True)
                                else:
                                    msg = message.Event(subscription.id,
                                                        publication,
                                                        args=retained_event.publish.args,
                                                        kwargs=retained_event.publish.kwargs,
                                                        publisher=retained_event.publisher,
                                                        publisher_authid=retained_event.publisher_authid,
                                                        publisher_authrole=retained_event.publisher_authrole,
                                                        retained=True)

                                msg.correlation_id = subscribe.correlation_id
                                msg.correlation_uri = subscribe.topic
                                msg.correlation_is_anchor = False
                                msg.correlation_is_last = False

                                return [msg]
                    return []
        def __init__(self, handler):
            self._log = False
            self._handler = handler
            self._serializer = serializer.JsonSerializer()
            self._registrations = {}
            self._invocations = {}
            #: str -> ID
            self._subscription_topics = {}

            self._handler.onOpen(self)

            self._my_session_id = util.id()

            roles = {u"broker": role.RoleBrokerFeatures(), u"dealer": role.RoleDealerFeatures()}

            msg = message.Welcome(self._my_session_id, roles)
            self._handler.onMessage(msg)
            self._fake_router_session = ApplicationSession()
Exemple #49
0
         def welcome(realm, authid = None, authrole = None, authmethod = None):
            self._session_id = util.id()
            self._goodbye_sent = False

            self._router = self._router_factory.get(realm)
            if not self._router:
               raise Exception("no such realm")

            self._authid = authid
            self._authrole = authrole
            self._authmethod = authmethod

            roles = self._router.attach(self)

            msg = message.Welcome(self._session_id, roles, authid = authid, authrole = authrole, authmethod = authmethod)
            self._transport.send(msg)

            self.onJoin(SessionDetails(self._realm, self._session_id, self._authid, self._authrole, self._authmethod))
Exemple #50
0
   def processRegister(self, session, register):
      """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processRegister`
      """
      assert(session in self._session_to_registrations)

      if not register.procedure in self._procs_to_regs:
         registration_id = util.id()
         self._procs_to_regs[register.procedure] = (registration_id, session)
         self._regs_to_procs[registration_id] = register.procedure

         self._session_to_registrations[session].add(registration_id)

         reply = message.Registered(register.request, registration_id)
      else:
         reply = message.Error(message.Register.MESSAGE_TYPE, register.request, 'wamp.error.procedure_already_exists')

      session._transport.send(reply)
Exemple #51
0
    def process_subscribe(self, packet):

        packet_watch = OrderedDict()
        d = Deferred()

        @d.addCallback
        def _(ign):
            self._mqtt.send_suback(
                packet.packet_identifier,
                [x["response"] for x in packet_watch.values()])
            del self._inflight_subscriptions[packet.packet_identifier]
            del self._subrequest_callbacks[packet.packet_identifier]

        self._subrequest_callbacks[packet.packet_identifier] = d
        self._inflight_subscriptions[packet.packet_identifier] = packet_watch

        for n, x in enumerate(packet.topic_requests):

            topic, match = _mqtt_topicfilter_to_wamp(x.topic_filter)

            self.log.info('process_subscribe -> topic={topic}, match={match}',
                          topic=topic,
                          match=match)

            request_id = util.id()

            msg = message.Subscribe(
                request=request_id,
                topic=topic,
                match=match,
                get_retained=True,
            )

            try:
                packet_watch[request_id] = {
                    "response": -1,
                    "topic": x.topic_filter
                }
                self._subrequest_to_mqtt_subrequest[
                    request_id] = packet.packet_identifier
                self._wamp_session.onMessage(msg)
            except:
                self.log.failure()
                packet_watch[request_id] = {"response": 128}
        def __init__(self, handler):
            self._log = False
            self._handler = handler
            self._serializer = serializer.JsonSerializer()
            self._registrations = {}
            self._invocations = {}
            #: str -> ID
            self._subscription_topics = {}

            self._handler.onOpen(self)

            self._my_session_id = util.id()

            roles = {'broker': role.RoleBrokerFeatures(), 'dealer': role.RoleDealerFeatures()}

            msg = message.Welcome(self._my_session_id, roles)
            self._handler.onMessage(msg)
            self._fake_router_session = ApplicationSession()

            self._transport_details = TransportDetails()
Exemple #53
0
   def _unregister(self, registration):
      """
      Called from :meth:`autobahn.wamp.protocol.Registration.unregister`
      """
      assert(isinstance(registration, Registration))
      assert registration.active
      assert(registration.id in self._registrations)

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      d = self._create_future()
      self._unregister_reqs[request] = (d, registration)

      msg = message.Unregister(request, registration.id)

      self._transport.send(msg)
      return d
Exemple #54
0
   def _unsubscribe(self, subscription):
      """
      Called from :meth:`autobahn.wamp.protocol.Subscription.unsubscribe`
      """
      assert(isinstance(subscription, Subscription))
      assert subscription.active
      assert(subscription.id in self._subscriptions)

      if not self._transport:
         raise exception.TransportLost()

      request = util.id()

      d = self._create_future()
      self._unsubscribe_reqs[request] = (d, subscription)

      msg = message.Unsubscribe(request, subscription.id)

      self._transport.send(msg)
      return d
    def call(self, procedure, *args, **kwargs):
        """
        Reimplemented to support calls with custom options
        """
        if six.PY2 and type(procedure) == str:
            procedure = six.u(procedure)
        assert(isinstance(procedure, six.text_type))
        if not self._transport:
            raise exception.TransportLost()

        request_id = util.id()
        on_reply = txaio.create_future()
        self._call_reqs[request_id] = CallRequest(request_id, procedure, on_reply, {})

        try:
            self._transport.send(AkCall(request_id, procedure, args, kwargs))
        except Exception as e:
            if request_id in self._call_reqs:
                del self._call_reqs[request_id]
            raise e
        return on_reply
Exemple #56
0
                def process_will(res):

                    payload_format, mapped_topic, options = yield self.factory.transform_mqtt(
                        packet.will_topic, packet.will_message)

                    request = util.id()

                    msg = message.Call(request=request,
                                       procedure=u"wamp.session.add_testament",
                                       args=[
                                           mapped_topic,
                                           options.get('args', None),
                                           options.get('kwargs', None), {
                                               'retain':
                                               bool(packet.flags.will_retain)
                                           }
                                       ])

                    self._wamp_session.onMessage(msg)

                    returnValue(res)
Exemple #57
0
            def on_authorize_success(authorized):
                if not authorized:

                    reply = message.Error(
                        message.Subscribe.MESSAGE_TYPE, subscribe.request,
                        ApplicationError.NOT_AUTHORIZED, [
                            "session is not authorized to subscribe to topic '{0}'"
                            .format(subscribe.topic)
                        ])

                else:

                    if not subscribe.topic in self._topic_to_sessions:
                        subscription = util.id()
                        self._topic_to_sessions[subscribe.topic] = (
                            subscription, set())

                    subscription, subscribers = self._topic_to_sessions[
                        subscribe.topic]

                    if not session in subscribers:
                        subscribers.add(session)

                    if not subscription in self._subscription_to_sessions:
                        self._subscription_to_sessions[subscription] = (
                            subscribe.topic, set())

                    _, subscribers = self._subscription_to_sessions[
                        subscription]
                    if not session in subscribers:
                        subscribers.add(session)

                    if not subscription in self._session_to_subscriptions[
                            session]:
                        self._session_to_subscriptions[session].add(
                            subscription)

                    reply = message.Subscribed(subscribe.request, subscription)

                session._transport.send(reply)
Exemple #58
0
    def process_subscribe(self, packet):

        packet_watch = OrderedDict()
        d = Deferred()

        @d.addCallback
        def _(ign):
            self._mqtt.send_suback(
                packet.packet_identifier,
                [x["response"] for x in packet_watch.values()])
            del self._inflight_subscriptions[packet.packet_identifier]
            del self._subrequest_callbacks[packet.packet_identifier]

        self._subrequest_callbacks[packet.packet_identifier] = d
        self._inflight_subscriptions[packet.packet_identifier] = packet_watch

        for n, x in enumerate(packet.topic_requests):
            # fixme
            match_type = u"exact"

            request_id = util.id()

            msg = message.Subscribe(
                request=request_id,
                topic=u".".join(tokenise_mqtt_topic(x.topic_filter)),
                match=match_type,
                get_retained=True,
            )

            try:
                packet_watch[request_id] = {
                    "response": -1,
                    "topic": x.topic_filter
                }
                self._subrequest_to_mqtt_subrequest[
                    request_id] = packet.packet_identifier
                self._wamp_session.onMessage(msg)
            except Exception:
                self.log.failure()
                packet_watch[request_id] = {"response": 128}
    def processRegister(self, session, register):
        """
      Implements :func:`autobahn.wamp.interfaces.IDealer.processRegister`
      """
        assert (session in self._session_to_registrations)

        ## check procedure URI
        ##
        if (not self._option_uri_strict and not  _URI_PAT_LOOSE_NON_EMPTY.match(register.procedure)) or \
           (    self._option_uri_strict and not _URI_PAT_STRICT_NON_EMPTY.match(register.procedure)):

            reply = message.Error(
                message.Register.MESSAGE_TYPE, register.request,
                ApplicationError.INVALID_URI, [
                    "register for invalid procedure URI '{}'".format(
                        register.procedure)
                ])

        else:

            if not register.procedure in self._procs_to_regs:
                registration_id = util.id()
                self._procs_to_regs[register.procedure] = (
                    registration_id, session, register.discloseCaller)
                self._regs_to_procs[registration_id] = register.procedure

                self._session_to_registrations[session].add(registration_id)

                reply = message.Registered(register.request, registration_id)
            else:
                reply = message.Error(
                    message.Register.MESSAGE_TYPE, register.request,
                    ApplicationError.PROCEDURE_ALREADY_EXISTS, [
                        "register for already registered procedure URI '{}'".
                        format(register.procedure)
                    ])

        session._transport.send(reply)