def setUp(self): self.queue_name = 'test_queue' self.host1 = 'host1' self.host2 = 'host2' self.port = 5672 self.submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port)
def test_url_generation_with_credentials(self): # Given with patch('app.submitter.submitter.BlockingConnection') as connection, \ patch('app.submitter.submitter.URLParameters') as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] username = '******' password = str(uuid.uuid4()) submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port, username=username, password=password) # When published = submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertTrue(published, 'send_message should publish message') # Check we create url for primary then secondary url_parameters_calls = [ call('amqp://{}:{}@{}:{}/%2F'.format(username, password, self.host1, self.port)), call('amqp://{}:{}@{}:{}/%2F'.format(username, password, self.host2, self.port)) ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2)
def setUp(self): self.queue = "test_queue" self.host1 = "host1" self.host2 = "host2" self.port = 5672 self.submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port, queue=self.queue)
def test_when_fail_to_connect_to_queue_then_published_false(self): # Given submitter = RabbitMQSubmitter() # When published = submitter.send_message(message={}, queue='test_queue') # Then self.assertFalse(published, 'send_message should fail to publish message')
def test_when_message_sent_then_published_true(self): # Given with patch('app.submitter.submitter.BlockingConnection'): published = RabbitMQSubmitter().send_message(message={}, queue='test_queue') # When # Then self.assertTrue(published, 'send_message should publish message')
def test_url_generation_with_credentials(self): # Given with patch( "app.submitter.submitter.BlockingConnection" ) as connection, patch( "app.submitter.submitter.URLParameters") as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] username = "******" password = str(uuid.uuid4()) submitter = RabbitMQSubmitter( host=self.host1, secondary_host=self.host2, port=self.port, queue=self.queue, username=username, password=password, ) # When published = submitter.send_message( message={}, tx_id="12345", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertTrue(published, "send_message should publish message") # Check we create url for primary then secondary url_parameters_calls = [ call("amqp://{}:{}@{}:{}/%2F".format(username, password, self.host1, self.port)), call("amqp://{}:{}@{}:{}/%2F".format(username, password, self.host2, self.port)), ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2)
def test_when_fail_to_publish_message_then_returns_false(self): # Given channel = Mock() channel.basic_publish = Mock(return_value=False) connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch('app.submitter.submitter.BlockingConnection', return_value=connection): # When published = RabbitMQSubmitter().send_message(message={}, queue='test_queue') # Then self.assertFalse(published, 'send_message should fail to publish message')
def test_when_fail_to_disconnect_then_log_warning_message(self): # Given connection = Mock() error = AMQPError() connection.close.side_effect = [error] with patch('app.submitter.submitter.BlockingConnection', return_value=connection), \ patch('app.submitter.submitter.logger') as logger: # When published = RabbitMQSubmitter().send_message(message={}, queue='test_queue') # Then self.assertTrue(published) logger.error.assert_called_once_with( 'unable to close rabbit mq connection', rabbit_url='amqp://localhost:5672/%2F', exc_info=error)
def test_when_first_connection_fails_then_secondary_succeeds(self): # Given with patch('app.submitter.submitter.BlockingConnection') as connection, \ patch('app.submitter.submitter.URLParameters') as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] # When published = RabbitMQSubmitter().send_message(message={}, queue='test_queue') # Then self.assertTrue(published, 'send_message should publish message') # Check we create url for primary then secondary url_parameters_calls = [ call(settings.EQ_RABBITMQ_URL), call(settings.EQ_RABBITMQ_URL_SECONDARY) ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with settings.EQ_RABBITMQ_URL_SECONDARY self.assertEqual(connection.call_count, 2)
def setup_submitter(application): if application.config["EQ_SUBMISSION_BACKEND"] == "gcs": bucket_id = application.config.get("EQ_GCS_SUBMISSION_BUCKET_ID") if not bucket_id: raise Exception("Setting EQ_GCS_SUBMISSION_BUCKET_ID Missing") application.eq["submitter"] = GCSSubmitter(bucket_name=bucket_id) elif application.config["EQ_SUBMISSION_BACKEND"] == "rabbitmq": host = application.config.get("EQ_RABBITMQ_HOST") secondary_host = application.config.get("EQ_RABBITMQ_HOST_SECONDARY") if not host: raise Exception("Setting EQ_RABBITMQ_HOST Missing") if not secondary_host: raise Exception("Setting EQ_RABBITMQ_HOST_SECONDARY Missing") application.eq["submitter"] = RabbitMQSubmitter( host=host, secondary_host=secondary_host, port=application.config["EQ_RABBITMQ_PORT"], queue=application.config["EQ_RABBITMQ_QUEUE_NAME"], username=application.eq["secret_store"].get_secret_by_name( "EQ_RABBITMQ_USERNAME" ), password=application.eq["secret_store"].get_secret_by_name( "EQ_RABBITMQ_PASSWORD" ), ) elif application.config["EQ_SUBMISSION_BACKEND"] == "log": application.eq["submitter"] = LogSubmitter() else: raise Exception("Unknown EQ_SUBMISSION_BACKEND")
def create_app(): # noqa: C901 pylint: disable=too-complex application = Flask(__name__, static_url_path='/s', static_folder='../static') application.config.from_object(settings) if application.config['EQ_APPLICATION_VERSION']: logger.info('starting eq survey runner', version=application.config['EQ_APPLICATION_VERSION']) if application.config['EQ_NEW_RELIC_ENABLED']: setup_newrelic() application.eq = {} if application.config['EQ_RABBITMQ_ENABLED']: application.eq['submitter'] = RabbitMQSubmitter( application.config['EQ_RABBITMQ_URL'], application.config['EQ_RABBITMQ_URL_SECONDARY'], ) else: application.eq['submitter'] = LogSubmitter() application.eq['encrypter'] = Encrypter( application.config['EQ_SUBMISSION_SR_PRIVATE_SIGNING_KEY'], application.config['EQ_SUBMISSION_SR_PRIVATE_SIGNING_KEY_PASSWORD'], application.config['EQ_SUBMISSION_SDX_PUBLIC_KEY'], ) application.eq['database'] = Database( application.config['EQ_SERVER_SIDE_STORAGE_DATABASE_URL'], application. config['EQ_SERVER_SIDE_STORAGE_DATABASE_SETUP_RETRY_COUNT'], application. config['EQ_SERVER_SIDE_STORAGE_DATABASE_SETUP_RETRY_DELAY_SECONDS'], ) application.eq['session_storage'] = SessionStorage( application.eq['database'], ) setup_secure_cookies(application) setup_babel(application) application.wsgi_app = AWSReverseProxied(application.wsgi_app) add_blueprints(application) configure_flask_logging(application) login_manager.init_app(application) add_safe_health_check(application) if application.config['EQ_DEV_MODE']: start_dev_mode(application) if application.config['EQ_ENABLE_CACHE']: cache.init_app(application, config={'CACHE_TYPE': 'simple'}) else: cache.init_app(application) # Doesnt cache # Add theme manager application.config['THEME_PATHS'] = os.path.dirname( os.path.abspath(__file__)) Themes(application, app_identifier="surveyrunner") @application.before_request def before_request(): # pylint: disable=unused-variable request_id = str(uuid4()) logger.new(request_id=request_id) @application.after_request def apply_caching(response): # pylint: disable=unused-variable for k, v in SECURE_HEADERS.items(): response.headers[k] = v return response @application.context_processor def override_url_for(): # pylint: disable=unused-variable return dict(url_for=versioned_url_for) @application.teardown_appcontext def shutdown_session(exception=None): # pylint: disable=unused-variable,unused-argument application.eq['database'].remove() return application
def create_app(setting_overrides=None): # noqa: C901 pylint: disable=too-complex application = Flask(__name__, static_url_path='/s', static_folder='../static') application.config.from_object(settings) application.eq = {} with open(application.config['EQ_SECRETS_FILE']) as secrets_file: secrets = yaml.safe_load(secrets_file) with open(application.config['EQ_KEYS_FILE']) as keys_file: keys = yaml.safe_load(keys_file) validate_required_secrets(secrets) validate_required_keys(keys, KEY_PURPOSE_SUBMISSION) application.eq['secret_store'] = SecretStore(secrets) application.eq['key_store'] = KeyStore(keys) if setting_overrides: application.config.update(setting_overrides) if application.config['EQ_APPLICATION_VERSION']: logger.info('starting eq survey runner', version=application.config['EQ_APPLICATION_VERSION']) if application.config['EQ_NEW_RELIC_ENABLED']: setup_newrelic() setup_database(application) setup_dynamodb(application) if application.config['EQ_RABBITMQ_ENABLED']: application.eq['submitter'] = RabbitMQSubmitter( host=application.config['EQ_RABBITMQ_HOST'], secondary_host=application.config['EQ_RABBITMQ_HOST_SECONDARY'], port=application.config['EQ_RABBITMQ_PORT'], username=application.eq['secret_store'].get_secret_by_name( 'EQ_RABBITMQ_USERNAME'), password=application.eq['secret_store'].get_secret_by_name( 'EQ_RABBITMQ_PASSWORD'), ) else: application.eq['submitter'] = LogSubmitter() application.eq['id_generator'] = UserIDGenerator( application.config['EQ_SERVER_SIDE_STORAGE_USER_ID_ITERATIONS'], application.eq['secret_store'].get_secret_by_name( 'EQ_SERVER_SIDE_STORAGE_USER_ID_SALT'), application.eq['secret_store'].get_secret_by_name( 'EQ_SERVER_SIDE_STORAGE_USER_IK_SALT'), ) setup_secure_cookies(application) setup_secure_headers(application) setup_babel(application) application.wsgi_app = AWSReverseProxied(application.wsgi_app) add_blueprints(application) configure_flask_logging(application) login_manager.init_app(application) add_safe_health_check(application) if application.config['EQ_DEV_MODE']: start_dev_mode(application) if application.config['EQ_ENABLE_CACHE']: cache.init_app(application, config={'CACHE_TYPE': 'simple'}) else: # no cache and silence warning cache.init_app(application, config={'CACHE_NO_NULL_WARNING': True}) # Switch off flask default autoescaping as content is html encoded # during schema/metadata/summary context (and navigition) generation application.jinja_env.autoescape = False # Add theme manager application.config['THEME_PATHS'] = os.path.dirname( os.path.abspath(__file__)) Themes(application, app_identifier='surveyrunner') @application.before_request def before_request(): # pylint: disable=unused-variable # While True the session lives for permanent_session_lifetime seconds # Needed to be able to set the client-side cookie expiration cookie_session.permanent = True request_id = str(uuid4()) logger.new(request_id=request_id) @application.after_request def apply_caching(response): # pylint: disable=unused-variable for k, v in CACHE_HEADERS.items(): response.headers[k] = v return response @application.context_processor def override_url_for(): # pylint: disable=unused-variable return dict(url_for=versioned_url_for) return application
class TestSubmitter(TestCase): def setUp(self): self.queue_name = 'test_queue' self.host1 = 'host1' self.host2 = 'host2' self.port = 5672 self.submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port) def test_when_fail_to_connect_to_queue_then_published_false(self): # Given with patch('app.submitter.submitter.BlockingConnection') as connection: connection.side_effect = AMQPError() # When published = self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertFalse(published, 'send_message should fail to publish message') def test_when_message_sent_then_published_true(self): # Given with patch('app.submitter.submitter.BlockingConnection'): # When published = self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertTrue(published, 'send_message should publish message') def test_when_first_connection_fails_then_secondary_succeeds(self): # Given with patch('app.submitter.submitter.BlockingConnection') as connection, \ patch('app.submitter.submitter.URLParameters') as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] # When published = self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertTrue(published, 'send_message should publish message') # Check we create url for primary then secondary url_parameters_calls = [ call('amqp://{}:{}/%2F'.format(self.host1, self.port)), call('amqp://{}:{}/%2F'.format(self.host2, self.port)) ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2) def test_url_generation_with_credentials(self): # Given with patch('app.submitter.submitter.BlockingConnection') as connection, \ patch('app.submitter.submitter.URLParameters') as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] username = '******' password = str(uuid.uuid4()) submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port, username=username, password=password) # When published = submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertTrue(published, 'send_message should publish message') # Check we create url for primary then secondary url_parameters_calls = [ call('amqp://{}:{}@{}:{}/%2F'.format(username, password, self.host1, self.port)), call('amqp://{}:{}@{}:{}/%2F'.format(username, password, self.host2, self.port)) ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2) def test_when_fail_to_disconnect_then_log_warning_message(self): # Given connection = Mock() error = AMQPError() connection.close.side_effect = [error] with patch('app.submitter.submitter.BlockingConnection', return_value=connection), \ patch('app.submitter.submitter.logger') as logger: # When published = self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertTrue(published) logger.error.assert_called_once_with('unable to close connection', category='rabbitmq', exc_info=error) def test_when_fail_to_publish_message_then_returns_false(self): # Given channel = Mock() channel.basic_publish = Mock(side_effect=UnroutableError('Error')) connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch('app.submitter.submitter.BlockingConnection', return_value=connection): # When published = self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then self.assertFalse(published, 'send_message should fail to publish message') def test_when_message_sent_then_tx_id_is_sent_in_header(self): # Given channel = Mock() connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch('app.submitter.submitter.BlockingConnection', return_value=connection): # When self.submitter.send_message(message={}, queue=self.queue_name, tx_id='12345') # Then call_args = channel.basic_publish.call_args properties = call_args[1]['properties'] headers = properties.headers self.assertEqual(headers['tx_id'], '12345') def test_when_message_sent_with_none_tx_id_then_tx_id_is_not_sent_in_header( self): # Given channel = Mock() connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch('app.submitter.submitter.BlockingConnection', return_value=connection): # When self.submitter.send_message(message={}, queue=self.queue_name, tx_id=None) # Then call_args = channel.basic_publish.call_args properties = call_args[1]['properties'] headers = properties.headers self.assertEqual(len(headers), 0)
class TestRabbitMQSubmitter(TestCase): def setUp(self): self.queue = "test_queue" self.host1 = "host1" self.host2 = "host2" self.port = 5672 self.submitter = RabbitMQSubmitter(host=self.host1, secondary_host=self.host2, port=self.port, queue=self.queue) def test_when_fail_to_connect_to_queue_then_published_false(self): # Given with patch("app.submitter.submitter.BlockingConnection") as connection: connection.side_effect = AMQPError() # When published = self.submitter.send_message( message={}, tx_id="123", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertFalse(published, "send_message should fail to publish message") def test_when_message_sent_then_published_true(self): # Given with patch("app.submitter.submitter.BlockingConnection"): published = self.submitter.send_message( message={}, tx_id="123", questionnaire_id="0123456789000000", case_id="456", ) # When # Then self.assertTrue(published, "send_message should publish message") def test_when_first_connection_fails_then_secondary_succeeds(self): # Given with patch( "app.submitter.submitter.BlockingConnection" ) as connection, patch( "app.submitter.submitter.URLParameters") as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] # When published = self.submitter.send_message( message={}, tx_id="12345", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertTrue(published, "send_message should publish message") # Check we create url for primary then secondary url_parameters_calls = [ call("amqp://{}:{}/%2F".format(self.host1, self.port)), call("amqp://{}:{}/%2F".format(self.host2, self.port)), ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2) def test_url_generation_with_credentials(self): # Given with patch( "app.submitter.submitter.BlockingConnection" ) as connection, patch( "app.submitter.submitter.URLParameters") as url_parameters: secondary_connection = Mock() connection.side_effect = [AMQPError(), secondary_connection] username = "******" password = str(uuid.uuid4()) submitter = RabbitMQSubmitter( host=self.host1, secondary_host=self.host2, port=self.port, queue=self.queue, username=username, password=password, ) # When published = submitter.send_message( message={}, tx_id="12345", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertTrue(published, "send_message should publish message") # Check we create url for primary then secondary url_parameters_calls = [ call("amqp://{}:{}@{}:{}/%2F".format(username, password, self.host1, self.port)), call("amqp://{}:{}@{}:{}/%2F".format(username, password, self.host2, self.port)), ] url_parameters.assert_has_calls(url_parameters_calls) # Check we create connection twice, failing first then with self.url2 self.assertEqual(connection.call_count, 2) def test_when_fail_to_disconnect_then_log_warning_message(self): # Given connection = Mock() error = AMQPError() connection.close.side_effect = [error] with patch("app.submitter.submitter.BlockingConnection", return_value=connection), patch( "app.submitter.submitter.logger") as logger: # When published = self.submitter.send_message( message={}, tx_id="123", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertTrue(published) logger.error.assert_called_once_with("unable to close connection", category="rabbitmq", exc_info=error) def test_when_fail_to_publish_message_then_returns_false(self): # Given channel = Mock() channel.basic_publish = Mock(return_value=False) connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch("app.submitter.submitter.BlockingConnection", return_value=connection): # When published = self.submitter.send_message( message={}, tx_id="123", questionnaire_id="0123456789000000", case_id="456", ) # Then self.assertFalse(published, "send_message should fail to publish message") def test_when_message_sent_then_metadata_is_sent_in_header(self): # Given channel = Mock() connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch("app.submitter.submitter.BlockingConnection", return_value=connection): # When self.submitter.send_message( message={}, tx_id="12345", questionnaire_id="0123456789000000", case_id="98765", ) # Then call_args = channel.basic_publish.call_args properties = call_args[1]["properties"] headers = properties.headers self.assertEqual(headers["tx_id"], "12345") self.assertEqual(headers["questionnaire_id"], "0123456789000000") self.assertEqual(headers["case_id"], "98765") def test_when_message_sent_then_case_id_not_in_header_if_missing(self): # Given channel = Mock() connection = Mock() connection.channel.side_effect = Mock(return_value=channel) with patch("app.submitter.submitter.BlockingConnection", return_value=connection): # When self.submitter.send_message(message={}, tx_id="12345", questionnaire_id="0123456789000000") # Then call_args = channel.basic_publish.call_args properties = call_args[1]["properties"] headers = properties.headers self.assertEqual(headers["tx_id"], "12345") self.assertEqual(headers["questionnaire_id"], "0123456789000000")
def create_app(setting_overrides=None): # noqa: C901 pylint: disable=too-complex,too-many-statements application = Flask(__name__, static_url_path='/s', static_folder='../static') application.config.from_object(settings) application.eq = {} with open(application.config['EQ_SECRETS_FILE']) as secrets_file: secrets = yaml.safe_load(secrets_file) with open(application.config['EQ_KEYS_FILE']) as keys_file: keys = yaml.safe_load(keys_file) validate_required_secrets(secrets) validate_required_keys(keys, KEY_PURPOSE_SUBMISSION) application.eq['secret_store'] = SecretStore(secrets) application.eq['key_store'] = KeyStore(keys) if setting_overrides: application.config.update(setting_overrides) if application.config['EQ_APPLICATION_VERSION']: logger.info('starting eq survey runner', version=application.config['EQ_APPLICATION_VERSION']) if application.config['EQ_NEW_RELIC_ENABLED']: setup_newrelic() setup_database(application) setup_dynamodb(application) setup_s3(application) setup_bigtable(application) setup_gcs(application) setup_redis(application) setup_gc_datastore(application) if application.config['EQ_SUBMITTER'] == 'rabbitmq': application.eq['submitter'] = RabbitMQSubmitter( host=application.config['EQ_RABBITMQ_HOST'], secondary_host=application.config['EQ_RABBITMQ_HOST_SECONDARY'], port=application.config['EQ_RABBITMQ_PORT'], username=application.eq['secret_store'].get_secret_by_name('EQ_RABBITMQ_USERNAME'), password=application.eq['secret_store'].get_secret_by_name('EQ_RABBITMQ_PASSWORD'), ) elif application.config['EQ_SUBMITTER'] == 'pubsub': application.eq['submitter'] = PubSubSubmitter( project_id=application.config['EQ_PUBSUB_PROJECT_ID'], topic=application.config['EQ_PUBSUB_TOPIC'], ) elif application.config['EQ_SUBMITTER'] == 'gcs': application.eq['submitter'] = GCSSubmitter( bucket_name=application.config['EQ_GCS_SUBMISSION_BUCKET_ID'], ) else: application.eq['submitter'] = LogSubmitter() application.eq['id_generator'] = UserIDGenerator( application.config['EQ_SERVER_SIDE_STORAGE_USER_ID_ITERATIONS'], application.eq['secret_store'].get_secret_by_name('EQ_SERVER_SIDE_STORAGE_USER_ID_SALT'), application.eq['secret_store'].get_secret_by_name('EQ_SERVER_SIDE_STORAGE_USER_IK_SALT'), ) setup_secure_cookies(application) setup_secure_headers(application) setup_babel(application) application.wsgi_app = AWSReverseProxied(application.wsgi_app) add_blueprints(application) configure_flask_logging(application) login_manager.init_app(application) add_safe_health_check(application) if application.config['EQ_DEV_MODE']: start_dev_mode(application) # Switch off flask default autoescaping as content is html encoded # during schema/metadata/summary context (and navigition) generation application.jinja_env.autoescape = False # Add theme manager application.config['THEME_PATHS'] = os.path.dirname(os.path.abspath(__file__)) Themes(application, app_identifier='surveyrunner') # pylint: disable=maybe-no-member application.jinja_env.globals['theme'] = flask_theme_cache.get_global_theme_template() @application.before_request def before_request(): # pylint: disable=unused-variable request_id = str(uuid4()) logger.new(request_id=request_id) @application.after_request def apply_caching(response): # pylint: disable=unused-variable for k, v in CACHE_HEADERS.items(): response.headers[k] = v return response @application.context_processor def override_url_for(): # pylint: disable=unused-variable return dict(url_for=versioned_url_for) return application
def setUp(self): self.queue_name = 'test_queue' self.url1 = 'amqp://localhost:5672/%2F' self.url2 = 'amqp://localhost:5672/%2F' self.submitter = RabbitMQSubmitter(self.url1, self.url2)