def shutdown(self, restart=False, details=None): """ Stop this node. """ log.msg("Shutting down node ..") shutdown_topic = 'crossbar.node.{}.on_shutdown'.format(self._node_id) shutdown_info = {} yield self.publish(shutdown_topic, shutdown_info, options=PublishOptions(acknowledge=True)) yield sleep(3) self._node._reactor.stop()
def publish_ready(self): # signal that this worker is ready for setup. the actual setup procedure # will either be sequenced from the local node configuration file or remotely # from a management service yield self.publish( u'{}.on_worker_ready'.format(self._uri_prefix), { u'type': self.WORKER_TYPE, u'id': self.config.extra.worker, u'pid': os.getpid(), }, options=PublishOptions(acknowledge=True) ) self.log.debug("Worker '{worker}' running as PID {pid}", worker=self.config.extra.worker, pid=os.getpid())
def onJoin(self, details): print("session attached {}".format(details)) yield self.subscribe(self.on_event, self.topic) print("Subscribed to '{}'".format(self.topic)) # if you send args, then all args (and kwargs) in the publish # are encoded into a JSON body as "the" MQTT message. Here we # also ask WAMP to send our message back to us. yield self.publish( u"mqtt.test_topic", b64encode("some data via WAMP"), mqtt_message=True, mqtt_qos=1, options=PublishOptions(exclude_me=False), )
async def on_message(message): payload = message.to_dict() print(payload) try: self.publish( "discordembedorg.github.bridge.server.{server_id}.channel.{channel_id}.message" .format(server_id=message.guild.id, channel_id=message.channel.id), payload, options=PublishOptions(retain=True)) except autobahn.wamp.exception.TransportLost as error: print("---ERROR---") print(error) print(message) print(payload) print("-----------")
def _process(self, request, event): # The topic we're going to send to topic = self._options["topic"] message = {} message[u"headers"] = { native_string(x): [native_string(z) for z in y] for x, y in request.requestHeaders.getAllRawHeaders() } message[u"body"] = event publish_options = PublishOptions(acknowledge=True) def _succ(result): response_text = self._options.get("success_response", u"OK").encode('utf8') return self._complete_request( request, 202, response_text, reason="Successfully sent webhook from {ip} to {topic}", topic=topic, ip=request.getClientIP(), log_category="AR201", ) def _err(result): response_text = self._options.get("error_response", u"NOT OK").encode('utf8') return self._fail_request( request, 500, "Unable to send webhook from {ip} to {topic}", topic=topic, ip=request.getClientIP(), body=response_text, log_failure=result, log_category="AR457", ) d = self._session.publish(topic, json.loads(json.dumps(message)), options=publish_options) d.addCallback(_succ) d.addErrback(_err) return d
def _stop_native_worker(self, worker_id, kill, details=None): if worker_id not in self._workers or not isinstance( self._workers[worker_id], NativeWorkerProcess): emsg = "Could not stop native worker: no native worker with ID '{}' currently running".format( worker_id) raise ApplicationError(u'crossbar.error.worker_not_running', emsg) worker = self._workers[worker_id] if worker.status != 'started': emsg = "Could not stop native worker: worker with ID '{}' is not in status 'started', but status: '{}')".format( worker_id, worker.status) raise ApplicationError(u'crossbar.error.worker_not_running', emsg) stop_info = { u'id': worker.id, u'type': worker.TYPE, u'kill': kill, u'who': details.caller if details else None, u'when': utcnow(), } # publish management API event # yield self.publish(u'{}.on_stop_requested'.format(self._uri_prefix), stop_info, options=PublishOptions( exclude=details.caller if details else None, acknowledge=True)) # send SIGKILL or SIGTERM to worker # if kill: self.log.info("Killing {worker_type} worker with ID '{worker_id}'", worker_type=worker.TYPE, worker_id=worker_id) self._workers[worker_id].proto.transport.signalProcess("KILL") else: self.log.info( "Stopping {worker_type} worker with ID '{worker_id}'", worker_type=worker.TYPE, worker_id=worker_id) self._workers[worker_id].factory.stopFactory() self._workers[worker_id].proto.transport.signalProcess('TERM') returnValue(stop_info)
def _process(self, request, event): if 'topic' not in event: return self._deny_request( request, 400, "invalid request event - missing 'topic' in HTTP/POST body", log_category="AR455") topic = event.pop('topic') args = event.pop('args', []) kwargs = event.pop('kwargs', {}) options = event.pop('options', {}) publish_options = PublishOptions(acknowledge=True, exclude=options.get('exclude', None), eligible=options.get( 'eligible', None)) kwargs['options'] = publish_options # http://twistedmatrix.com/documents/current/web/howto/web-in-60/asynchronous-deferred.html d = self._session.publish(topic, *args, **kwargs) def on_publish_ok(pub): res = {'id': pub.id} body = json.dumps(res, separators=(',', ':'), ensure_ascii=False).encode('utf8') request.setHeader(b'content-type', b'application/json; charset=UTF-8') request.setHeader( b'cache-control', b'no-store, no-cache, must-revalidate, max-age=0') self._complete_request(request, 202, body, log_category="AR200") def on_publish_error(err): return self._fail_request( request, 400, "PublisherResource failed with error {e}", e=err.value, log_category="AR456") return d.addCallbacks(on_publish_ok, on_publish_error)
def mapper(self, state): result = None jsonState = json.loads(state) phase = jsonState['phase'] print("Inside mapper for phase: {}".format(phase)) if phase in self.phaseToMethod: result = self.phaseToMethod[phase](state) uri = self.endpoints['RESPONSE'].format(self.gameId, self.sessionId) self.publish(uri, phase, result, options=PublishOptions(acknowledge=True, retain=True)) if phase == "END_GAME" and isinstance(jsonState['phase_payload'], dict): #The last game has completed self.teardownAgent()
def _test_pubsub(self, delay=None): options = PublishOptions(acknowledge=True, exclude_me=False) counter = 1 while counter <= self.NUM: msg = 'Counter is at {}'.format(counter) topic = 'com.myapp.hello' pub = yield self.publish(topic, msg, options=options) self.log.info('event published: {pub}', pub=pub) topic = 'com.myapp.encrypted.hello' pub = yield self.publish(topic, msg, options=options) self.log.info('event published: {pub}', pub=pub) if delay: yield sleep(1) counter += 1
def onJoin(self, details): self.log.info('session joined: {details}', details=details) def on_event(pid, seq, ran, details=None): self.log.info( 'event received on topic {topic}: pid={pid}, seq={seq}, ran={ran}, details={details}\n', topic=details.topic, pid=pid, seq=seq, ran=binascii.b2a_hex(ran), details=details) reg = yield self.subscribe(on_event, SUBTOPIC, options=SubscribeOptions(match=SUBMATCH, details=True)) self.log.info( 'subscribed to topic {topic} (match={match}): registration={reg}', topic=SUBTOPIC, match=SUBMATCH, reg=reg) pid = os.getpid() seq = 1 while True: self.log.info('-' * 60) pubs = [] for PUBTOPIC in [PUBTOPIC1, PUBTOPIC2, PUBTOPIC3, PUBTOPIC4]: topic = PUBTOPIC.format(seq) pub = self.publish( topic, pid, seq, os.urandom(8), options=PublishOptions(acknowledge=True, exclude_me=False), ) self.log.info( 'event published to {topic}: publication={pub}\n', topic=topic, pub=pub) pubs.append(pub) seq += 1 yield txaio.gather(pubs) yield sleep(1)
def onJoin(self, details): def on_event(i): print("Got event: {}".format(i)) yield from self.subscribe(on_event, u'com.myapp.topic1') counter = 0 while True: publication = yield from self.publish(u'com.myapp.topic1', counter, options=PublishOptions( acknowledge=True, exclude_me=False)) print("Event published with publication ID {}".format( publication.id)) counter += 1 yield from asyncio.sleep(1)
def _test_pubsub(self, delay=None): options = PublishOptions(acknowledge=True, exclude_me=False, disclose_me=True) counter = 1 while counter <= self.NUM: msg = u"Counter is at {}".format(counter) pub = yield self.publish(u'com.myapp.hello', msg, options=options) print("published: {}".format(pub)) pub = yield self.publish(u'com.myapp.encrypted.hello', msg, options=options) print("published: {}".format(pub)) if delay: yield sleep(1) counter += 1
def stop_router_transport(self, transport_id, details=None): """ Stop a transport currently running in this router worker. :param transport_id: The ID of the transport to stop. :type transport_id: str :param details: Call details. :type details: :class:`autobahn.wamp.types.CallDetails` """ self.log.debug("{name}.stop_router_transport", name=self.__class__.__name__) if transport_id not in self.transports or self.transports[ transport_id].state != self.personality.RouterTransport.STATE_STARTED: emsg = "Cannot stop transport: no transport with ID '{}' or transport is already stopping".format( transport_id) self.log.error(emsg) raise ApplicationError(u'crossbar.error.not_running', emsg) router_transport = self.transports[transport_id] self.log.debug("Stopping transport with ID '{transport_id}'", transport_id=transport_id) caller = details.caller if details else None event = {u'id': transport_id} topic = u'{}.on_router_transport_stopping'.format(self._uri_prefix) self.publish(topic, event, options=PublishOptions(exclude=caller)) # stop listening .. d = router_transport.stop() def ok(_): del self.transports[transport_id] topic = u'{}.on_router_transport_stopped'.format(self._uri_prefix) self.publish(topic, event, options=PublishOptions(exclude=caller)) def fail(err): emsg = "Cannot stop listening on transport endpoint: {log_failure}" self.log.error(emsg, log_failure=err) raise ApplicationError(u"crossbar.error.cannot_stop", emsg) d.addCallbacks(ok, fail) return d
async def on_event(key_id, enc_ser, ciphertext, details=None): try: payload = await buyer.unwrap(key_id, enc_ser, ciphertext) print(payload) key_id, enc_ser, ciphertext = await seller.wrap(api_id, topic_seller, payload) pub = await session.publish(topic_seller, key_id, enc_ser, ciphertext, options=PublishOptions(acknowledge=True)) print('Published event {}: {}'.format(pub.id, payload)) except Exception as e: print(e) session.leave() else: print('Received event {}:'.format(details.publication), payload)
def onJoin(self, details): self.log.info('XBRProducer connected: {details}', details=details) self._xbr_prefix = 'xbr.producer' self._xbr_keyring = XBRRing(self) yield self.register(self._xbr_keyring, self._xbr_prefix, options=RegisterOptions(details_arg='details')) enc_key = self._xbr_keyring.issue_key(10) #price_quote = yield self.call('xbr.maker.quote', 'key123') #self.log.info('GOT PRICE QUOTE!!! {price_quote}', price_quote=price_quote) counter = 0 while True: # event payload to publish obj = { 'cnt_sq': counter * counter, 'msg': 'Hello, world! This is my message {}'.format(counter) } # serialize to bytes data = json.dumps(obj, ensure_ascii=False).encode('utf8') # encrypt event payload with current enc_key enc_keyid, enc_data = enc_key.encrypt(data) # publish encrypted payload yield self.publish('com.example.oncounter', enc_keyid, enc_data, options=PublishOptions(acknowledge=True)) self.log.info('counter {counter}', counter=counter) # rotate key every 100 publications counter += 1 if counter % 100 == 0: yield enc_key.rotate() self.log.info('key rotated: {seq}', seq=enc_key.seq) # publish every 200ms yield sleep(.2)
def start_router_realm_interface(self, realm_id, interface_id, interface_config, details=None): if realm_id not in self.realms: raise ApplicationError(u"crossbar.error.no_such_object", "No realm with ID '{}'".format(realm_id)) if interface_id in self.realms[realm_id].interfaces: raise ApplicationError( u"crossbar.error.already_exists", "An interface with ID '{}' already exists in realm with ID '{}'".format(interface_id, realm_id)) self.realms[realm_id].interfaces[interface_id] = RouterRealmInterface(interface_id, interface_config) realm = self.realms[realm_id].config['name'] self._router_factory.add_interface(realm, interface_config) topic = u'{}.on_router_realm_interface_started'.format(self._uri_prefix) event = {u'id': interface_id} caller = details.caller if details else None self.publish(topic, event, options=PublishOptions(exclude=caller))
def onJoin(self, details): print("session attached") counter = 0 topics = ['com.myapp.topic1', 'com.foobar.topic2'] while True: for topic in topics: try: yield self.publish( topic, counter, options=PublishOptions(acknowledge=True)) print("Event published to {}".format(topic)) except Exception as e: print("Publication to {} failed: {}".format(topic, e)) counter += 1 yield sleep(1)
async def onJoin(self, details): print('Client session joined: {}'.format(details)) topic = 'com.example.topic1' def on_event(i): print('Event received: {}'.format(i)) await self.subscribe(on_event, topic) for i in range(5): self.publish(topic, i, options=PublishOptions(acknowledge=True, exclude_me=False)) await sleep(1) self.leave()
def onJoin(self, details): self.log.info('session joined: {}'.format(details)) yield self.register(add2, 'com.example.add2') for i in range(10): res = yield self.call('com.example.add2', 23, i * self._countdown) self.log.info('result: {}'.format(res)) i = 0 while True: msg = 'Hello, world! [{}]'.format(i) yield self.publish('com.example.topic1', msg, options=PublishOptions(acknowledge=True)) self.log.info(msg) yield sleep(1) i += 1
def _(session, details): print("joined: {}".format(details)) topic_name = u"demo.foo" pid = os.getpid() counter = 0 while session.is_connected(): print("pid {} publish {} to '{}'".format(pid, counter, topic_name)) data = os.urandom(10) session.publish( topic_name, pid, counter, foo='0x' + binascii.b2a_hex(data).decode(), baz=data, options=PublishOptions(exclude_me=False), ) counter += 1 yield sleep(1)
def on_management_event(*args, **kwargs): if not self._manager.is_attached(): self.log.warn("Can't foward management event: CDC session not attached") return details = kwargs.pop('details') # a node local event such as 'crossbar.node.on_ready' is mogrified to 'local.crossbar.node.on_ready' # (one reason is that URIs such as 'wamp.*' and 'crossbar.*' are restricted to trusted sessions, and # the management bridge is connecting over network to the uplink CDC and hence can't be trusted) # topic = u"local.{}".format(details.topic) try: yield self._manager.publish(topic, *args, options=PublishOptions(acknowledge=True), **kwargs) except Exception as e: self.log.error("Failed to forward event on topic '{topic}': {error}", topic=topic, error=e) else: self.log.debug("Forwarded management event on topic '{topic}'", topic=topic)
def restart_component(self, component_id, reload_modules=False, details=None): """ Restart a component currently running within this container using the same configuration that was used when first starting the component. :param component_id: The ID of the component to restart. :type component_id: str :param reload_modules: If `True`, enforce reloading of modules (user code) that were modified (see: TrackingModuleReloader). :type reload_modules: bool :param details: Caller details. :type details: instance of :class:`autobahn.wamp.types.CallDetails` :returns dict -- A dict with combined info from component stopping/starting. """ if component_id not in self.components: raise ApplicationError(u'crossbar.error.no_such_object', 'no component with ID {} running in this container'.format(component_id)) component = self.components[component_id] stopped = yield self.stop_container_component(component_id, details=details) started = yield self.start_component(component_id, component.config, reload_modules=reload_modules, details=details) del stopped[u'caller'] del started[u'caller'] restarted = { u'stopped': stopped, u'started': started, u'caller': { u'session': details.caller, u'authid': details.caller_authid, u'authrole': details.caller_authrole, } } self.publish(u'{}.on_component_restarted'.format(self._uri_prefix), restarted, options=PublishOptions(exclude=details.caller)) returnValue(restarted)
def _stop_native_worker(self, wtype, id, kill, details=None): assert(wtype in ['router', 'container', 'websocket-testee']) if id not in self._workers or self._workers[id].TYPE != wtype: emsg = "Could not stop native worker: no {} worker with ID '{}' currently running".format(wtype, id) raise ApplicationError(u'crossbar.error.worker_not_running', emsg) worker = self._workers[id] if worker.status != 'started': emsg = "Could not stop native worker: worker with ID '{}' is not in status 'started', but status: '{}')".format(id, worker.status) raise ApplicationError(u'crossbar.error.worker_not_running', emsg) stop_info = { u'id': worker.id, u'type': wtype, u'kill': kill, u'who': details.caller if details else None, u'when': utcnow(), } # publish management API event # yield self.publish( 'crossbar.node.{}.worker.{}.on_stop_requested'.format(self._node_id, worker.id), stop_info, options=PublishOptions(exclude=details.caller if details else None, acknowledge=True) ) # send SIGKILL or SIGTERM to worker # if kill: self.log.info("Killing {wtype} worker with ID '{id}'", wtype=wtype, id=id) self._workers[id].proto.transport.signalProcess("KILL") else: self.log.info("Stopping {wtype} worker with ID '{id}'", wtype=wtype, id=id) self._workers[id].factory.stopFactory() self._workers[id].proto.transport.signalProcess('TERM') returnValue(stop_info)
def publish_started(session, start_details): """ when our component starts, we publish .on_component_start """ # hook up handlers for "session is ready" session.on('ready', publish_ready) # publish .on_component_start self.log.info( "started component: {session} id={session_id}", session=class_name(session), session_id=session._session_id, ) topic = self._uri_prefix + '.on_component_start' event = {'id': id} caller = details.caller if details else None self.publish(topic, event, options=PublishOptions(exclude=caller)) return event
def on_ready_success(id): log.msg("{} with ID '{}' and PID {} started".format( worker_logname, worker.id, worker.pid)) worker.status = 'started' worker.started = datetime.utcnow() started_info = { 'id': worker.id, 'status': worker.status, 'started': utcstr(worker.started), 'who': worker.who } self.publish(started_topic, started_info, options=PublishOptions(exclude=[details.caller])) return started_info
def on_ready_success(worker_id): self.log.debug( '{worker_type} worker "{worker_id}" process {pid} started', worker_type=worker_logname, worker_id=worker.id, pid=worker.pid) self._node._reactor.addSystemEventTrigger( 'before', 'shutdown', self._cleanup_worker, self._node._reactor, worker, ) worker.on_worker_started() started_info = { u'id': worker.id, u'status': worker.status, u'started': utcstr(worker.started), u'who': worker.who, u'pid': worker.pid, u'startup_time': (worker.started - worker.created).total_seconds() if worker.started else None } # FIXME: make start of stats printer dependent on log level .. if False: worker.log_stats(5.) self.publish(started_topic, started_info, options=PublishOptions(exclude=details.caller)) return started_info
def onJoin(self, details): self.log.info('backend joined: {details}', details=details) def on_event(msg, details=None): self.log.info('received event on {topic}: {msg}', topic=details.topic, msg=msg) self.log.info('details: {details}', details=details) sub = yield self.subscribe(on_event, '', SubscribeOptions(match='prefix', details=True)) self.log.info('backend subscribed: {sub}', sub=sub) counter = 0 while True: msg = 'counter is at {}'.format(counter) pub = yield self.publish('topic1', msg, options=PublishOptions(exclude_me=False, acknowledge=True)) self.log.info('event published: {pub}', pub=pub) counter += 1 yield sleep(1)
def onJoin(self, details): print("session attached") def on_event(i): print("Got event: {}".format(i)) yield self.subscribe(on_event, u'com.myapp.topic1') counter = 0 while True: print("publish: com.myapp.topic1", counter) pub_options = PublishOptions(acknowledge=True, exclude_me=False) publication = yield self.publish( u'com.myapp.topic1', counter, options=pub_options, ) print("Published with publication ID {}".format(publication.id)) counter += 1 yield sleep(1)
def stop_container_component(self, id, details=None): """ Stop a component currently running within this container. :param id: The ID of the component to stop. :type id: int :param details: Caller details. :type details: instance of :class:`autobahn.wamp.types.CallDetails` :returns dict -- A dict with component start information. """ if id not in self.components: raise ApplicationError( 'crossbar.error.no_such_object', 'no component with ID {} running in this container'.format(id)) now = datetime.utcnow() # FIXME: should we session.leave() first and only close the transport then? # This gives the app component a better hook to do any cleanup. self.components[id].proto.close() c = self.components[id] event = { 'id': id, 'started': utcstr(c.started), 'stopped': utcstr(now), 'uptime': (now - c.started).total_seconds() } # publish event "on_component_stop" to all but the caller # topic = 'crossbar.node.{}.worker.{}.container.on_component_stop'.format( self.config.extra.node, self.config.extra.worker) self.publish(topic, event, options=PublishOptions(exclude=[details.caller])) del self.components[id] return event
def onJoin(self, details): print("session attached") def on_event(i): print("Got event: {}".format(i)) yield self.subscribe(on_event, 'com.myapp.topic1') counter = 0 while True: print(".") publication = yield self.publish('com.myapp.topic1', counter, options=PublishOptions( acknowledge=True, discloseMe=True, excludeMe=False)) print("Event published with publication ID {}".format( publication.id)) counter += 1 yield sleep(1)