Example #1
0
	def get_client(self, io_loop=None, callback=None):
		credentials = pika.PlainCredentials('guest', 'guest')
		# This will connect immediately.
		parameters = pika.ConnectionParameters(host='localhost',
			port=self.port,
			virtual_host='/',
			credentials=credentials)
		self.client = TornadoConnection(parameters, on_open_callback=callback, io_loop=io_loop)
		# TODO: This supresses some warnings during unit tests, but maybe is not good for production.
		self.client.set_backpressure_multiplier(1000)
		return self.client
Example #2
0
class TemporaryRabbitMQ:
	server_config = """
[
    {rabbit, [{tcp_listeners, [%(RABBITMQ_PORT)s]}]}
].
"""

	def __init__(self, configuration):
		self.started = False
		self.configuration = configuration
		self.client = None

	def start(self):
		# Choose some configuration values.
		self.dir = tempfile.mkdtemp()
		self.nodename = "paasmaker@localhost"
		self.pidfile = os.path.join(self.dir, self.nodename + '.pid')
		self.port = self.configuration.get_free_port()
		self.configfile = tempfile.mkstemp()[1]
		self.outputspoolfile = tempfile.mkstemp()[1]
		self.spoolfd = open(self.outputspoolfile, 'w')

		# Set up an environment.
		environment = {}
		environment['HOME'] = self.dir
		environment['RABBITMQ_BASE'] = self.dir
		environment['RABBITMQ_HOME'] = self.dir
		environment['RABBITMQ_MNESIA_BASE'] = self.dir
		environment['RABBITMQ_LOG_BASE'] = self.dir
		environment['RABBITMQ_NODENAME'] = self.nodename
		environment['RABBITMQ_PORT'] = str(self.port)
		environment['RABBITMQ_CONFIG_FILE'] = self.configfile

		# Set up a configuration file. (Needed to change the listening port)
		config = self.server_config % environment
		open(self.configfile + '.config', 'w').write(config)

		# Fire up the server.
		logging.info("Starting up rabbitmq server because requested by test.")
		self.process = subprocess.Popen([self.configuration.get_flat('rabbitmq_binary')], env=environment,
			stdout=self.spoolfd, stderr=self.spoolfd)

		# As this takes a while, wait until it's started.
		checkfd = open(self.outputspoolfile, 'r')
		max_times = 30 # 6 seconds.
		self.started = False
		while not self.started and max_times > 0:
			checkfd.seek(0)
			contents = checkfd.read()
			if contents.find("broker running") != -1:
				# It's started.
				self.started = True
			else:
				# Wait a bit longer.
				max_times -= 1
				time.sleep(0.2)

		if not self.started:
			checkfd.seek(0)
			raise Exception("Failed to start RabbitMQ: " + checkfd.read())

	def get_client(self, io_loop=None, callback=None):
		credentials = pika.PlainCredentials('guest', 'guest')
		# This will connect immediately.
		parameters = pika.ConnectionParameters(host='localhost',
			port=self.port,
			virtual_host='/',
			credentials=credentials)
		self.client = TornadoConnection(parameters, on_open_callback=callback, io_loop=io_loop)
		# TODO: This supresses some warnings during unit tests, but maybe is not good for production.
		self.client.set_backpressure_multiplier(1000)
		return self.client

	def stop(self):
		if self.started:
			if self.client:
				self.client.close()
			# Clean up the server.
			pid = int(open(self.pidfile, 'r').read())
			os.kill(pid, signal.SIGTERM)
			os.unlink(self.configfile + '.config')
			os.unlink(self.outputspoolfile)
			shutil.rmtree(self.dir)
Example #3
0
class ManagedRabbitMQ(ManagedDaemon):
	"""
	.. warning::
		This class is not in a working state.

	Start a managed instance of a RabbitMQ server.

	No passwords or authentication details are set up on the new node.

	If you plan to use multiple nodes, give each one a different
	``nodepurpose`` argument when calling ``configure()``. This
	prevents the RabbitMQ's from conflicting with each other.

	Please note that it can take 5-7 seconds to start the daemon.

	This was originally designed for unit tests, but later in
	development the code was rearranged to not require RabbitMQ,
	and as such this was no longer used.
	"""

	RABBITMQ_SERVER_CONFIG = """
[
    {rabbit, [{tcp_listeners, [%(RABBITMQ_PORT)s]}]}
].
"""

	def configure(self, working_dir, port, bind_host, nodepurpose=None):
		"""
		Configure this instance.

		:arg str working_dir: The working directory.
		:arg int port: The port to listen on.
		:arg str bind_host: The address to bind to.
		:arg str|None nodepurpose: An optional string to append
			to the node name to make it unique.
		"""
		# TODO: Allow authentication.
		self.parameters['working_dir'] = working_dir
		self.parameters['port'] = port
		self.parameters['host'] = bind_host
		if nodepurpose:
			self.parameters['nodename'] = '%s-paasmaker@localhost' % nodepurpose
		else:
			self.parameters['nodename'] = 'paasmaker@localhost'
		self.parameters['pidfile'] = os.path.join(working_dir, self.parameters['nodename'] + '.pid')
		self.parameters['logfile'] = os.path.join(working_dir, 'rabbitmq.log')

		environment = {}
		environment['HOME'] = working_dir
		environment['RABBITMQ_BASE'] = working_dir
		environment['RABBITMQ_HOME'] = working_dir
		environment['RABBITMQ_MNESIA_BASE'] = working_dir
		environment['RABBITMQ_LOG_BASE'] = working_dir
		environment['RABBITMQ_NODENAME'] = self.parameters['nodename']
		environment['RABBITMQ_PORT'] = str(self.parameters['port'])
		environment['RABBITMQ_CONFIG_FILE'] = self.get_configuration_path(working_dir)

		self.parameters['environment'] = environment

		# Create the working dir. If this fails, let it bubble up.
		if not os.path.exists(working_dir):
			os.makedirs(working_dir)

		self.save_parameters()

	def get_pid_path(self):
		return self.parameters['pidfile']

	def is_running(self, keyword=None):
		return super(ManagedRabbitMQ, self).is_running('rabbitmq')

	def start(self, callback, error_callback):
		"""
		Start up the server for this instance.
		"""
		# Write out the configuration.
		configfile = self.get_configuration_path(self.parameters['working_dir'])
		rabbitconfig = self.RABBITMQ_SERVER_CONFIG % self.parameters['environment']
		fp = open(configfile  + '.config', 'w')
		fp.write(rabbitconfig)
		fp.close()

		logfp = open(self.parameters['logfile'], 'a')

		# Fire up the server.
		logging.info("Starting up RabbitMQ server on port %d (can take up to 10 seconds)." % self.parameters['port'])
		subprocess.Popen(
			[self.configuration.get_flat('rabbitmq_binary')],
			env=self.parameters['environment'],
			stdout=logfp,
			stderr=logfp
		)

		def error(message):
			log_file = open(self.parameters['logfile'], 'r').read()
			error_callback(log_file)

		# Wait for the port to come into use.
		self.configuration.port_allocator.wait_until_port_used(
			self.configuration.io_loop,
			self.parameters['port'],
			5,
			callback,
			error
		)

	def get_client(self, callback=None):
		credentials = pika.PlainCredentials('guest', 'guest')
		# This will connect immediately.
		parameters = pika.ConnectionParameters(host=self.parameters['host'],
			port=self.parameters['port'],
			virtual_host='/',
			credentials=credentials)
		self.client = TornadoConnection(parameters, on_open_callback=callback, io_loop=self.configuration.io_loop)
		# TODO: This supresses some warnings during unit tests, but maybe is not good for production.
		self.client.set_backpressure_multiplier(1000)
		return self.client

	def stop(self, sig=signal.SIGTERM):
		"""
		Stop this instance of the rabbitmq server, allowing for it to be restarted later.
		"""
		if self.client:
			self.client.close()

		super(ManagedRabbitMQ, self).stop(sig)

	def destroy(self):
		"""
		Destroy this instance of rabbitmq, removing all assigned data.
		"""
		# Hard shutdown - we're about to delete the data anyway.
		self.stop(signal.SIGKILL)
		shutil.rmtree(self.parameters['working_dir'])