Example #1
0
    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()
Example #2
0
class AMQPClientHandler(AMQPHandler):
    """
    This class handles the AMQP connection, incoming and outgoing connections
    and allows event callback registration.
    """
    _conn = None
    __capabilities = {}
    __peers = {}
    _eventProvider = None
    __proxy = None
    url = None
    joined = False

    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 get_proxy(self):
        return self.__proxy

    def sendEvent(self, data):
        """ Override original sendEvent. Use proxy instead. """
        if not isinstance(data, str):
            data = etree.tostring(data)

        return self.__proxy.sendEvent(data)

    def start(self):
        """
        Enable AMQP queueing. This method puts up the event processor and
        sets it to "active".
        """
        self.log.debug("enabling AMQP queueing")

        # Evaluate username
        user = self.env.uuid

        # Create initial broker connection
        url = "%s:%s" % (self.url['host'], self.url['port'])
        self._conn = Connection.establish(
            url,
            reconnect=self.reconnect,
            username=user,
            password=self.env.config.get("amqp.key"),
            transport=self.url['transport'],
            reconnect_interval=self.reconnect_interval,
            reconnect_limit=self.reconnect_limit)

        # Do automatic broker failover if requested
        if self.env.config.get('amqp.failover', default=False):
            auto_fetch_reconnect_urls(self._conn)

        # Create event provider
        try:
            self._eventProvider = EventProvider(self.env, self._conn)
        except NotFound as e:
            self.env.log.critical("queue has gone: %s" % str(e))
            self.env.requestRestart()

    def close(self):
        self.log.debug("shutting down AMQP client handler")
        if self._conn:
            self._conn.close()

    def __del__(self):
        self.close()
Example #3
0
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)
Example #4
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from clacks.common.components import AMQPServiceProxy

# Create connection to service
proxy = AMQPServiceProxy('amqps://*****:*****@amqp.intranet.gonicus.de/org.clacks')

# List methods
print proxy.getMethods()

# Create samba password hash
print proxy.mksmbhash("secret")
Example #5
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from clacks.common.components import AMQPServiceProxy
from clacks.common.event import EventMaker
from lxml import etree

# Connect to AMQP bus
proxy = AMQPServiceProxy('amqp://*****:*****@localhost/org.clacks')

# Example of building event without direct strings...
e = EventMaker()
status = e.Event(
    e.PhoneStatus(
        e.CallerId("012345"),
        e.ReceiverId("12343424"),
        e.Status("busy")
    )
)

# ... which in turn needs to be converted to a string
status = etree.tostring(status, pretty_print=True)

# Send it
proxy.sendEvent(status)