def serve(self): """ Start JSONRPC service for this GOsa service provider. """ # Get http service instance self.__http = PluginRegistry.getInstance("HTTPService") cr = PluginRegistry.getInstance("CommandRegistry") # Register ourselves app = JsonRpcApp(cr) self.__http.app.register( self.path, AuthCookieHandler( app, timeout=self.env.config.get("jsonrpc.cookie-lifetime", default=1800), cookie_name="GOsaRPC", secret=self.env.config.get("http.cookie_secret", default="TecloigJink4"), ), ) # Announce service self.__zeroconf = ZeroconfService( name="GOsa JSONRPC command service", port=self.__http.port, stype="_%s._tcp" % self.__http.scheme, text="path=%s\001service=gosa" % self.path, ) self.__zeroconf.publish() self.log.info("ready to process incoming requests")
def serve(self): """ Start AMQP service for this GOsa service provider. """ # Load AMQP and Command registry instances amqp = PluginRegistry.getInstance('AMQPHandler') self.__cr = PluginRegistry.getInstance('CommandRegistry') # Create a list of queues we need here queues = {} for dsc in self.__cr.commands.values(): queues[dsc['target']] = True # Finally create the queues for queue in queues: # Add round robin processor for queue self.__cmdWorker = AMQPWorker(self.env, connection=amqp.getConnection(), r_address='%s.command.%s; { create:always, node:{ type:queue, x-bindings:[ { exchange:"amq.direct", queue:"%s.command.%s" } ] } }' % (self.env.domain, queue, self.env.domain, queue), workers=self.env.config.get('amqp.command-worker', default=1), callback=self.commandReceived) # Add private processor for queue self.__cmdWorker = AMQPWorker(self.env, connection=amqp.getConnection(), r_address='%s.command.%s.%s; { create:always, delete:receiver, node:{ type:queue, x-bindings:[ { exchange:"amq.direct", queue:"%s.command.%s.%s" } ] } }' % (self.env.domain, queue, self.env.id, self.env.domain, queue, self.env.id), workers=self.env.config.get('amqp.command-worker', default=1), callback=self.commandReceived) # Announce service url = parseURL(self.env.config.get("amqp.url")) self.__zeroconf = ZeroconfService(name="GOsa AMQP command service", port=url['port'], stype="_%s._tcp" % url['scheme'], text="path=%s\001service=gosa" % url['path']) self.__zeroconf.publish() self.log.info("ready to process incoming requests")
class AMQPService(object): """ Class to serve all available queues and commands to the AMQP broker. It makes use of a couple of configuration flags provided by the gosa configurations file ``[amqp]`` section: ============== ============= Key Description ============== ============= url AMQP URL to connect to the broker id User name to connect with key Password to connect with command-worker Number of worker processes ============== ============= Example:: [amqp] url = amqps://amqp.intranet.gonicus.de:5671 id = node1 key = secret """ implements(IInterfaceHandler) _priority_ = 1 def __init__(self): env = Environment.getInstance() self.log = logging.getLogger(__name__) self.log.info("initializing AMQP service provider") self.env = env self.__cr = None self.__zeroconf = None self.__cmdWorker = None def serve(self): """ Start AMQP service for this GOsa service provider. """ # Load AMQP and Command registry instances amqp = PluginRegistry.getInstance('AMQPHandler') self.__cr = PluginRegistry.getInstance('CommandRegistry') # Create a list of queues we need here queues = {} for dsc in self.__cr.commands.values(): queues[dsc['target']] = True # Finally create the queues for queue in queues: # Add round robin processor for queue self.__cmdWorker = AMQPWorker(self.env, connection=amqp.getConnection(), r_address='%s.command.%s; { create:always, node:{ type:queue, x-bindings:[ { exchange:"amq.direct", queue:"%s.command.%s" } ] } }' % (self.env.domain, queue, self.env.domain, queue), workers=self.env.config.get('amqp.command-worker', default=1), callback=self.commandReceived) # Add private processor for queue self.__cmdWorker = AMQPWorker(self.env, connection=amqp.getConnection(), r_address='%s.command.%s.%s; { create:always, delete:receiver, node:{ type:queue, x-bindings:[ { exchange:"amq.direct", queue:"%s.command.%s.%s" } ] } }' % (self.env.domain, queue, self.env.id, self.env.domain, queue, self.env.id), workers=self.env.config.get('amqp.command-worker', default=1), callback=self.commandReceived) # Announce service url = parseURL(self.env.config.get("amqp.url")) self.__zeroconf = ZeroconfService(name="GOsa AMQP command service", port=url['port'], stype="_%s._tcp" % url['scheme'], text="path=%s\001service=gosa" % url['path']) self.__zeroconf.publish() self.log.info("ready to process incoming requests") def stop(self): """ Stop AMQP service for this GOsa service provider. """ self.__zeroconf.unpublish() def commandReceived(self, ssn, message): """ Process incoming commands, coming in with session and message information. ================= ========================== Parameter Description ================= ========================== ssn AMQP session object message Received AMQP message ================= ========================== Incoming messages are coming from an :class:`gosa.common.components.amqp_proxy.AMQPServiceProxy` which is providing a *reply to* queue as a return channel. The command result is written to that queue. """ # Check for id if not message.user_id: raise ValueError("incoming message without user_id") err = None res = None id_ = '' try: req = loads(message.content) except ServiceRequestNotTranslatable, e: err = str(e) req = {'id': id_} if err == None: try: id_ = req['id'] name = req['method'] args = req['params'] except KeyError: err = str(BadServiceRequest(message.content)) if not isinstance(args, list) and not isinstance(args, dict): raise ValueError("bad params %r: must be a list or dict" % args) # Extract source queue p = re.compile(r';.*$') queue = p.sub('', message._receiver.source) self.log.info("received call [%s/%s] for %s: %s(%s)" % (id_, queue, message.user_id, name, args)) # Don't process messages if the command registry thinks it's not ready if not self.__cr.processing.is_set(): self.log.warning("waiting for registry to get ready") if not self.__cr.processing.wait(5): self.log.error("releasing call [%s/%s] for %s: %s(%s) - timed out" % (id_, queue, message.user_id, name, args)) ssn.acknowledge(message, Disposition(RELEASED, set_redelivered=True)) return # Try to execute either with or without keyword arguments if err == None: try: if isinstance(args, dict): res = self.__cr.dispatch(message.user_id, queue, name, **args) else: res = self.__cr.dispatch(message.user_id, queue, name, *args) # Catch everything that might happen in the dispatch, pylint: disable=W0703 except Exception as e: text = traceback.format_exc() self.log.exception(text) err = str(e) exc_value = sys.exc_info()[1] # If message starts with [, it's a translateable message in # repr format if err.startswith("[") or err.startswith("("): if err.startswith("("): err = "[" + err[1:-1] + "]" err = loads(repr2json(err)) err = dict( name='JSONRPCError', code=100, message=str(exc_value), error=err) self.log.debug("returning call [%s]: %s / %s" % (id_, res, err)) response = dumps({"result": res, "id": id_, "error": err}) ssn.acknowledge(message) # Talk to client generated reply queue sender = ssn.sender(message.reply_to) # Get rid of it... sender.send(Message(response))
class JSONRPCService(object): """ This is the JSONRPC GOsa agent plugin which is registering an instance of :class:`gosa.agent.jsonrpc_service.JsonRpcApp` into the :class:`gosa.agent.httpd.HTTPService`. It is configured thru the ``[jsonrpc]`` section of your GOsa configuration: =============== ============ Key Description =============== ============ path Path to register the service in HTTP cookie-lifetime Seconds of authentication cookie lifetime =============== ============ Example:: [jsonrpc] path = /rpc cookie-lifetime = 3600 """ implements(IInterfaceHandler) _priority_ = 11 __proxy = {} def __init__(self): env = Environment.getInstance() self.env = env self.log = logging.getLogger(__name__) self.log.info("initializing JSON RPC service provider") self.path = self.env.config.get("jsonrpc.path", default="/rpc") self.__zeroconf = None self.__http = None def serve(self): """ Start JSONRPC service for this GOsa service provider. """ # Get http service instance self.__http = PluginRegistry.getInstance("HTTPService") cr = PluginRegistry.getInstance("CommandRegistry") # Register ourselves app = JsonRpcApp(cr) self.__http.app.register( self.path, AuthCookieHandler( app, timeout=self.env.config.get("jsonrpc.cookie-lifetime", default=1800), cookie_name="GOsaRPC", secret=self.env.config.get("http.cookie_secret", default="TecloigJink4"), ), ) # Announce service self.__zeroconf = ZeroconfService( name="GOsa JSONRPC command service", port=self.__http.port, stype="_%s._tcp" % self.__http.scheme, text="path=%s\001service=gosa" % self.path, ) self.__zeroconf.publish() self.log.info("ready to process incoming requests") def stop(self): """ Stop serving the JSONRPC service for this GOsa service provider. """ self.log.debug("shutting down JSON RPC service provider") self.__http.app.unregister(self.path)