def __init__(self): """ Construct a new AMQPClientHandler instance based on the configuration stored in the environment. @type env: Environment @param env: L{Environment} object """ env = Environment.getInstance() self.log = logging.getLogger(__name__) self.log.debug("initializing AMQP client handler") self.env = env # Load configuration self.url = parseURL(self.env.config.get('amqp.url', None)) self.domain = self.env.config.get('ampq.domain', default="org.clacks") self.dns_domain = socket.getfqdn().split('.', 1)[1] # Use zeroconf if there's no URL if self.url: o = urlparse(self.url['source']) else: url = ZeroconfClient.discover(['_amqps._tcp', '_amqp._tcp'], domain=self.domain)[0] o = urlparse(url) # pylint: disable=E1101 self.domain = o.path[1::] # Configure system user = self.env.uuid key = self.env.config.get('amqp.key') if key: # pylint: disable=E1101 self.url = parseURL( '%s://%s:%s@%s%s' % (o.scheme, user, key, o.netloc, o.path)) else: self.url = parseURL(url) # Make proxy connection self.log.info( "using service '%s/%s'" % (self.url['host'], self.url['path'])) self.__proxy = AMQPServiceProxy(self.url['source']) # Set params and go for it self.reconnect = self.env.config.get('amqp.reconnect', True) self.reconnect_interval = self.env.config.get( 'amqp.reconnect-interval', 3) self.reconnect_limit = self.env.config.get('amqp.reconnect-limit', 0) # Check if credentials are supplied if not self.env.config.get("amqp.key"): raise Exception("no key supplied - please join the client") # Start connection self.start()
def main(): env = Environment.getInstance() config = env.config # Load configuration path = config.get('backend-monitor.audit-log', default='/var/lib/clacks/ldap-audit.log') modifier = config.get('backend-monitor.modifier') user = config.get('core.id') password = config.get('amqp.key') url = parseURL(makeAuthURL(config.get('amqp.url'), user, password)) # Connect to Clacks BUS proxy = AMQPServiceProxy(url['source'] + "/" + env.domain) # Main loop while True: sleep(1) # Wait for file to pop up if not os.path.exists(path): continue # Wait for file to be file if not os.path.isfile(path): continue # Check if it is effectively readable try: with open(path) as f: pass except IOError as e: continue # Listen for changes monitor(path, modifier, proxy)
def serve(self): """ Start AMQP service for this clacks 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=int(self.env.config.get('amqp.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=int(self.env.config.get('amqp.worker', default=1)), callback=self.commandReceived) # Announce service if self.env.config.get("amqp.announce", default="True").lower() == "true": url = parseURL(self.env.config.get("amqp.url")) self.__zeroconf = ZeroconfService(name="Clacks RPC service", port=url['port'], stype="_%s._tcp" % url['scheme'], text=dict_to_txt_array({'path': self.env.domain, 'service': 'clacks'})) self.__zeroconf.publish() self.log.info("ready to process incoming requests")
def __init__(self, url, domain="org.clacks", xquery=".", callback=None): # Build connection url = parseURL(url) _url = "%s:%s" % (url['host'], url['port']) self.__conn = Connection.establish(_url, reconnect=True, username=url['user'], password=url['password'], transport=url['transport'], reconnect_interval=3, reconnect_limit=0) # Do automatic broker failover if requested #TODO: configure reconnect #auto_fetch_reconnect_urls(self.__conn) # Assemble subscription query queue = 'event-listener-%s' % uuid4() address = """%s; { create: always, delete:always, node: { durable: False, x-declare: { exclusive: True, auto-delete: True } }, link: { x-bindings: [ { exchange: '%s', queue: %s, key: event, arguments: { xquery: %r} } ] } }""" % (queue, domain, queue, xquery) # Add processor for core.event queue self.__callback = callback self.__eventWorker = AMQPStandaloneWorker( self.__conn, r_address=address, workers=1, callback=self.__eventProcessor)
def __init__(self): env = Environment.getInstance() self.log = logging.getLogger(__name__) self.log.debug("initializing AMQP handler") self.env = env self.config = env.config # Initialize parser schema_root = etree.XML(PluginRegistry.getEventSchema()) schema = etree.XMLSchema(schema_root) self._parser = objectify.makeparser(schema=schema) # Evaluate username user = self.env.uuid password = self.config.get("amqp.key") # Load configuration self.url = parseURL(makeAuthURL(self.config.get('amqp.url'), user, password)) self.reconnect = self.config.get('amqp.reconnect', True) self.reconnect_interval = self.config.get('amqp.reconnect_interval', 3) self.reconnect_limit = self.config.get('amqp.reconnect_limit', 0) # Go for it self.start()
def __init__(self, serviceURL, serviceAddress=None, serviceName=None, conn=None, worker=None, methods=None): self.__URL = url = parseURL(serviceURL) self.__serviceURL = serviceURL self.__serviceName = serviceName self.__serviceAddress = serviceAddress self.__worker = worker self.__domain = url['path'] self.__methods = methods # Prepare AMQP connection if not already there if not conn: _url = "%s:%s" % (url['host'], url['port']) conn = Connection.establish(_url, reconnect=True, username=url['user'], password=url['password'], transport=url['transport'], reconnect_interval=3, reconnect_limit=0) #TODO: configure reconnect #auto_fetch_reconnect_urls(conn) # Prefill __serviceAddress correctly if domain is given if self.__domain: self.__serviceAddress = '%s.command.core' % self.__domain if not self.__serviceAddress: raise AMQPException("no serviceAddress or domain specified") if not self.__worker: self.__worker = {self.__serviceAddress: {}} # Pre instanciate core sessions for i in range(0, WORKERS): ssn = conn.session(str(uuid4())) self.__worker[self.__serviceAddress][i] = { 'ssn': ssn, 'sender': ssn.sender(self.__serviceAddress), 'receiver': ssn.receiver('reply-%s; {create:always, delete:always, node: { type: queue, durable: False, x-declare: { exclusive: False, auto-delete: True } }}' % ssn.name), 'locked': False} # Store connection self.__conn = conn self.__ssn = None self.__sender = None self.__receiver = None self.__sess = None # Retrieve methods if not self.__methods: self.__serviceName = "getMethods" self.__methods = self.__call__() self.__serviceName = None # If we've no direct queue, we need to push to different queues if self.__domain: queues = set([ x['target'] for x in self.__methods.itervalues() if x['target'] != 'core' ]) # Pre instanciate queue sessions for queue in queues: for i in range(0, WORKERS): ssn = conn.session(str(uuid4())) self.__worker[queue] = {} self.__worker[queue][i] = { 'ssn': ssn, 'sender': ssn.sender("%s.command.%s" % (self.__domain, queue)), 'receiver': ssn.receiver('reply-%s; {create:always, delete:always, node: { type: queue, durable: False, x-declare: { exclusive: False, auto-delete: True } }}' % ssn.name), 'locked': False}
def connect(service_uri='', username='', password=''): """ Creates a service proxy object from the arguments. """ # Clean arguments username = username.strip() password = password.strip() service_uri = service_uri.strip() domain = socket.getfqdn().split('.', 1)[1] if len(service_uri) <= 0: print(_("Searching service provider...")) try: service_uri = ZeroconfClient.discover(['_amqps._tcp', '_amqp._tcp', '_https._tcp', '_http._tcp'], domain=domain)[0] except DBusException as e: print(_("DBUS error: %s") % str(e)) sys.exit(1) except Exception as e: print(e.__dict__) # Test if one argument is still needed. if len(service_uri) <= 0: tmp = service_uri service_uri = raw_input('Service URI: [%s]' % service_uri).strip() if len(service_uri) <= 0: service_uri = tmp # Chek if URL is parsable url = parseURL(service_uri) # If we have still no service host, quit, because the connect will fail # pylint: disable-msg=E1101 if not url: print(_("Need at least a service URI!")) sys.exit(1) # TRANSLATOR: Conected to URL, i.e. https://amqp.local:8080/rpc print(_("Connected to %s://%s:%s/%s") % (url['scheme'], url['host'], url['port'], url['path'])) # Check weather to use method parameters or the URI elements. # If URI username is set and the method username is not set if url['user']: username = url['user'] # If URI password is set and the username is set and the method password is not set if url['password']: password = url['password'] # If we have still no credentials query for them if len(username) <= 0: # TRANSLATOR: This is a prompt - Username [joe]: username = raw_input(_("Username") + " [%s]: " % getpass.getuser()).strip() if len(username) <= 0: username = getpass.getuser() if len(password) <= 0: # TRANSLATOR: This is a prompt - Password: password = getpass.getpass(_("Password") + ': ') # Create service proxy if url['scheme'][0:4] == "amqp": connection = '%s://%s:%s@%s:%s/%s' % ( url['scheme'], username, password, url['host'], url['port'], url['path']) proxy = AMQPServiceProxy(connection) elif url['scheme'][0:4] == "http": connection = '%s://%s:%s/%s' % ( url['scheme'], url['host'], url['port'], url['path']) proxy = JSONServiceProxy(connection) else: print(_("The selected protocol is not supported!")) sys.exit(1) # Try to log in try: if not proxy.login(username, password): print(_("Login of user '%s' failed") % username) sys.exit(1) except Exception, e: print(e) sys.exit(1)