summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Fedotov <dfedotov@pivotal.io>2017-02-16 17:19:15 +0000
committerDaniil Fedotov <dfedotov@pivotal.io>2017-02-16 17:19:15 +0000
commit38bf6ec721f7d71e6e0477e029cde510bda85378 (patch)
treec9d9a72608e5ab2c2edb5363f3c8601b2f52efef
parent6aa14c4889e2a85acf4c2ed343694152f7a7051e (diff)
parent3b9953647e49883d64d6f205e2ec05c2440a301f (diff)
downloadrabbitmq-server-git-38bf6ec721f7d71e6e0477e029cde510bda85378.tar.gz
Merge branch 'master' into rabbitmq-auth-backend-uaa-3
-rw-r--r--Makefile29
-rw-r--r--docs/rabbitmq.conf.example60
-rw-r--r--docs/rabbitmq.config.example36
-rw-r--r--priv/schema/rabbitmq.schema8
-rw-r--r--rabbitmq-components.mk7
-rw-r--r--rabbitmq.conf.d/ldap.conf138
-rw-r--r--rabbitmq.conf.d/rabbitmq.conf731
-rw-r--r--scripts/rabbitmq-server.bat8
-rw-r--r--scripts/rabbitmq-service.bat8
-rw-r--r--src/rabbit.erl4
-rw-r--r--src/rabbit_mirror_queue_sync.erl2
-rw-r--r--src/rabbit_priority_queue.erl2
-rw-r--r--src/rabbit_ssl.erl228
-rw-r--r--src/rabbit_table.erl2
-rw-r--r--src/rabbit_upgrade_functions.erl2
-rw-r--r--src/rabbit_variable_queue.erl133
-rw-r--r--test/config_schema_SUITE_data/snippets.config141
-rw-r--r--test/dynamic_ha_SUITE.erl28
-rw-r--r--test/priority_queue_SUITE.erl26
-rw-r--r--test/proxy_protocol_SUITE.erl100
-rw-r--r--test/topic_permission_SUITE.erl46
-rw-r--r--test/unit_inbroker_SUITE.erl24
22 files changed, 505 insertions, 1258 deletions
diff --git a/Makefile b/Makefile
index f953eaf46f..dbe9d55545 100644
--- a/Makefile
+++ b/Makefile
@@ -89,11 +89,11 @@ define PROJECT_ENV
%% setting has no effect because credit_flow is not used when
%% writing to the queue index. See the setting
%% queue_index_embed_msgs_below above.
- {msg_store_credit_disc_bound, {2000, 500}},
+ {msg_store_credit_disc_bound, {3000, 800}},
{msg_store_io_batch_size, 2048},
- %% see rabbitmq-server#143
- %% and rabbitmq-server#949
- {credit_flow_default_credit, {200, 100}},
+ %% see rabbitmq-server#143,
+ %% rabbitmq-server#949, rabbitmq-server#1098
+ {credit_flow_default_credit, {400, 200}},
%% see rabbitmq-server#248
%% and rabbitmq-server#667
{channel_operation_timeout, 15000},
@@ -112,8 +112,10 @@ define PROJECT_ENV
%% rabbitmq-server-973
{queue_explicit_gc_run_operation_threshold, 1000},
{lazy_queue_explicit_gc_run_operation_threshold, 1000},
- {background_gc_enabled, true},
- {background_gc_target_interval, 60000}
+ {background_gc_enabled, false},
+ {background_gc_target_interval, 60000},
+ %% rabbitmq-server-589
+ {proxy_protocol, false}
]
endef
@@ -139,10 +141,6 @@ EXTRA_SOURCES += $(USAGES_ERL)
.DEFAULT_GOAL = all
$(PROJECT).d:: $(EXTRA_SOURCES)
-copy-escripts:
- cp -r ${DEPS_DIR}/rabbitmq_cli/escript ./
-
-
DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk \
rabbit_common/mk/rabbitmq-dist.mk \
rabbit_common/mk/rabbitmq-run.mk \
@@ -180,13 +178,22 @@ USE_PROPER_QC := $(shell $(ERL) -eval 'io:format({module, proper} =:= code:ensur
RMQ_ERLC_OPTS += $(if $(filter true,$(USE_PROPER_QC)),-Duse_proper_qc)
endif
+.PHONY: copy-escripts clean-extra-sources clean-escripts
+
+CLI_ESCRIPTS_DIR = escript
+
+copy-escripts:
+ $(gen_verbose) $(MAKE) -C $(DEPS_DIR)/rabbitmq_cli install \
+ PREFIX="$(abspath $(CLI_ESCRIPTS_DIR))" \
+ DESTDIR=
+
clean:: clean-extra-sources clean-escripts
clean-extra-sources:
$(gen_verbose) rm -f $(EXTRA_SOURCES)
clean-escripts:
- $(gen_verbose) rm -rf escript
+ $(gen_verbose) rm -rf "$(CLI_ESCRIPTS_DIR)"
# --------------------------------------------------------------------
# Documentation.
diff --git a/docs/rabbitmq.conf.example b/docs/rabbitmq.conf.example
index 96d0967db7..0e8d1e0596 100644
--- a/docs/rabbitmq.conf.example
+++ b/docs/rabbitmq.conf.example
@@ -395,6 +395,16 @@
##
# background_gc_target_interval = 60000
+## Whether or not to enable proxy protocol support.
+## Once enabled, clients cannot directly connect to the broker
+## anymore. They must connect through a load balancer that sends the
+## proxy protocol header to the broker at connection time.
+## This setting applies only to AMQP clients, other protocols
+## like MQTT or STOMP have their own setting to enable proxy protocol.
+## See the plugins documentation for more information.
+##
+# proxy_protocol = false
+
## ----------------------------------------------------------------------------
## Advanced Erlang Networking/Clustering Options.
##
@@ -515,6 +525,16 @@
##
# stomp.implicit_connect = true
+## Whether or not to enable proxy protocol support.
+## Once enabled, clients cannot directly connect to the broker
+## anymore. They must connect through a load balancer that sends the
+## proxy protocol header to the broker at connection time.
+## This setting applies only to STOMP clients, other protocols
+## like MQTT or AMQP have their own setting to enable proxy protocol.
+## See the plugins or broker documentation for more information.
+##
+# stomp.proxy_protocol = false
+
## ----------------------------------------------------------------------------
## RabbitMQ MQTT Adapter
##
@@ -578,6 +598,16 @@
# mqtt.tcp_listen_options.backlog = 128
# mqtt.tcp_listen_options.nodelay = true
+## Whether or not to enable proxy protocol support.
+## Once enabled, clients cannot directly connect to the broker
+## anymore. They must connect through a load balancer that sends the
+## proxy protocol header to the broker at connection time.
+## This setting applies only to STOMP clients, other protocols
+## like STOMP or AMQP have their own setting to enable proxy protocol.
+## See the plugins or broker documentation for more information.
+##
+# mqtt.proxy_protocol = false
+
## ----------------------------------------------------------------------------
## RabbitMQ AMQP 1.0 Support
##
@@ -660,25 +690,25 @@
## Specify servers to bind to. You *must* set this in order for the plugin
## to work properly.
##
-# ldap.servers.1 = your-server-name-goes-here
+# auth_ldap.servers.1 = your-server-name-goes-here
## You can define multiple servers
-# ldap.servers.2 = your-other-server
+# auth_ldap.servers.2 = your-other-server
## Connect to the LDAP server using SSL
##
-# ldap.use_ssl = false
+# auth_ldap.use_ssl = false
## Specify the LDAP port to connect to
##
-# ldap.port = 389
+# auth_ldap.port = 389
## LDAP connection timeout, in milliseconds or 'infinity'
##
-# ldap.timeout = infinity
+# auth_ldap.timeout = infinity
## Or number
-# ldap.timeout = 500
+# auth_ldap.timeout = 500
## Enable logging of LDAP queries.
## One of
@@ -688,11 +718,11 @@
##
## Defaults to false.
##
-# ldap.log = false
+# auth_ldap.log = false
## Also can be true or network
-# ldap.log = true
-# ldap.log = network
+# auth_ldap.log = true
+# auth_ldap.log = network
##
## Authentication
@@ -702,7 +732,7 @@
## Pattern to convert the username given through AMQP to a DN before
## binding
##
-# ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com
+# auth_ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com
## Alternatively, you can convert a username to a Distinguished
## Name via an LDAP lookup after binding. See the documentation for
@@ -712,8 +742,8 @@
## the name of the attribute that represents the user name, and the
## base DN for the lookup query.
##
-# ldap.dn_lookup_attribute = userPrincipalName
-# ldap.dn_lookup_base = DC=gopivotal,DC=com
+# auth_ldap.dn_lookup_attribute = userPrincipalName
+# auth_ldap.dn_lookup_base = DC=gopivotal,DC=com
## Controls how to bind for authorisation queries and also to
## retrieve the details of users logging in without presenting a
@@ -725,11 +755,11 @@
##
## Defaults to 'as_user'.
##
-# ldap.other_bind = as_user
+# auth_ldap.other_bind = as_user
## Or can be more complex:
-# ldap.other_bind.user_dn = User
-# ldap.other_bind.password = Password
+# auth_ldap.other_bind.user_dn = User
+# auth_ldap.other_bind.password = Password
## If user_dn and password defined - other options is ignored.
diff --git a/docs/rabbitmq.config.example b/docs/rabbitmq.config.example
index aaffcab2d8..50e97cd3bb 100644
--- a/docs/rabbitmq.config.example
+++ b/docs/rabbitmq.config.example
@@ -346,7 +346,17 @@
%% the operation (can be higher than this interval). Values less than
%% 30000 milliseconds are not recommended.
%%
- %% {background_gc_target_interval, 60000}
+ %% {background_gc_target_interval, 60000},
+
+ %% Whether or not to enable proxy protocol support.
+ %% Once enabled, clients cannot directly connect to the broker
+ %% anymore. They must connect through a load balancer that sends the
+ %% proxy protocol header to the broker at connection time.
+ %% This setting applies only to AMQP clients, other protocols
+ %% like MQTT or STOMP have their own setting to enable proxy protocol.
+ %% See the plugins documentation for more information.
+ %%
+ %% {proxy_protocol, false}
]},
@@ -517,7 +527,17 @@
%% SSL certificate whenever the first frame sent on a session is not a
%% CONNECT frame.
%%
- %% {implicit_connect, true}
+ %% {implicit_connect, true},
+
+ %% Whether or not to enable proxy protocol support.
+ %% Once enabled, clients cannot directly connect to the broker
+ %% anymore. They must connect through a load balancer that sends the
+ %% proxy protocol header to the broker at connection time.
+ %% This setting applies only to STOMP clients, other protocols
+ %% like MQTT or AMQP have their own setting to enable proxy protocol.
+ %% See the plugins or broker documentation for more information.
+ %%
+ %% {proxy_protocol, false}
]},
%% ----------------------------------------------------------------------------
@@ -575,7 +595,17 @@
%% TCP/Socket options (as per the broker configuration).
%%
%% {tcp_listen_options, [{backlog, 128},
- %% {nodelay, true}]}
+ %% {nodelay, true}]},
+
+ %% Whether or not to enable proxy protocol support.
+ %% Once enabled, clients cannot directly connect to the broker
+ %% anymore. They must connect through a load balancer that sends the
+ %% proxy protocol header to the broker at connection time.
+ %% This setting applies only to MQTT clients, other protocols
+ %% like STOMP or AMQP have their own setting to enable proxy protocol.
+ %% See the plugins or broker documentation for more information.
+ %%
+ %% {proxy_protocol, false}
]},
%% ----------------------------------------------------------------------------
diff --git a/priv/schema/rabbitmq.schema b/priv/schema/rabbitmq.schema
index 71032c4ffb..6f3f42e4ed 100644
--- a/priv/schema/rabbitmq.schema
+++ b/priv/schema/rabbitmq.schema
@@ -284,6 +284,7 @@ fun(Conf) ->
(internal) -> rabbit_auth_backend_internal;
(ldap) -> rabbit_auth_backend_ldap;
(http) -> rabbit_auth_backend_http;
+ (cache) -> rabbit_auth_backend_cache;
(amqp) -> rabbit_auth_backend_amqp;
(dummy) -> rabbit_auth_backend_dummy;
(Other) when is_atom(Other) -> Other;
@@ -941,6 +942,13 @@ end}.
{mapping, "background_gc_target_interval", "rabbit.background_gc_target_interval",
[{datatype, integer}]}.
+%% Whether or not to enable proxy protocol support.
+%%
+%% {proxy_protocol, false}
+
+{mapping, "proxy_protocol", "rabbit.proxy_protocol",
+ [{datatype, {enum, [true, false]}}]}.
+
% ==========================
% Lager section
% ==========================
diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk
index fdabf1ac11..590c204d65 100644
--- a/rabbitmq-components.mk
+++ b/rabbitmq-components.mk
@@ -42,6 +42,7 @@ dep_rabbit = git_rmq rabbitmq-server $(current_rmq_re
dep_rabbit_common = git_rmq rabbitmq-common $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_amqp1_0 = git_rmq rabbitmq-amqp1.0 $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_amqp = git_rmq rabbitmq-auth-backend-amqp $(current_rmq_ref) $(base_rmq_ref) master
+dep_rabbitmq_auth_backend_cache = git_rmq rabbitmq-auth-backend-cache $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_http = git_rmq rabbitmq-auth-backend-http $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_backend_ldap = git_rmq rabbitmq-auth-backend-ldap $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_auth_mechanism_ssl = git_rmq rabbitmq-auth-mechanism-ssl $(current_rmq_ref) $(base_rmq_ref) master
@@ -59,6 +60,7 @@ dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rm
dep_rabbitmq_federation_management = git_rmq rabbitmq-federation-management $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_java_client = git_rmq rabbitmq-java-client $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_jms_client = git_rmq rabbitmq-jms-client $(current_rmq_ref) $(base_rmq_ref) master
+dep_rabbitmq_jms_cts = git_rmq rabbitmq-jms-cts $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_jms_topic_exchange = git_rmq rabbitmq-jms-topic-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_lvc = git_rmq rabbitmq-lvc-plugin $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_management = git_rmq rabbitmq-management $(current_rmq_ref) $(base_rmq_ref) master
@@ -102,14 +104,16 @@ dep_rabbitmq_public_umbrella = git_rmq rabbitmq-public-umbrella $(curre
dep_cowboy_commit = 1.1.0
dep_mochiweb = git git://github.com/basho/mochiweb.git v2.9.0p2
-dep_ranch_commit = 1.3.1
+dep_ranch_commit = 1.3.2
dep_webmachine_commit = 1.10.8p2
+dep_ranch_proxy_protocol = git git://github.com/heroku/ranch_proxy_protocol.git 1.4.2
RABBITMQ_COMPONENTS = amqp_client \
rabbit \
rabbit_common \
rabbitmq_amqp1_0 \
rabbitmq_auth_backend_amqp \
+ rabbitmq_auth_backend_cache \
rabbitmq_auth_backend_http \
rabbitmq_auth_backend_ldap \
rabbitmq_auth_mechanism_ssl \
@@ -127,6 +131,7 @@ RABBITMQ_COMPONENTS = amqp_client \
rabbitmq_federation_management \
rabbitmq_java_client \
rabbitmq_jms_client \
+ rabbitmq_jms_cts \
rabbitmq_jms_topic_exchange \
rabbitmq_lvc \
rabbitmq_management \
diff --git a/rabbitmq.conf.d/ldap.conf b/rabbitmq.conf.d/ldap.conf
deleted file mode 100644
index 2f51cbb409..0000000000
--- a/rabbitmq.conf.d/ldap.conf
+++ /dev/null
@@ -1,138 +0,0 @@
-# ## ----------------------------------------------------------------------------
-# ## RabbitMQ LDAP Plugin
-# ##
-# ## See http://www.rabbitmq.com/ldap.html for details.
-# ##
-# ## ----------------------------------------------------------------------------
-
-
-# =======================================
-# LDAP section
-# =======================================
-
-# Should be defined in additional.conf maybe?
-
-# {rabbitmq_auth_backend_ldap,
-# [##
-# ## Connecting to the LDAP server(s)
-# ## ================================
-# ##
-
-# ## Specify servers to bind to. You *must* set this in order for the plugin
-# ## to work properly.
-# ##
-# ## {servers, ["your-server-name-goes-here"]},
-
-ldap.servers.myserver = your-server-name-goes-here
-
-# ## Connect to the LDAP server using SSL
-# ##
-# ## {use_ssl, false},
-
-ldap.use_ssl = false
-
-# ## Specify the LDAP port to connect to
-# ##
-# ## {port, 389},
-
-ldap.port = 389
-
-# ## LDAP connection timeout, in milliseconds or 'infinity'
-# ##
-# ## {timeout, infinity},
-
-ldap.timeout = infinity
-
-# Or number
-# ldap.timeout = 500
-
-# ## Enable logging of LDAP queries.
-# ## One of
-# ## - false (no logging is performed)
-# ## - true (verbose logging of the logic used by the plugin)
-# ## - network (as true, but additionally logs LDAP network traffic)
-# ##
-# ## Defaults to false.
-# ##
-# ## {log, false},
-
-ldap.log = false
-
-# Also can be true or network
-# ldap.log = true
-# ldap.log = network
-
-# ##
-# ## Authentication
-# ## ==============
-# ##
-
-# ## Pattern to convert the username given through AMQP to a DN before
-# ## binding
-# ##
-# ## {user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"},
-
-ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com
-
-# ## Alternatively, you can convert a username to a Distinguished
-# ## Name via an LDAP lookup after binding. See the documentation for
-# ## full details.
-
-# ## When converting a username to a dn via a lookup, set these to
-# ## the name of the attribute that represents the user name, and the
-# ## base DN for the lookup query.
-# ##
-# ## {dn_lookup_attribute, "userPrincipalName"},
-# ## {dn_lookup_base, "DC=gopivotal,DC=com"},
-
-ldap.dn_lookup_attribute = userPrincipalName
-ldap.dn_lookup_base = DC=gopivotal,DC=com
-
-# ## Controls how to bind for authorisation queries and also to
-# ## retrieve the details of users logging in without presenting a
-# ## password (e.g., SASL EXTERNAL).
-# ## One of
-# ## - as_user (to bind as the authenticated user - requires a password)
-# ## - anon (to bind anonymously)
-# ## - {UserDN, Password} (to bind with a specified user name and password)
-# ##
-# ## Defaults to 'as_user'.
-# ##
-# ## {other_bind, as_user},
-
-ldap.other_bind = as_user
-
-# Or can be more complex:
-# ldap.other_bind.user_dn = User
-# ldap.other_bind.password = Password
-# If user_dn and password defined - other options is ignored.
-
-# -----------------------------
-# Too complex section of LDAP
-# -----------------------------
-
-# ##
-# ## Authorisation
-# ## =============
-# ##
-
-# ## The LDAP plugin can perform a variety of queries against your
-# ## LDAP server to determine questions of authorisation. See
-# ## http://www.rabbitmq.com/ldap.html#authorisation for more
-# ## information.
-
-# ## Set the query to use when determining vhost access
-# ##
-# ## {vhost_access_query, {in_group,
-# ## "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}},
-
-# ## Set the query to use when determining resource (e.g., queue) access
-# ##
-# ## {resource_access_query, {constant, true}},
-
-# ## Set queries to determine which tags a user has
-# ##
-# ## {tag_queries, []}
-# ]},
-# -----------------------------
-
diff --git a/rabbitmq.conf.d/rabbitmq.conf b/rabbitmq.conf.d/rabbitmq.conf
deleted file mode 100644
index 6d43dc9f7f..0000000000
--- a/rabbitmq.conf.d/rabbitmq.conf
+++ /dev/null
@@ -1,731 +0,0 @@
-# ======================================
-# RabbbitMQ broker section
-# ======================================
-
-## Network Connectivity
-## ====================
-##
-## By default, RabbitMQ will listen on all interfaces, using
-## the standard (reserved) AMQP port.
-##
-listener.tcp.default = 5672
-
-
-## To listen on a specific interface, provide an IP address with port.
-## For example, to listen only on localhost for both IPv4 and IPv6:
-##
-# IPv4
-# listener.tcp.local = 127.0.0.1:5672
-# IPv6
-# listener.tcp.local_v6 = ::1:5672
-
-## You can define multiple listeners using listener names
-# listener.tcp.other_port = 5673
-# listener.tcp.other_ip = 10.10.10.10:5672
-
-
-## SSL listeners are configured in the same fashion as TCP listeners,
-## including the option to control the choice of interface.
-##
-# listener.ssl.default = 5671
-
-## Number of Erlang processes that will accept connections for the TCP
-## and SSL listeners.
-##
-num_acceptors.tcp = 10
-num_acceptors.ssl = 1
-
-
-## Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection
-## and SSL handshake), in milliseconds.
-##
-handshake_timeout = 10000
-
-## Set to 'true' to perform reverse DNS lookups when accepting a
-## connection. Hostnames will then be shown instead of IP addresses
-## in rabbitmqctl and the management plugin.
-##
-reverse_dns_lookups = true
-
-##
-## Security / AAA
-## ==============
-##
-
-## The default "guest" user is only permitted to access the server
-## via a loopback interface (e.g. localhost).
-## {loopback_users, [<<"guest">>]},
-##
-loopback_user.guest = true
-
-## Uncomment the following line if you want to allow access to the
-## guest user from anywhere on the network.
-# loopback_user.guest = false
-
-## Configuring SSL.
-## See http://www.rabbitmq.com/ssl.html for full documentation.
-##
-ssl_option.verify = verify_peer
-ssl_option.fail_if_no_peer_cert = false
-# ssl_option.cacertfile = /path/to/rabbitmq.crt
-# ssl_option.certfile = /path/to/rabbitmq.crt
-# ssl_option.keyfile = /path/to/rabbitmq.key
-
-## Choose the available SASL mechanism(s) to expose.
-## The two default (built in) mechanisms are 'PLAIN' and
-## 'AMQPLAIN'. Additional mechanisms can be added via
-## plugins.
-##
-## See http://www.rabbitmq.com/authentication.html for more details.
-##
-auth_mechanism.plain = PLAIN
-auth_mechanism.amqplain = AMQPLAIN
-
-## Select an authentication database to use. RabbitMQ comes bundled
-## with a built-in auth-database, based on mnesia.
-##
-auth_backends.1 = internal
-
-auth_backends.2.authn = ldap
-auth_backends.2.authz = internal
-
-auth_backends.3.authz = rabbit_auth_backend_uaa
-
-## Configurations supporting the rabbitmq_auth_mechanism_ssl and
-## rabbitmq_auth_backend_ldap plugins.
-##
-## NB: These options require that the relevant plugin is enabled.
-## See http://www.rabbitmq.com/plugins.html for further details.
-
-
-## The RabbitMQ-auth-mechanism-ssl plugin makes it possible to
-## authenticate a user based on the client's SSL certificate.
-##
-## To use auth-mechanism-ssl, add to or replace the auth_mechanisms
-## with EXTERNAL value.
-##
-#auth_mechanism.external = EXTERNAL
-
-## The rabbitmq_auth_backend_ldap plugin allows the broker to
-## perform authentication and authorisation by deferring to an
-## external LDAP server.
-##
-## For more information about configuring the LDAP backend, see
-## http://www.rabbitmq.com/ldap.html.
-##
-## Enable the LDAP auth backend by adding to or replacing the
-## auth_backends entry:
-##
-# auth_backends.2 = rabbit_auth_backend_ldap
-
-## Add another backend
-# auth_backend.3 = rabbit_auth_backend_http
-
-
-## This pertains to both the rabbitmq_auth_mechanism_ssl plugin and
-## STOMP ssl_cert_login configurations. See the rabbitmq_stomp
-## configuration section later in this file and the README in
-## https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further
-## details.
-##
-## To use the SSL cert's CN instead of its DN as the username
-##
-# ssl_cert_login_from = common_name
-
-## SSL handshake timeout, in milliseconds.
-##
-# ssl_handshake_timeout = 5000
-
-
-## Password hashing implementation. Will only affect newly
-## created users. To recalculate hash for an existing user
-## it's necessary to update her password.
-##
-## To use SHA-512, set to rabbit_password_hashing_sha512.
-##
-password_hashing_module = rabbit_password_hashing_sha256
-
-## When importing definitions exported from versions earlier
-## than 3.6.0, it is possible to go back to MD5 (only do this
-## as a temporary measure!) by setting this to rabbit_password_hashing_md5.
-##
-# password_hashing_module = rabbit_password_hashing_md5
-
-##
-## Default User / VHost
-## ====================
-##
-
-## On first start RabbitMQ will create a vhost and a user. These
-## config items control what gets created. See
-## http://www.rabbitmq.com/access-control.html for further
-## information about vhosts and access control.
-##
-default_vhost = /
-default_user = guest
-default_pass = guest
-
-default_permissions.configure = .*
-default_permissions.read = .*
-default_permissions.write = .*
-
-## Tags for default user
-##
-## For more details about tags, see the documentation for the
-## Management Plugin at http://www.rabbitmq.com/management.html.
-##
-default_user_tags.administrator = true
-
-## Define other tags like this:
-# default_user_tags.management = true
-# default_user_tags.custom_tag = true
-
-##
-## Additional network and protocol related configuration
-## =====================================================
-##
-
-## Set the default AMQP heartbeat delay (in seconds).
-##
-heartbeat = 600
-
-## Set the max permissible size of an AMQP frame (in bytes).
-##
-frame_max = 131072
-
-## Set the max frame size the server will accept before connection
-## tuning occurs
-##
-initial_frame_max = 4096
-
-## Set the max permissible number of channels per connection.
-## 0 means "no limit".
-##
-channel_max = 128
-
-## Customising Socket Options.
-##
-## See (http://www.erlang.org/doc/man/inet.html#setopts-2) for
-## further documentation.
-##
-
-tcp_listen_option.backlog = 128
-tcp_listen_option.nodelay = true
-tcp_listen_option.exit_on_close = false
-
-##
-## Resource Limits & Flow Control
-## ==============================
-##
-## See http://www.rabbitmq.com/memory.html for full details.
-
-## Memory-based Flow Control threshold.
-##
-vm_memory_high_watermark.relative = 0.4
-
-## Alternatively, we can set a limit (in bytes) of RAM used by the node.
-##
-# vm_memory_high_watermark.absolute = 1073741824
-
-## Or you can set absolute value using memory units (with RabbitMQ 3.6.0+).
-## Absolute watermark will be ignored if relative is defined!
-##
-# vm_memory_high_watermark.absolute = 2GB
-##
-## Supported units suffixes:
-##
-## kb, KB: kibibytes (2^10 bytes)
-## mb, MB: mebibytes (2^20)
-## gb, GB: gibibytes (2^30)
-
-
-
-## Fraction of the high watermark limit at which queues start to
-## page message out to disc in order to free up memory.
-##
-## Values greater than 0.9 can be dangerous and should be used carefully.
-##
-vm_memory_high_watermark_paging_ratio = 0.5
-
-## Interval (in milliseconds) at which we perform the check of the memory
-## levels against the watermarks.
-##
-memory_monitor_interval = 2500
-
-## Set disk free limit (in bytes). Once free disk space reaches this
-## lower bound, a disk alarm will be set - see the documentation
-## listed above for more details.
-##
-## Absolute watermark will be ignored if relative is defined!
-disk_free_limit.absolute = 50000
-
-## Or you can set it using memory units (same as in vm_memory_high_watermark)
-## with RabbitMQ 3.6.0+.
-# disk_free_limit.absolute = 500KB
-# disk_free_limit.absolute = 50mb
-# disk_free_limit.absolute = 5GB
-
-## Alternatively, we can set a limit relative to total available RAM.
-##
-## Values lower than 1.0 can be dangerous and should be used carefully.
-disk_free_limit.relative = 2.0
-
-##
-## Clustering
-## =====================
-##
-cluster_partition_handling = ignore
-
-## pause_if_all_down strategy require additional configuration
-# cluster_partition_handling = pause_if_all_down
-
-## Recover strategy. Can be either 'autoheal' or 'ignore'
-# cluster_partition_handling.pause_if_all_down.recover = ignore
-
-## Node names to check
-# cluster_partition_handling.pause_if_all_down.node.rabbit = rabbit@localhost
-# cluster_partition_handling.pause_if_all_down.node.hare = hare@localhost
-
-## Mirror sync batch size, in messages. Increasing this will speed
-## up syncing but total batch size in bytes must not exceed 2 GiB.
-## Available in RabbitMQ 3.6.0 or later.
-##
-mirroring_sync_batch_size = 4096
-
-## Make clustering happen *automatically* at startup - only applied
-## to nodes that have just been reset or started for the first time.
-## See http://www.rabbitmq.com/clustering.html#auto-config for
-## further details.
-##
-# cluster_nodes.disc.1 = rabbit@my.host.com
-
-## You can define multiple nodes
-# cluster_nodes.disc.2 = hare@my.host.com
-
-## There can be also ram nodes.
-## Ram nodes should not be defined together with disk nodes
-# cluster_nodes.ram.1 = rabbit@my.host.com
-
-## Interval (in milliseconds) at which we send keepalive messages
-## to other cluster members. Note that this is not the same thing
-## as net_ticktime; missed keepalive messages will not cause nodes
-## to be considered down.
-##
-# cluster_keepalive_interval = 10000
-
-##
-## Statistics Collection
-## =====================
-##
-
-## Set (internal) statistics collection granularity.
-##
-## Can be none, coarse or fine
-collect_statistics = none
-
-# collect_statistics = coarse
-
-## Statistics collection interval (in milliseconds). Increasing
-## this will reduce the load on management database.
-##
-collect_statistics_interval = 5000
-
-##
-## Misc/Advanced Options
-## =====================
-##
-## NB: Change these only if you understand what you are doing!
-##
-
-## Explicitly enable/disable hipe compilation.
-##
-hipe_compile = false
-
-## Timeout used when waiting for Mnesia tables in a cluster to
-## become available.
-##
-mnesia_table_loading_retry_timeout = 30000
-
-## Retries when waiting for Mnesia tables in the cluster startup. Note that
-## this setting is not applied to Mnesia upgrades or node deletions.
-##
-## mnesia_table_loading_retry_limit = 10
-
-## Size in bytes below which to embed messages in the queue index. See
-## http://www.rabbitmq.com/persistence-conf.html
-##
-queue_index_embed_msgs_below = 4096
-
-## You can also set this size in memory units
-##
-queue_index_embed_msgs_below = 4kb
-
-## ----------------------------------------------------------------------------
-## Advanced Erlang Networking/Clustering Options.
-##
-## See http://www.rabbitmq.com/clustering.html for details
-## ----------------------------------------------------------------------------
-
-# ======================================
-# Kernel section
-# ======================================
-
-# kernel.net_ticktime = 60
-
-## ----------------------------------------------------------------------------
-## RabbitMQ Management Plugin
-##
-## See http://www.rabbitmq.com/management.html for details
-## ----------------------------------------------------------------------------
-
-# =======================================
-# Management section
-# =======================================
-
-## Pre-Load schema definitions from the following JSON file. See
-## http://www.rabbitmq.com/management.html#load-definitions
-##
-# management.load_definitions = /path/to/schema.json
-
-## Log all requests to the management HTTP API to a file.
-##
-# management.http_log_dir = /path/to/access.log
-
-## Change the port on which the HTTP listener listens,
-## specifying an interface for the web server to bind to.
-## Also set the listener to use SSL and provide SSL options.
-##
-
-# QA: Maybe use IP type like in tcp_listener?
-management.listener.port = 12345
-management.listener.ip = 127.0.0.1
-# management.listener.ssl = true
-
-# management.listener.ssl_opts.cacertfile = /path/to/cacert.pem
-# management.listener.ssl_opts.certfile = /path/to/cert.pem
-# management.listener.ssl_opts.keyfile = /path/to/key.pem
-
-## One of 'basic', 'detailed' or 'none'. See
-## http://www.rabbitmq.com/management.html#fine-stats for more details.
-management.rates_mode = basic
-
-## Configure how long aggregated data (such as message rates and queue
-## lengths) is retained. Please read the plugin's documentation in
-## http://www.rabbitmq.com/management.html#configuration for more
-## details.
-## Your can use 'minute', 'hour' and '24hours' keys or integer key (in seconds)
-management.sample_retention_policies.global.minute = 5
-management.sample_retention_policies.global.hour = 60
-management.sample_retention_policies.global.day = 1200
-
-management.sample_retention_policies.basic.minute = 5
-management.sample_retention_policies.basic.hour = 60
-
-management.sample_retention_policies.detailed.10 = 5
-
-## ----------------------------------------------------------------------------
-## RabbitMQ Shovel Plugin
-##
-## See http://www.rabbitmq.com/shovel.html for details
-## ----------------------------------------------------------------------------
-
-## Shovel plugin config example is defined in additional.config file
-
-
-## ----------------------------------------------------------------------------
-## RabbitMQ Stomp Adapter
-##
-## See http://www.rabbitmq.com/stomp.html for details
-## ----------------------------------------------------------------------------
-
-# =======================================
-# STOMP section
-# =======================================
-
-## Network Configuration - the format is generally the same as for the broker
-##
-stomp.listener.tcp.default = 61613
-
-## Same for ssl listeners
-##
-# stomp.listener.ssl.default = 61614
-
-## Number of Erlang processes that will accept connections for the TCP
-## and SSL listeners.
-##
-stomp.num_acceptors.tcp = 10
-stomp.num_acceptors.ssl = 1
-
-## Additional SSL options
-
-## Extract a name from the client's certificate when using SSL.
-##
-stomp.ssl_cert_login = true
-
-## Set a default user name and password. This is used as the default login
-## whenever a CONNECT frame omits the login and passcode headers.
-##
-## Please note that setting this will allow clients to connect without
-## authenticating!
-##
-# stomp.default_user = guest
-# stomp.default_pass = guest
-
-## If a default user is configured, or you have configured use SSL client
-## certificate based authentication, you can choose to allow clients to
-## omit the CONNECT frame entirely. If set to true, the client is
-## automatically connected as the default user or user supplied in the
-## SSL certificate whenever the first frame sent on a session is not a
-## CONNECT frame.
-##
-# stomp.implicit_connect = true
-
-## ----------------------------------------------------------------------------
-## RabbitMQ MQTT Adapter
-##
-## See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md
-## for details
-## ----------------------------------------------------------------------------
-
-# =======================================
-# MQTT section
-# =======================================
-
-## Set the default user name and password. Will be used as the default login
-## if a connecting client provides no other login details.
-##
-## Please note that setting this will allow clients to connect without
-## authenticating!
-##
-# mqtt.default_user = guest
-# mqtt.default_pass = guest
-
-## Enable anonymous access. If this is set to false, clients MUST provide
-## login information in order to connect. See the default_user/default_pass
-## configuration elements for managing logins without authentication.
-##
-# mqtt.allow_anonymous = true
-
-## If you have multiple chosts, specify the one to which the
-## adapter connects.
-##
-mqtt.vhost = /
-
-## Specify the exchange to which messages from MQTT clients are published.
-##
-mqtt.exchange = amq.topic
-
-## Specify TTL (time to live) to control the lifetime of non-clean sessions.
-##
-# mqtt.subscription_ttl = 1800000
-
-## Set the prefetch count (governing the maximum number of unacknowledged
-## messages that will be delivered).
-##
-mqtt.prefetch = 10
-
-## TCP/SSL Configuration (as per the broker configuration).
-##
-mqtt.listener.tcp.default = 1883
-
-## Same for ssl listener
-##
-# mqtt.listener.ssl.default = 1884
-
-## Number of Erlang processes that will accept connections for the TCP
-## and SSL listeners.
-##
-mqtt.num_acceptors.tcp = 10
-mqtt.num_acceptors.ssl = 1
-
-## TCP/Socket options (as per the broker configuration).
-##
-# mqtt.tcp_listen_option.backlog = 128
-# mqtt.tcp_listen_option.nodelay = true
-
-## ----------------------------------------------------------------------------
-## RabbitMQ AMQP 1.0 Support
-##
-## See https://github.com/rabbitmq/rabbitmq-amqp1.0/blob/stable/README.md
-## for details
-## ----------------------------------------------------------------------------
-
-# =======================================
-# AMQP_1 section
-# =======================================
-
-
-## Connections that are not authenticated with SASL will connect as this
-## account. See the README for more information.
-##
-## Please note that setting this will allow clients to connect without
-## authenticating!
-##
-amqp1_0.default_user = guest
-
-## Enable protocol strict mode. See the README for more information.
-##
-amqp1_0.protocol_strict_mode = false
-
-## Lager controls logging.
-## See https://github.com/basho/lager for more documentation
-##
-## Log direcrory, taken from the RABBITMQ_LOG_BASE env variable by default.
-##
-# log.dir = /var/log/rabbitmq
-
-## Logging to console (can be true or false)
-##
-# log.console = false
-
-## Loglevel to log to console
-##
-# log.console.level = info
-
-## Logging to file. Can be false or filename.
-## Default:
-# log.file = rabbit.log
-
-## To turn off:
-# log.file = false
-
-## Loglevel to log to file
-##
-# log.file.level = info
-
-## File rotation config. No rotation by defualt.
-## DO NOT SET rotation date to ''. Leave unset if require "" value
-# log.file.rotation.date = $D0
-# log.file.rotation.size = 0
-
-
-## QA: Config for syslog logging
-# log.syslog = false
-# log.syslog.identity = rabbitmq
-# log.syslog.level = info
-# log.syslog.facility = daemon
-
-
-## ----------------------------------------------------------------------------
-## RabbitMQ LDAP Plugin
-##
-## See http://www.rabbitmq.com/ldap.html for details.
-##
-## ----------------------------------------------------------------------------
-
-# =======================================
-# LDAP section
-# =======================================
-
-##
-## Connecting to the LDAP server(s)
-## ================================
-##
-
-## Specify servers to bind to. You *must* set this in order for the plugin
-## to work properly.
-##
-# ldap.servers.1 = your-server-name-goes-here
-
-## You can define multiple servers
-# ldap.servers.2 = your-other-server
-
-## Connect to the LDAP server using SSL
-##
-# ldap.use_ssl = false
-
-## Specify the LDAP port to connect to
-##
-# ldap.port = 389
-
-## LDAP connection timeout, in milliseconds or 'infinity'
-##
-# ldap.timeout = infinity
-
-## Or number
-# ldap.timeout = 500
-
-## Enable logging of LDAP queries.
-## One of
-## - false (no logging is performed)
-## - true (verbose logging of the logic used by the plugin)
-## - network (as true, but additionally logs LDAP network traffic)
-##
-## Defaults to false.
-##
-# ldap.log = false
-
-## Also can be true or network
-# ldap.log = true
-# ldap.log = network
-
-##
-## Authentication
-## ==============
-##
-
-## Pattern to convert the username given through AMQP to a DN before
-## binding
-##
-# ldap.user_dn_pattern = cn=${username},ou=People,dc=example,dc=com
-
-## Alternatively, you can convert a username to a Distinguished
-## Name via an LDAP lookup after binding. See the documentation for
-## full details.
-
-## When converting a username to a dn via a lookup, set these to
-## the name of the attribute that represents the user name, and the
-## base DN for the lookup query.
-##
-# ldap.dn_lookup_attribute = userPrincipalName
-# ldap.dn_lookup_base = DC=gopivotal,DC=com
-
-## Controls how to bind for authorisation queries and also to
-## retrieve the details of users logging in without presenting a
-## password (e.g., SASL EXTERNAL).
-## One of
-## - as_user (to bind as the authenticated user - requires a password)
-## - anon (to bind anonymously)
-## - {UserDN, Password} (to bind with a specified user name and password)
-##
-## Defaults to 'as_user'.
-##
-# ldap.other_bind = as_user
-
-## Or can be more complex:
-# ldap.other_bind.user_dn = User
-# ldap.other_bind.password = Password
-
-## If user_dn and password defined - other options is ignored.
-
-# -----------------------------
-# Too complex section of LDAP
-# -----------------------------
-
-##
-## Authorisation
-## =============
-##
-
-## The LDAP plugin can perform a variety of queries against your
-## LDAP server to determine questions of authorisation. See
-## http://www.rabbitmq.com/ldap.html#authorisation for more
-## information.
-
-## Following configuration should be defined in additional.config file
-## DO NOT UNCOMMENT THIS LINES!
-
-## Set the query to use when determining vhost access
-##
-## {vhost_access_query, {in_group,
-## "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}},
-
-## Set the query to use when determining resource (e.g., queue) access
-##
-## {resource_access_query, {constant, true}},
-
-## Set queries to determine which tags a user has
-##
-## {tag_queries, []}
-# ]},
-# -----------------------------
diff --git a/scripts/rabbitmq-server.bat b/scripts/rabbitmq-server.bat
index 5da2ac5632..de25f95bdf 100644
--- a/scripts/rabbitmq-server.bat
+++ b/scripts/rabbitmq-server.bat
@@ -93,9 +93,9 @@ if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.config" (
)
) else if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.conf" (
set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE_NOEX!" ^
- -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_dir "!RABBITMQ_GENERATED_CONFIG_DIR!" ^
-conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
- -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ -conf_schema_dir "!RABBITMQ_SCHEMA_DIR!"
if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
-conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
@@ -106,9 +106,9 @@ if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.config" (
set RABBITMQ_CONFIG_ARG=-config "!RABBITMQ_CONFIG_FILE!"
) else if exist "!RABBITMQ_CONFIG_FILE!.conf" (
set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE!" ^
- -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_dir "!RABBITMQ_GENERATED_CONFIG_DIR!" ^
-conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
- -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ -conf_schema_dir "!RABBITMQ_SCHEMA_DIR!"
if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
-conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
diff --git a/scripts/rabbitmq-service.bat b/scripts/rabbitmq-service.bat
index 6390324f0c..624d18d913 100644
--- a/scripts/rabbitmq-service.bat
+++ b/scripts/rabbitmq-service.bat
@@ -182,9 +182,9 @@ if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.config" (
)
) else if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.conf" (
set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE_NOEX!" ^
- -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_dir "!RABBITMQ_GENERATED_CONFIG_DIR!" ^
-conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
- -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ -conf_schema_dir "!RABBITMQ_SCHEMA_DIR!"
if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
-conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
@@ -197,9 +197,9 @@ if "!RABBITMQ_CONFIG_FILE!" == "!RABBITMQ_CONFIG_FILE_NOEX!.config" (
rem Always specify generated config arguments, we cannot
rem assume .conf file is available
set RABBITMQ_CONFIG_ARG=-conf "!RABBITMQ_CONFIG_FILE!" ^
- -conf_dir !RABBITMQ_GENERATED_CONFIG_DIR! ^
+ -conf_dir "!RABBITMQ_GENERATED_CONFIG_DIR!" ^
-conf_script_dir !CONF_SCRIPT_DIR:\=/! ^
- -conf_schema_dir !RABBITMQ_SCHEMA_DIR!
+ -conf_schema_dir "!RABBITMQ_SCHEMA_DIR!"
if exist "!RABBITMQ_ADVANCED_CONFIG_FILE!.config" (
set RABBITMQ_CONFIG_ARG=!RABBITMQ_CONFIG_ARG! ^
-conf_advanced "!RABBITMQ_ADVANCED_CONFIG_FILE!" ^
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 588774a7a9..8498e54c09 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -95,8 +95,8 @@
[{description, "core metrics storage"},
{mfa, {rabbit_sup, start_child,
[rabbit_metrics]}},
- {requires, external_infrastructure},
- {enables, kernel_ready}]}).
+ {requires, pre_boot},
+ {enables, external_infrastructure}]}).
-rabbit_boot_step({rabbit_event,
[{description, "statistics event manager"},
diff --git a/src/rabbit_mirror_queue_sync.erl b/src/rabbit_mirror_queue_sync.erl
index d6357e0dc0..2994e8cbcf 100644
--- a/src/rabbit_mirror_queue_sync.erl
+++ b/src/rabbit_mirror_queue_sync.erl
@@ -37,7 +37,7 @@
%%
%% Master Syncer Slave(s)
%% sync_mirrors -> || ||
-%% (from channel) || -- (spawns) --> || ||
+%% || -- (spawns) --> || ||
%% || --------- sync_start (over GM) -------> ||
%% || || <--- sync_ready ---- ||
%% || || (or) ||
diff --git a/src/rabbit_priority_queue.erl b/src/rabbit_priority_queue.erl
index b7a3afd129..34e23260ba 100644
--- a/src/rabbit_priority_queue.erl
+++ b/src/rabbit_priority_queue.erl
@@ -657,7 +657,7 @@ cse(_, lazy) -> lazy;
cse(lazy, _) -> lazy;
%% numerical stats
cse(A, B) when is_number(A) -> A + B;
-cse({delta, _, _, _}, _) -> {delta, todo, todo, todo};
+cse({delta, _, _, _, _}, _) -> {delta, todo, todo, todo, todo};
cse(A, B) -> exit({A, B}).
%% When asked about 'head_message_timestamp' fro this priority queue, we
diff --git a/src/rabbit_ssl.erl b/src/rabbit_ssl.erl
index ac9fb204d0..6a87d93a29 100644
--- a/src/rabbit_ssl.erl
+++ b/src/rabbit_ssl.erl
@@ -11,13 +11,11 @@
%% The Original Code is RabbitMQ.
%%
%% The Initial Developer of the Original Code is GoPivotal, Inc.
-%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
+%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
%%
-module(rabbit_ssl).
--include("rabbit.hrl").
-
-include_lib("public_key/include/public_key.hrl").
-export([peer_cert_issuer/1, peer_cert_subject/1, peer_cert_validity/1]).
@@ -27,15 +25,7 @@
-export_type([certificate/0]).
--type certificate() :: binary().
-
--spec peer_cert_issuer(certificate()) -> string().
--spec peer_cert_subject(certificate()) -> string().
--spec peer_cert_validity(certificate()) -> string().
--spec peer_cert_subject_items
- (certificate(), tuple()) -> [string()] | 'not_found'.
--spec peer_cert_auth_name
- (certificate()) -> binary() | 'not_found' | 'unsafe'.
+-type certificate() :: rabbit_cert_info:certificate().
%%--------------------------------------------------------------------------
%% High-level functions used by reader
@@ -43,38 +33,24 @@
%% Return a string describing the certificate's issuer.
peer_cert_issuer(Cert) ->
- cert_info(fun(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- issuer = Issuer }}) ->
- format_rdn_sequence(Issuer)
- end, Cert).
+ rabbit_cert_info:issuer(Cert).
%% Return a string describing the certificate's subject, as per RFC4514.
peer_cert_subject(Cert) ->
- cert_info(fun(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- subject = Subject }}) ->
- format_rdn_sequence(Subject)
- end, Cert).
+ rabbit_cert_info:subject(Cert).
%% Return the parts of the certificate's subject.
peer_cert_subject_items(Cert, Type) ->
- cert_info(fun(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- subject = Subject }}) ->
- find_by_type(Type, Subject)
- end, Cert).
+ rabbit_cert_info:subject_items(Cert, Type).
%% Return a string describing the certificate's validity.
peer_cert_validity(Cert) ->
- cert_info(fun(#'OTPCertificate' {
- tbsCertificate = #'OTPTBSCertificate' {
- validity = {'Validity', Start, End} }}) ->
- rabbit_misc:format("~s - ~s", [format_asn1_value(Start),
- format_asn1_value(End)])
- end, Cert).
+ rabbit_cert_info:validity(Cert).
%% Extract a username from the certificate
+-spec peer_cert_auth_name
+ (certificate()) -> binary() | 'not_found' | 'unsafe'.
+
peer_cert_auth_name(Cert) ->
{ok, Mode} = application:get_env(rabbit, ssl_cert_login_from),
peer_cert_auth_name(Mode, Cert).
@@ -106,189 +82,3 @@ auth_config_sane() ->
"disabled, verify=~p~n", [V]),
false
end.
-
-%%--------------------------------------------------------------------------
-
-cert_info(F, Cert) ->
- F(case public_key:pkix_decode_cert(Cert, otp) of
- {ok, DecCert} -> DecCert; %%pre R14B
- DecCert -> DecCert %%R14B onwards
- end).
-
-find_by_type(Type, {rdnSequence, RDNs}) ->
- case [V || #'AttributeTypeAndValue'{type = T, value = V}
- <- lists:flatten(RDNs),
- T == Type] of
- [] -> not_found;
- L -> [format_asn1_value(V) || V <- L]
- end.
-
-%%--------------------------------------------------------------------------
-%% Formatting functions
-%%--------------------------------------------------------------------------
-
-%% Format and rdnSequence as a RFC4514 subject string.
-format_rdn_sequence({rdnSequence, Seq}) ->
- string:join(lists:reverse([format_complex_rdn(RDN) || RDN <- Seq]), ",").
-
-%% Format an RDN set.
-format_complex_rdn(RDNs) ->
- string:join([format_rdn(RDN) || RDN <- RDNs], "+").
-
-%% Format an RDN. If the type name is unknown, use the dotted decimal
-%% representation. See RFC4514, section 2.3.
-format_rdn(#'AttributeTypeAndValue'{type = T, value = V}) ->
- FV = escape_rdn_value(format_asn1_value(V)),
- Fmts = [{?'id-at-surname' , "SN"},
- {?'id-at-givenName' , "GIVENNAME"},
- {?'id-at-initials' , "INITIALS"},
- {?'id-at-generationQualifier' , "GENERATIONQUALIFIER"},
- {?'id-at-commonName' , "CN"},
- {?'id-at-localityName' , "L"},
- {?'id-at-stateOrProvinceName' , "ST"},
- {?'id-at-organizationName' , "O"},
- {?'id-at-organizationalUnitName' , "OU"},
- {?'id-at-title' , "TITLE"},
- {?'id-at-countryName' , "C"},
- {?'id-at-serialNumber' , "SERIALNUMBER"},
- {?'id-at-pseudonym' , "PSEUDONYM"},
- {?'id-domainComponent' , "DC"},
- {?'id-emailAddress' , "EMAILADDRESS"},
- {?'street-address' , "STREET"},
- {{0,9,2342,19200300,100,1,1} , "UID"}], %% Not in public_key.hrl
- case proplists:lookup(T, Fmts) of
- {_, Fmt} ->
- rabbit_misc:format(Fmt ++ "=~s", [FV]);
- none when is_tuple(T) ->
- TypeL = [rabbit_misc:format("~w", [X]) || X <- tuple_to_list(T)],
- rabbit_misc:format("~s=~s", [string:join(TypeL, "."), FV]);
- none ->
- rabbit_misc:format("~p=~s", [T, FV])
- end.
-
-%% Escape a string as per RFC4514.
-escape_rdn_value(V) ->
- escape_rdn_value(V, start).
-
-escape_rdn_value([], _) ->
- [];
-escape_rdn_value([C | S], start) when C =:= $ ; C =:= $# ->
- [$\\, C | escape_rdn_value(S, middle)];
-escape_rdn_value(S, start) ->
- escape_rdn_value(S, middle);
-escape_rdn_value([$ ], middle) ->
- [$\\, $ ];
-escape_rdn_value([C | S], middle) when C =:= $"; C =:= $+; C =:= $,; C =:= $;;
- C =:= $<; C =:= $>; C =:= $\\ ->
- [$\\, C | escape_rdn_value(S, middle)];
-escape_rdn_value([C | S], middle) when C < 32 ; C >= 126 ->
- %% Of ASCII characters only U+0000 needs escaping, but for display
- %% purposes it's handy to escape all non-printable chars. All non-ASCII
- %% characters get converted to UTF-8 sequences and then escaped. We've
- %% already got a UTF-8 sequence here, so just escape it.
- rabbit_misc:format("\\~2.16.0B", [C]) ++ escape_rdn_value(S, middle);
-escape_rdn_value([C | S], middle) ->
- [C | escape_rdn_value(S, middle)].
-
-%% Get the string representation of an OTPCertificate field.
-format_asn1_value({ST, S}) when ST =:= teletexString; ST =:= printableString;
- ST =:= universalString; ST =:= utf8String;
- ST =:= bmpString ->
- format_directory_string(ST, S);
-format_asn1_value({utcTime, [Y1, Y2, M1, M2, D1, D2, H1, H2,
- Min1, Min2, S1, S2, $Z]}) ->
- rabbit_misc:format("20~c~c-~c~c-~c~cT~c~c:~c~c:~c~cZ",
- [Y1, Y2, M1, M2, D1, D2, H1, H2, Min1, Min2, S1, S2]);
-%% We appear to get an untagged value back for an ia5string
-%% (e.g. domainComponent).
-format_asn1_value(V) when is_list(V) ->
- V;
-format_asn1_value(V) when is_binary(V) ->
- %% OTP does not decode some values when combined with an unknown
- %% type. That's probably wrong, so as a last ditch effort let's
- %% try manually decoding. 'DirectoryString' is semi-arbitrary -
- %% but it is the type which covers the various string types we
- %% handle below.
- try
- {ST, S} = public_key:der_decode('DirectoryString', V),
- format_directory_string(ST, S)
- catch _:_ ->
- rabbit_misc:format("~p", [V])
- end;
-format_asn1_value(V) ->
- rabbit_misc:format("~p", [V]).
-
-%% DirectoryString { INTEGER : maxSize } ::= CHOICE {
-%% teletexString TeletexString (SIZE (1..maxSize)),
-%% printableString PrintableString (SIZE (1..maxSize)),
-%% bmpString BMPString (SIZE (1..maxSize)),
-%% universalString UniversalString (SIZE (1..maxSize)),
-%% uTF8String UTF8String (SIZE (1..maxSize)) }
-%%
-%% Precise definitions of printable / teletexString are hard to come
-%% by. This is what I reconstructed:
-%%
-%% printableString:
-%% "intended to represent the limited character sets available to
-%% mainframe input terminals"
-%% A-Z a-z 0-9 ' ( ) + , - . / : = ? [space]
-%% http://msdn.microsoft.com/en-us/library/bb540814(v=vs.85).aspx
-%%
-%% teletexString:
-%% "a sizable volume of software in the world treats TeletexString
-%% (T61String) as a simple 8-bit string with mostly Windows Latin 1
-%% (superset of iso-8859-1) encoding"
-%% http://www.mail-archive.com/asn1@asn1.org/msg00460.html
-%%
-%% (However according to that link X.680 actually defines
-%% TeletexString in some much more involved and crazy way. I suggest
-%% we treat it as ISO-8859-1 since Erlang does not support Windows
-%% Latin 1).
-%%
-%% bmpString:
-%% UCS-2 according to RFC 3641. Hence cannot represent Unicode
-%% characters above 65535 (outside the "Basic Multilingual Plane").
-%%
-%% universalString:
-%% UCS-4 according to RFC 3641.
-%%
-%% utf8String:
-%% UTF-8 according to RFC 3641.
-%%
-%% Within Rabbit we assume UTF-8 encoding. Since printableString is a
-%% subset of ASCII it is also a subset of UTF-8. The others need
-%% converting. Fortunately since the Erlang SSL library does the
-%% decoding for us (albeit into a weird format, see below), we just
-%% need to handle encoding into UTF-8. Note also that utf8Strings come
-%% back as binary.
-%%
-%% Note for testing: the default Ubuntu configuration for openssl will
-%% only create printableString or teletexString types no matter what
-%% you do. Edit string_mask in the [req] section of
-%% /etc/ssl/openssl.cnf to change this (see comments there). You
-%% probably also need to set utf8 = yes to get it to accept UTF-8 on
-%% the command line. Also note I could not get openssl to generate a
-%% universalString.
-
-format_directory_string(printableString, S) -> S;
-format_directory_string(teletexString, S) -> utf8_list_from(S);
-format_directory_string(bmpString, S) -> utf8_list_from(S);
-format_directory_string(universalString, S) -> utf8_list_from(S);
-format_directory_string(utf8String, S) -> binary_to_list(S).
-
-utf8_list_from(S) ->
- binary_to_list(
- unicode:characters_to_binary(flatten_ssl_list(S), utf32, utf8)).
-
-%% The Erlang SSL implementation invents its own representation for
-%% non-ascii strings - looking like [97,{0,0,3,187}] (that's LATIN
-%% SMALL LETTER A followed by GREEK SMALL LETTER LAMDA). We convert
-%% this into a list of unicode characters, which we can tell
-%% unicode:characters_to_binary is utf32.
-
-flatten_ssl_list(L) -> [flatten_ssl_list_item(I) || I <- L].
-
-flatten_ssl_list_item({A, B, C, D}) ->
- A * (1 bsl 24) + B * (1 bsl 16) + C * (1 bsl 8) + D;
-flatten_ssl_list_item(N) when is_number (N) ->
- N.
diff --git a/src/rabbit_table.erl b/src/rabbit_table.erl
index 040075ea87..56a9c2b578 100644
--- a/src/rabbit_table.erl
+++ b/src/rabbit_table.erl
@@ -280,7 +280,7 @@ definitions() ->
{attributes, record_info(fields, topic_permission)},
{disc_copies, [node()]},
{match, #topic_permission{topic_permission_key = #topic_permission_key{_='_'},
- pattern = '_',
+ permission = #permission{_='_'},
_='_'}}]},
{rabbit_vhost,
[{record_name, vhost},
diff --git a/src/rabbit_upgrade_functions.erl b/src/rabbit_upgrade_functions.erl
index 0dcf84af6e..2116e2dfa1 100644
--- a/src/rabbit_upgrade_functions.erl
+++ b/src/rabbit_upgrade_functions.erl
@@ -591,7 +591,7 @@ user_password_hashing() ->
topic_permission() ->
create(rabbit_topic_permission,
[{record_name, topic_permission},
- {attributes, [topic_permission_key, pattern]},
+ {attributes, [topic_permission_key, permission]},
{disc_copies, [node()]}]).
exchange_options() ->
diff --git a/src/rabbit_variable_queue.erl b/src/rabbit_variable_queue.erl
index 5581143e69..c42b4856f2 100644
--- a/src/rabbit_variable_queue.erl
+++ b/src/rabbit_variable_queue.erl
@@ -292,6 +292,7 @@
unacked_bytes,
persistent_count, %% w unacked
persistent_bytes, %% w unacked
+ delta_transient_bytes, %%
target_ram_count,
ram_msg_count, %% w/o unacked
@@ -339,6 +340,7 @@
-record(delta,
{ start_seq_id, %% start_seq_id is inclusive
count,
+ transient,
end_seq_id %% end_seq_id is exclusive
}).
@@ -430,9 +432,11 @@
-define(BLANK_DELTA, #delta { start_seq_id = undefined,
count = 0,
+ transient = 0,
end_seq_id = undefined }).
-define(BLANK_DELTA_PATTERN(Z), #delta { start_seq_id = Z,
count = 0,
+ transient = 0,
end_seq_id = Z }).
-define(MICROS_PER_SECOND, 1000000.0).
@@ -933,6 +937,8 @@ info(messages_ram, State) ->
info(messages_ready_ram, State) + info(messages_unacknowledged_ram, State);
info(messages_persistent, #vqstate{persistent_count = PersistentCount}) ->
PersistentCount;
+info(messages_paged_out, #vqstate{delta = #delta{transient = Count}}) ->
+ Count;
info(message_bytes, #vqstate{bytes = Bytes,
unacked_bytes = UBytes}) ->
Bytes + UBytes;
@@ -944,6 +950,8 @@ info(message_bytes_ram, #vqstate{ram_bytes = RamBytes}) ->
RamBytes;
info(message_bytes_persistent, #vqstate{persistent_bytes = PersistentBytes}) ->
PersistentBytes;
+info(message_bytes_paged_out, #vqstate{delta_transient_bytes = PagedOutBytes}) ->
+ PagedOutBytes;
info(head_message_timestamp, #vqstate{
q3 = Q3,
q4 = Q4,
@@ -1303,14 +1311,14 @@ maybe_write_delivered(true, SeqId, IndexState) ->
rabbit_queue_index:deliver([SeqId], IndexState).
betas_from_index_entries(List, TransientThreshold, DelsAndAcksFun, State) ->
- {Filtered, Delivers, Acks, RamReadyCount, RamBytes} =
+ {Filtered, Delivers, Acks, RamReadyCount, RamBytes, TransientCount, TransientBytes} =
lists:foldr(
fun ({_MsgOrId, SeqId, _MsgProps, IsPersistent, IsDelivered} = M,
- {Filtered1, Delivers1, Acks1, RRC, RB} = Acc) ->
+ {Filtered1, Delivers1, Acks1, RRC, RB, TC, TB} = Acc) ->
case SeqId < TransientThreshold andalso not IsPersistent of
true -> {Filtered1,
cons_if(not IsDelivered, SeqId, Delivers1),
- [SeqId | Acks1], RRC, RB};
+ [SeqId | Acks1], RRC, RB, TC, TB};
false -> MsgStatus = m(beta_msg_status(M)),
HaveMsg = msg_in_ram(MsgStatus),
Size = msg_size(MsgStatus),
@@ -1318,12 +1326,15 @@ betas_from_index_entries(List, TransientThreshold, DelsAndAcksFun, State) ->
false -> {?QUEUE:in_r(MsgStatus, Filtered1),
Delivers1, Acks1,
RRC + one_if(HaveMsg),
- RB + one_if(HaveMsg) * Size};
+ RB + one_if(HaveMsg) * Size,
+ TC + one_if(not IsPersistent),
+ TB + one_if(not IsPersistent) * Size};
true -> Acc %% [0]
end
end
- end, {?QUEUE:new(), [], [], 0, 0}, List),
- {Filtered, RamReadyCount, RamBytes, DelsAndAcksFun(Delivers, Acks, State)}.
+ end, {?QUEUE:new(), [], [], 0, 0, 0, 0}, List),
+ {Filtered, RamReadyCount, RamBytes, DelsAndAcksFun(Delivers, Acks, State),
+ TransientCount, TransientBytes}.
%% [0] We don't increase RamBytes here, even though it pertains to
%% unacked messages too, since if HaveMsg then the message must have
%% been stored in the QI, thus the message must have been in
@@ -1336,18 +1347,28 @@ is_msg_in_pending_acks(SeqId, #vqstate { ram_pending_ack = RPA,
gb_trees:is_defined(SeqId, DPA) orelse
gb_trees:is_defined(SeqId, QPA)).
-expand_delta(SeqId, ?BLANK_DELTA_PATTERN(X)) ->
- d(#delta { start_seq_id = SeqId, count = 1, end_seq_id = SeqId + 1 });
+expand_delta(SeqId, ?BLANK_DELTA_PATTERN(X), IsPersistent) ->
+ d(#delta { start_seq_id = SeqId, count = 1, end_seq_id = SeqId + 1,
+ transient = one_if(not IsPersistent)});
expand_delta(SeqId, #delta { start_seq_id = StartSeqId,
- count = Count } = Delta)
+ count = Count,
+ transient = Transient } = Delta,
+ IsPersistent )
when SeqId < StartSeqId ->
- d(Delta #delta { start_seq_id = SeqId, count = Count + 1 });
+ d(Delta #delta { start_seq_id = SeqId, count = Count + 1,
+ transient = Transient + one_if(not IsPersistent)});
expand_delta(SeqId, #delta { count = Count,
- end_seq_id = EndSeqId } = Delta)
+ end_seq_id = EndSeqId,
+ transient = Transient } = Delta,
+ IsPersistent)
when SeqId >= EndSeqId ->
- d(Delta #delta { count = Count + 1, end_seq_id = SeqId + 1 });
-expand_delta(_SeqId, #delta { count = Count } = Delta) ->
- d(Delta #delta { count = Count + 1 }).
+ d(Delta #delta { count = Count + 1, end_seq_id = SeqId + 1,
+ transient = Transient + one_if(not IsPersistent)});
+expand_delta(_SeqId, #delta { count = Count,
+ transient = Transient } = Delta,
+ IsPersistent ) ->
+ d(Delta #delta { count = Count + 1,
+ transient = Transient + one_if(not IsPersistent) }).
%%----------------------------------------------------------------------------
%% Internal major helpers for Public API
@@ -1369,6 +1390,7 @@ init(IsDurable, IndexState, DeltaCount, DeltaBytes, Terms,
true -> ?BLANK_DELTA;
false -> d(#delta { start_seq_id = LowSeqId,
count = DeltaCount1,
+ transient = 0,
end_seq_id = NextSeqId })
end,
Now = erlang:monotonic_time(),
@@ -1397,6 +1419,7 @@ init(IsDurable, IndexState, DeltaCount, DeltaBytes, Terms,
persistent_count = DeltaCount1,
bytes = DeltaBytes1,
persistent_bytes = DeltaBytes1,
+ delta_transient_bytes = 0,
target_ram_count = infinity,
ram_msg_count = 0,
@@ -1436,22 +1459,22 @@ in_r(MsgStatus = #msg_status { msg = undefined },
false -> {Msg, State1 = #vqstate { q4 = Q4a }} =
read_msg(MsgStatus, State),
MsgStatus1 = MsgStatus#msg_status{msg = Msg},
- stats(ready0, {MsgStatus, MsgStatus1},
+ stats(ready0, {MsgStatus, MsgStatus1}, 0,
State1 #vqstate { q4 = ?QUEUE:in_r(MsgStatus1, Q4a) })
end;
in_r(MsgStatus,
State = #vqstate { mode = default, q4 = Q4 }) ->
State #vqstate { q4 = ?QUEUE:in_r(MsgStatus, Q4) };
%% lazy queues
-in_r(MsgStatus = #msg_status { seq_id = SeqId },
+in_r(MsgStatus = #msg_status { seq_id = SeqId, is_persistent = IsPersistent },
State = #vqstate { mode = lazy, q3 = Q3, delta = Delta}) ->
case ?QUEUE:is_empty(Q3) of
true ->
{_MsgStatus1, State1} =
maybe_write_to_disk(true, true, MsgStatus, State),
- State2 = stats(ready0, {MsgStatus, none}, State1),
- Delta1 = expand_delta(SeqId, Delta),
- State2 #vqstate{ delta = Delta1 };
+ State2 = stats(ready0, {MsgStatus, none}, 1, State1),
+ Delta1 = expand_delta(SeqId, Delta, IsPersistent),
+ State2 #vqstate{ delta = Delta1};
false ->
State #vqstate { q3 = ?QUEUE:in_r(MsgStatus, Q3) }
end.
@@ -1487,8 +1510,8 @@ read_msg(MsgId, IsPersistent, State = #vqstate{msg_store_clients = MSCState,
{Msg, State #vqstate {msg_store_clients = MSCState1,
disk_read_count = Count + 1}}.
-stats(Signs, Statuses, State) ->
- stats0(expand_signs(Signs), expand_statuses(Statuses), State).
+stats(Signs, Statuses, DeltaPaged, State) ->
+ stats0(expand_signs(Signs), expand_statuses(Statuses), DeltaPaged, State).
expand_signs(ready0) -> {0, 0, true};
expand_signs(lazy_pub) -> {1, 0, true};
@@ -1503,13 +1526,14 @@ expand_statuses({B, A}) -> {msg_in_ram(B), msg_in_ram(A), B}.
%% contains "Ready" or "Unacked" iff that is what it counts. If
%% neither is present it counts both.
stats0({DeltaReady, DeltaUnacked, ReadyMsgPaged},
- {InRamBefore, InRamAfter, MsgStatus},
+ {InRamBefore, InRamAfter, MsgStatus}, DeltaPaged,
State = #vqstate{len = ReadyCount,
bytes = ReadyBytes,
ram_msg_count = RamReadyCount,
persistent_count = PersistentCount,
unacked_bytes = UnackedBytes,
ram_bytes = RamBytes,
+ delta_transient_bytes = DeltaBytes,
persistent_bytes = PersistentBytes}) ->
S = msg_size(MsgStatus),
DeltaTotal = DeltaReady + DeltaUnacked,
@@ -1532,7 +1556,8 @@ stats0({DeltaReady, DeltaUnacked, ReadyMsgPaged},
bytes = ReadyBytes + DeltaReady * S,
unacked_bytes = UnackedBytes + DeltaUnacked * S,
ram_bytes = RamBytes + DeltaRam * S,
- persistent_bytes = PersistentBytes + DeltaPersistent * S}.
+ persistent_bytes = PersistentBytes + DeltaPersistent * S,
+ delta_transient_bytes = DeltaBytes + DeltaPaged * one_if(not MsgStatus#msg_status.is_persistent) * S}.
msg_size(#msg_status{msg_props = #message_properties{size = Size}}) -> Size.
@@ -1554,7 +1579,7 @@ remove(true, MsgStatus = #msg_status {
MsgStatus #msg_status {
is_delivered = true }, State),
- State2 = stats({-1, 1}, {MsgStatus, MsgStatus}, State1),
+ State2 = stats({-1, 1}, {MsgStatus, MsgStatus}, 0, State1),
{SeqId, maybe_update_rates(
State2 #vqstate {out_counter = OutCount + 1,
@@ -1590,7 +1615,7 @@ remove(false, MsgStatus = #msg_status {
false -> IndexState1
end,
- State1 = stats({-1, 0}, {MsgStatus, none}, State),
+ State1 = stats({-1, 0}, {MsgStatus, none}, 0, State),
{undefined, maybe_update_rates(
State1 #vqstate {out_counter = OutCount + 1,
@@ -1674,7 +1699,7 @@ process_queue_entries1(
is_delivered = true }, State1),
{cons_if(IndexOnDisk andalso not IsDelivered, SeqId, Delivers),
Fun(Msg, SeqId, FetchAcc),
- stats({-1, 1}, {MsgStatus, MsgStatus}, State2)}.
+ stats({-1, 1}, {MsgStatus, MsgStatus}, 0, State2)}.
collect_by_predicate(Pred, QAcc, State) ->
case queue_out(State) of
@@ -1776,7 +1801,7 @@ remove_queue_entries1(
end,
cons_if(IndexOnDisk andalso not IsDelivered, SeqId, Delivers),
cons_if(IndexOnDisk, SeqId, Acks),
- stats({-1, 0}, {MsgStatus, none}, State)}.
+ stats({-1, 0}, {MsgStatus, none}, 0, State)}.
process_delivers_and_acks_fun(deliver_and_ack) ->
fun (Delivers, Acks, State = #vqstate { index_state = IndexState }) ->
@@ -1813,7 +1838,7 @@ publish1(Msg = #basic_message { is_persistent = IsPersistent, id = MsgId },
end,
InCount1 = InCount + 1,
UC1 = gb_sets_maybe_insert(NeedsConfirming, MsgId, UC),
- stats({1, 0}, {none, MsgStatus1},
+ stats({1, 0}, {none, MsgStatus1}, 0,
State2#vqstate{ next_seq_id = SeqId + 1,
in_counter = InCount1,
unconfirmed = UC1 });
@@ -1826,17 +1851,17 @@ publish1(Msg = #basic_message { is_persistent = IsPersistent, id = MsgId },
in_counter = InCount,
durable = IsDurable,
unconfirmed = UC,
- delta = Delta }) ->
+ delta = Delta}) ->
IsPersistent1 = IsDurable andalso IsPersistent,
MsgStatus = msg_status(IsPersistent1, IsDelivered, SeqId, Msg, MsgProps, IndexMaxSize),
{MsgStatus1, State1} = PersistFun(true, true, MsgStatus, State),
- Delta1 = expand_delta(SeqId, Delta),
+ Delta1 = expand_delta(SeqId, Delta, IsPersistent),
UC1 = gb_sets_maybe_insert(NeedsConfirming, MsgId, UC),
- stats(lazy_pub, {lazy, m(MsgStatus1)},
+ stats(lazy_pub, {lazy, m(MsgStatus1)}, 1,
State1#vqstate{ delta = Delta1,
next_seq_id = SeqId + 1,
in_counter = InCount + 1,
- unconfirmed = UC1 }).
+ unconfirmed = UC1}).
batch_publish1({Msg, MsgProps, IsDelivered}, {ChPid, Flow, State}) ->
{ChPid, Flow, publish1(Msg, MsgProps, IsDelivered, ChPid, Flow,
@@ -1859,7 +1884,7 @@ publish_delivered1(Msg = #basic_message { is_persistent = IsPersistent,
{MsgStatus1, State1} = PersistFun(false, false, MsgStatus, State),
State2 = record_pending_ack(m(MsgStatus1), State1),
UC1 = gb_sets_maybe_insert(NeedsConfirming, MsgId, UC),
- State3 = stats({0, 1}, {none, MsgStatus1},
+ State3 = stats({0, 1}, {none, MsgStatus1}, 0,
State2 #vqstate { next_seq_id = SeqId + 1,
out_counter = OutCount + 1,
in_counter = InCount + 1,
@@ -1882,7 +1907,7 @@ publish_delivered1(Msg = #basic_message { is_persistent = IsPersistent,
{MsgStatus1, State1} = PersistFun(true, true, MsgStatus, State),
State2 = record_pending_ack(m(MsgStatus1), State1),
UC1 = gb_sets_maybe_insert(NeedsConfirming, MsgId, UC),
- State3 = stats({0, 1}, {none, MsgStatus1},
+ State3 = stats({0, 1}, {none, MsgStatus1}, 0,
State2 #vqstate { next_seq_id = SeqId + 1,
out_counter = OutCount + 1,
in_counter = InCount + 1,
@@ -2070,7 +2095,7 @@ remove_pending_ack(true, SeqId, State) ->
{none, _} ->
{none, State};
{MsgStatus, State1} ->
- {MsgStatus, stats({0, -1}, {MsgStatus, none}, State1)}
+ {MsgStatus, stats({0, -1}, {MsgStatus, none}, 0, State1)}
end;
remove_pending_ack(false, SeqId, State = #vqstate{ram_pending_ack = RPA,
disk_pending_ack = DPA,
@@ -2215,14 +2240,14 @@ msgs_and_indices_written_to_disk(Callback, MsgIdSet) ->
publish_alpha(#msg_status { msg = undefined } = MsgStatus, State) ->
{Msg, State1} = read_msg(MsgStatus, State),
MsgStatus1 = MsgStatus#msg_status { msg = Msg },
- {MsgStatus1, stats({1, -1}, {MsgStatus, MsgStatus1}, State1)};
+ {MsgStatus1, stats({1, -1}, {MsgStatus, MsgStatus1}, 0, State1)};
publish_alpha(MsgStatus, State) ->
- {MsgStatus, stats({1, -1}, {MsgStatus, MsgStatus}, State)}.
+ {MsgStatus, stats({1, -1}, {MsgStatus, MsgStatus}, 0, State)}.
publish_beta(MsgStatus, State) ->
{MsgStatus1, State1} = maybe_prepare_write_to_disk(true, false, MsgStatus, State),
MsgStatus2 = m(trim_msg_status(MsgStatus1)),
- {MsgStatus2, stats({1, -1}, {MsgStatus, MsgStatus2}, State1)}.
+ {MsgStatus2, stats({1, -1}, {MsgStatus, MsgStatus2}, 0, State1)}.
%% Rebuild queue, inserting sequence ids to maintain ordering
queue_merge(SeqIds, Q, MsgIds, Limit, PubFun, State) ->
@@ -2261,11 +2286,12 @@ delta_merge(SeqIds, Delta, MsgIds, State) ->
case msg_from_pending_ack(SeqId, State0) of
{none, _} ->
Acc;
- {#msg_status { msg_id = MsgId } = MsgStatus, State1} ->
+ {#msg_status { msg_id = MsgId,
+ is_persistent = IsPersistent } = MsgStatus, State1} ->
{_MsgStatus, State2} =
maybe_prepare_write_to_disk(true, true, MsgStatus, State1),
- {expand_delta(SeqId, Delta0), [MsgId | MsgIds0],
- stats({1, -1}, {MsgStatus, none}, State2)}
+ {expand_delta(SeqId, Delta0, IsPersistent), [MsgId | MsgIds0],
+ stats({1, -1}, {MsgStatus, none}, 1, State2)}
end
end, {Delta, MsgIds, State}, SeqIds).
@@ -2467,7 +2493,7 @@ limit_ram_acks(Quota, State = #vqstate { ram_pending_ack = RPA,
MsgStatus2 = m(trim_msg_status(MsgStatus1)),
DPA1 = gb_trees:insert(SeqId, MsgStatus2, DPA),
limit_ram_acks(Quota - 1,
- stats({0, 0}, {MsgStatus, MsgStatus2},
+ stats({0, 0}, {MsgStatus, MsgStatus2}, 0,
State1 #vqstate { ram_pending_ack = RPA1,
disk_pending_ack = DPA1 }))
end.
@@ -2556,16 +2582,18 @@ maybe_deltas_to_betas(DelsAndAcksFun,
ram_msg_count = RamMsgCount,
ram_bytes = RamBytes,
disk_read_count = DiskReadCount,
+ delta_transient_bytes = DeltaTransientBytes,
transient_threshold = TransientThreshold }) ->
#delta { start_seq_id = DeltaSeqId,
count = DeltaCount,
+ transient = Transient,
end_seq_id = DeltaSeqIdEnd } = Delta,
DeltaSeqId1 =
lists:min([rabbit_queue_index:next_segment_boundary(DeltaSeqId),
DeltaSeqIdEnd]),
{List, IndexState1} = rabbit_queue_index:read(DeltaSeqId, DeltaSeqId1,
IndexState),
- {Q3a, RamCountsInc, RamBytesInc, State1} =
+ {Q3a, RamCountsInc, RamBytesInc, State1, TransientCount, TransientBytes} =
betas_from_index_entries(List, TransientThreshold,
DelsAndAcksFun,
State #vqstate { index_state = IndexState1 }),
@@ -2588,13 +2616,16 @@ maybe_deltas_to_betas(DelsAndAcksFun,
%% can now join q2 onto q3
State2 #vqstate { q2 = ?QUEUE:new(),
delta = ?BLANK_DELTA,
- q3 = ?QUEUE:join(Q3b, Q2) };
+ q3 = ?QUEUE:join(Q3b, Q2),
+ delta_transient_bytes = 0};
N when N > 0 ->
Delta1 = d(#delta { start_seq_id = DeltaSeqId1,
count = N,
+ transient = Transient - TransientCount,
end_seq_id = DeltaSeqIdEnd }),
State2 #vqstate { delta = Delta1,
- q3 = Q3b }
+ q3 = Q3b,
+ delta_transient_bytes = DeltaTransientBytes - TransientBytes }
end
end.
@@ -2603,7 +2634,8 @@ push_alphas_to_betas(Quota, State) ->
push_alphas_to_betas(
fun ?QUEUE:out/1,
fun (MsgStatus, Q1a,
- State0 = #vqstate { q3 = Q3, delta = #delta { count = 0 } }) ->
+ State0 = #vqstate { q3 = Q3, delta = #delta { count = 0,
+ transient = 0 } }) ->
State0 #vqstate { q1 = Q1a, q3 = ?QUEUE:in(MsgStatus, Q3) };
(MsgStatus, Q1a, State0 = #vqstate { q2 = Q2 }) ->
State0 #vqstate { q1 = Q1a, q2 = ?QUEUE:in(MsgStatus, Q2) }
@@ -2639,7 +2671,7 @@ push_alphas_to_betas(Generator, Consumer, Quota, Q, State) ->
State),
MsgStatus2 = m(trim_msg_status(MsgStatus1)),
State2 = stats(
- ready0, {MsgStatus, MsgStatus2}, State1),
+ ready0, {MsgStatus, MsgStatus2}, 0, State1),
State3 = Consumer(MsgStatus2, Qa, State2),
push_alphas_to_betas(Generator, Consumer, Quota - 1,
Qa, State3)
@@ -2702,10 +2734,11 @@ push_betas_to_deltas1(Generator, Limit, Q, {Quota, Delta, State}) ->
when SeqId < Limit ->
{Q, {Quota, Delta, ui(State)}};
{{value, MsgStatus = #msg_status { seq_id = SeqId }}, Qa} ->
- {#msg_status { index_on_disk = true }, State1} =
+ {#msg_status { index_on_disk = true,
+ is_persistent = IsPersistent }, State1} =
maybe_batch_write_index_to_disk(true, MsgStatus, State),
- State2 = stats(ready0, {MsgStatus, none}, State1),
- Delta1 = expand_delta(SeqId, Delta),
+ State2 = stats(ready0, {MsgStatus, none}, 1, State1),
+ Delta1 = expand_delta(SeqId, Delta, IsPersistent),
push_betas_to_deltas1(Generator, Limit, Qa,
{Quota - 1, Delta1, State2})
end.
diff --git a/test/config_schema_SUITE_data/snippets.config b/test/config_schema_SUITE_data/snippets.config
index 7a854a10e1..9fb0b7519b 100644
--- a/test/config_schema_SUITE_data/snippets.config
+++ b/test/config_schema_SUITE_data/snippets.config
@@ -50,7 +50,12 @@ auth_backends.2 = internal",
]
}],[]}
,
-
+{7.1,
+"auth_backends.1.authn = ldap",
+[{rabbit, [
+ {auth_backends, [{rabbit_auth_backend_ldap, rabbit_auth_backend_ldap}]}
+ ]
+ }],[]},
{8,
"ssl_options.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
@@ -134,41 +139,47 @@ auth_backends.2 = internal",
[{rabbit,[{auth_backends, [{rabbit_auth_backend_ldap, rabbit_auth_backend_internal},
rabbit_auth_backend_internal]}]}],[]}
,
-{16,
-"rabbitmq_auth_backend_ldap.servers.1 = some_server
- rabbitmq_auth_backend_ldap.servers.2 = some_other_server",
-[{rabbitmq_auth_backend_ldap, [{servers, ["some_server", "some_other_server"]}]}],
+{16.1,
+"auth_ldap.servers.1 = DC1.domain.com
+ auth_ldap.servers.2 = DC1.eng.domain.com",
+[{rabbitmq_auth_backend_ldap, [{servers, ["DC1.domain.com", "DC1.eng.domain.com"]}]}],
+[rabbitmq_auth_backend_ldap]}
+,
+{16.2,
+"auth_ldap.servers.1 = hostname1
+ auth_ldap.servers.2 = hostname2",
+[{rabbitmq_auth_backend_ldap, [{servers, ["hostname1", "hostname2"]}]}],
[rabbitmq_auth_backend_ldap]}
,
{17,
-"rabbitmq_auth_backend_ldap.dn_lookup_attribute = userPrincipalName
-rabbitmq_auth_backend_ldap.dn_lookup_base = DC=gopivotal,DC=com
-rabbitmq_auth_backend_ldap.dn_lookup_bind = as_user",
+"auth_ldap.dn_lookup_attribute = userPrincipalName
+auth_ldap.dn_lookup_base = DC=gopivotal,DC=com
+auth_ldap.dn_lookup_bind = as_user",
[{rabbitmq_auth_backend_ldap, [{dn_lookup_attribute, "userPrincipalName"},
{dn_lookup_base, "DC=gopivotal,DC=com"},
{dn_lookup_bind, as_user}]}],
[rabbitmq_auth_backend_ldap]}
,
{18,
-"rabbitmq_auth_backend_ldap.dn_lookup_bind.user_dn = username
-rabbitmq_auth_backend_ldap.dn_lookup_bind.password = password",
+"auth_ldap.dn_lookup_bind.user_dn = username
+auth_ldap.dn_lookup_bind.password = password",
[{rabbitmq_auth_backend_ldap, [
{dn_lookup_bind, {"username", "password"}}]}],
[rabbitmq_auth_backend_ldap]}
,
{19,
-"rabbitmq_auth_backend_ldap.other_bind = anon",
+"auth_ldap.other_bind = anon",
[{rabbitmq_auth_backend_ldap, [{other_bind, anon}]}],
[rabbitmq_auth_backend_ldap]}
,
{20,
-"rabbitmq_auth_backend_ldap.other_bind = as_user",
+"auth_ldap.other_bind = as_user",
[{rabbitmq_auth_backend_ldap, [{other_bind, as_user}]}],
[rabbitmq_auth_backend_ldap]}
,
{21,
-"rabbitmq_auth_backend_ldap.other_bind.user_dn = username
-rabbitmq_auth_backend_ldap.other_bind.password = password",
+"auth_ldap.other_bind.user_dn = username
+auth_ldap.other_bind.password = password",
[{rabbitmq_auth_backend_ldap, [{other_bind, {"username", "password"}}]}],
[rabbitmq_auth_backend_ldap]}
,
@@ -252,7 +263,8 @@ mqtt.listeners.ssl = none
# mqtt.listeners.ssl.default = 8883
mqtt.listeners.tcp.default = 1883
mqtt.tcp_listen_options.backlog = 128
-mqtt.tcp_listen_options.nodelay = true",
+mqtt.tcp_listen_options.nodelay = true
+mqtt.proxy_protocol = false",
[{rabbit, [{tcp_listeners, [5672]}]},
{rabbitmq_mqtt, [{default_user, <<"guest">>},
{default_pass, <<"guest">>},
@@ -266,7 +278,8 @@ mqtt.tcp_listen_options.nodelay = true",
%% {ssl_listeners, [8883]}
{tcp_listeners, [1883]},
{tcp_listen_options, [{backlog, 128},
- {nodelay, true}]}]}
+ {nodelay, true}]},
+ {proxy_protocol, false}]}
],
[rabbitmq_mqtt]}
,
@@ -312,7 +325,8 @@ mqtt.allow_anonymous = true
mqtt.vhost = /
mqtt.exchange = amq.topic
mqtt.subscription_ttl = undefined
-mqtt.prefetch = 10",
+mqtt.prefetch = 10
+mqtt.proxy_protocol = true",
[{rabbit, [{tcp_listeners, [5672]}]},
{rabbitmq_mqtt, [{default_user, <<"guest">>},
{default_pass, <<"guest">>},
@@ -320,7 +334,8 @@ mqtt.prefetch = 10",
{vhost, <<"/">>},
{exchange, <<"amq.topic">>},
{subscription_ttl, undefined},
- {prefetch, 10}]}
+ {prefetch, 10},
+ {proxy_protocol, true}]}
],
[rabbitmq_mqtt]}
,
@@ -634,8 +649,10 @@ stomp.listeners.ssl.1 = 61614",
{57,
"stomp.default_user = guest
-stomp.default_pass = guest",
-[{rabbitmq_stomp, [{default_user, [{login, "guest"},{passcode, "guest"}]}]}],
+stomp.default_pass = guest
+stomp.proxy_protocol = false",
+[{rabbitmq_stomp, [{default_user, [{login, "guest"},{passcode, "guest"}]},
+ {proxy_protocol, false}]}],
[rabbitmq_stomp]}
,
{58,
@@ -650,8 +667,10 @@ stomp.default_pass = guest",
{60,
"stomp.default_user = guest
stomp.default_pass = guest
-stomp.implicit_connect = true",
-[{rabbitmq_stomp, [{default_user,[{login, "guest"}, {passcode, "guest"}]},{implicit_connect, true}]}],
+stomp.implicit_connect = true
+stomp.proxy_protocol = true",
+[{rabbitmq_stomp, [{default_user,[{login, "guest"}, {passcode, "guest"}]},
+ {implicit_connect, true}, {proxy_protocol, true}]}],
[rabbitmq_stomp]}
,
{61,
@@ -721,9 +740,9 @@ web_stomp.ssl.password = changeme",
[rabbitmq_web_stomp]},
{69,
"auth_backends.1 = http
-rabbitmq_auth_backend_http.user_path = http://some-server/auth/user
-rabbitmq_auth_backend_http.vhost_path = http://some-server/auth/vhost
-rabbitmq_auth_backend_http.resource_path = http://some-server/auth/resource",
+auth_http.user_path = http://some-server/auth/user
+auth_http.vhost_path = http://some-server/auth/vhost
+auth_http.resource_path = http://some-server/auth/resource",
[{rabbit, [{auth_backends, [rabbit_auth_backend_http]}]},
{rabbitmq_auth_backend_http,
[{user_path, "http://some-server/auth/user"},
@@ -806,6 +825,78 @@ credential_validator.regexp = ^abc\\d+",
{validation_backend, rabbit_credential_validator_password_regexp},
{regexp, "^abc\\d+"}
]}
+]}],[]},
+
+{79,
+"auth_backends.1 = amqp
+auth_amqp.username = user
+auth_amqp.vhost = my_vhost
+auth_amqp.exchange = exchange_name
+auth_amqp.timeout = 100",
+[{rabbit, [{auth_backends, [rabbit_auth_backend_amqp]}]},
+ {rabbitmq_auth_backend_amqp,
+ [{username, <<"user">>},
+ {vhost, <<"my_vhost">>},
+ {exchange, <<"exchange_name">>},
+ {timeout, 100}]}],
+[rabbitmq_auth_backend_amqp]},
+
+{80,
+"auth_backends.1 = cache
+auth_cache.cached_backend = ldap",
+[
+ {rabbit,
+ [{auth_backends,[rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache,
+ [{cached_backend,rabbit_auth_backend_ldap}]}
+], [rabbitmq_auth_backend_cache]},
+
+{auth_backend_cache,
+ "auth_backends.1 = cache",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]}],
+ [rabbitmq_auth_backend_cache]},
+
+{auth_backend_cache_cached_backend,
+ "auth_backends.1 = cache
+ auth_cache.cached_backend = ldap",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache, [{cached_backend, rabbit_auth_backend_ldap}]}],
+ [rabbitmq_auth_backend_cache]},
+{auth_backend_cache_cached_authn_authz,
+ "auth_backends.1 = cache
+ auth_cache.cached_backend.authn = ldap
+ auth_cache.cached_backend.authz = http",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache, [{cached_backend, {rabbit_auth_backend_ldap, rabbit_auth_backend_http}}]}],
+ [rabbitmq_auth_backend_cache]},
+{auth_backend_cache_cached_authn,
+ "auth_backends.1 = cache
+ auth_cache.cached_backend.authn = ldap",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache, [{cached_backend, {rabbit_auth_backend_ldap, rabbit_auth_backend_ldap}}]}],
+ [rabbitmq_auth_backend_cache]},
+{auth_backend_cache_cache_ttl,
+ "auth_backends.1 = cache
+ auth_cache.cache_ttl = 200",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache, [{cache_ttl, 200}]}],
+ [rabbitmq_auth_backend_cache]},
+{auth_backend_cache_cache_module,
+ "auth_backends.1 = cache
+ auth_cache.cache_module = rabbit_auth_backend_ets_segmented",
+ [{rabbit, [{auth_backends, [rabbit_auth_backend_cache]}]},
+ {rabbitmq_auth_backend_cache, [{cache_module, rabbit_auth_backend_ets_segmented}]}],
+ [rabbitmq_auth_backend_cache]},
+
+{81.1,
+"proxy_protocol = true",
+[{rabbit, [
+ {proxy_protocol, true}
+]}],[]},
+{81.2,
+"proxy_protocol = false",
+[{rabbit, [
+ {proxy_protocol, false}
]}],[]}
].
diff --git a/test/dynamic_ha_SUITE.erl b/test/dynamic_ha_SUITE.erl
index 1e32fae254..acb46ad872 100644
--- a/test/dynamic_ha_SUITE.erl
+++ b/test/dynamic_ha_SUITE.erl
@@ -65,8 +65,8 @@ groups() ->
nodes_policy_should_pick_master_from_its_params
% FIXME: Re-enable those tests when the know issues are
% fixed.
- %failing_random_policies,
- %random_policy
+ % failing_random_policies,
+ % random_policy
]}
]}
].
@@ -124,17 +124,18 @@ change_policy(Config) ->
%% When we first declare a queue with no policy, it's not HA.
amqp_channel:call(ACh, #'queue.declare'{queue = ?QNAME}),
+ timer:sleep(100),
assert_slaves(A, ?QNAME, {A, ''}),
%% Give it policy "all", it becomes HA and gets all mirrors
rabbit_ct_broker_helpers:set_ha_policy(Config, A, ?POLICY, <<"all">>),
- assert_slaves(A, ?QNAME, {A, [B, C]}),
+ assert_slaves(A, ?QNAME, {A, [B, C]}, [{A, []}, {A, [B]}, {A, [C]}]),
%% Give it policy "nodes", it gets specific mirrors
rabbit_ct_broker_helpers:set_ha_policy(Config, A, ?POLICY,
{<<"nodes">>, [rabbit_misc:atom_to_binary(A),
rabbit_misc:atom_to_binary(B)]}),
- assert_slaves(A, ?QNAME, {A, [B]}),
+ assert_slaves(A, ?QNAME, {A, [B]}, [{A, [B, C]}]),
%% Now explicitly change the mirrors
rabbit_ct_broker_helpers:set_ha_policy(Config, A, ?POLICY,
@@ -150,7 +151,7 @@ change_policy(Config) ->
rabbit_ct_broker_helpers:set_ha_policy(Config, A, ?POLICY,
{<<"nodes">>, [rabbit_misc:atom_to_binary(B),
rabbit_misc:atom_to_binary(C)]}),
- assert_slaves(A, ?QNAME, {A, [B, C]}, [{A, [B]}, {A, [C]}]),
+ assert_slaves(A, ?QNAME, {B, [C]}, [{A, []}, {A, [B]}, {A, [C]}, {A, [B, C]}]),
ok.
@@ -166,15 +167,15 @@ change_cluster(Config) ->
%% Give it policy exactly 4, it should mirror to all 3 nodes
rabbit_ct_broker_helpers:set_ha_policy(Config, A, ?POLICY,
{<<"exactly">>, 4}),
- assert_slaves(A, ?QNAME, {A, [B, C]}),
+ assert_slaves(A, ?QNAME, {A, [B, C]}, [{A, []}, {A, [B]}, {A, [C]}]),
%% Add D and E, D joins in
rabbit_ct_broker_helpers:cluster_nodes(Config, [A, D, E]),
- assert_slaves(A, ?QNAME, {A, [B, C, D]}),
+ assert_slaves(A, ?QNAME, {A, [B, C, D]}, [{A, [B, C]}]),
%% Remove D, E joins in
rabbit_ct_broker_helpers:stop_node(Config, D),
- assert_slaves(A, ?QNAME, {A, [B, C, E]}),
+ assert_slaves(A, ?QNAME, {A, [B, C, E]}, [{A, [B, C]}]),
ok.
@@ -343,15 +344,18 @@ assert_slaves0(RPCNode, QName, {ExpMNode, ExpSNodes}, PermittedIntermediate) ->
%% just wait - of course this means if something does not
%% change when expected then we time out the test which is
%% a bit tedious
- case [found || {PermMNode, PermSNodes} <- PermittedIntermediate,
+ case [{PermMNode, PermSNodes} || {PermMNode, PermSNodes} <- PermittedIntermediate,
PermMNode =:= ActMNode,
equal_list(PermSNodes, ActSNodes)] of
[] -> ct:fail("Expected ~p / ~p, got ~p / ~p~nat ~p~n",
[ExpMNode, ExpSNodes, ActMNode, ActSNodes,
get_stacktrace()]);
- _ -> timer:sleep(100),
- assert_slaves0(RPCNode, QName, {ExpMNode, ExpSNodes},
- PermittedIntermediate)
+ State ->
+ ct:pal("Waiting to leave state ~p~n Waiting for ~p~n",
+ [State, {ExpMNode, ExpSNodes}]),
+ timer:sleep(100),
+ assert_slaves0(RPCNode, QName, {ExpMNode, ExpSNodes},
+ PermittedIntermediate)
end;
true ->
put(previous_exp_m_node, ExpMNode),
diff --git a/test/priority_queue_SUITE.erl b/test/priority_queue_SUITE.erl
index 8e1b48dd3b..eecd59b879 100644
--- a/test/priority_queue_SUITE.erl
+++ b/test/priority_queue_SUITE.erl
@@ -44,7 +44,8 @@ groups() ->
resume,
simple_order,
straight_through,
- invoke
+ invoke,
+ gen_server2_stats
]},
{cluster_size_3, [], [
mirror_queue_auto_ack,
@@ -214,6 +215,29 @@ invoke(Config) ->
rabbit_ct_client_helpers:close_connection(Conn),
passed.
+
+gen_server2_stats(Config) ->
+ %% Synthetic test to check the invoke callback, as the bug tested here
+ %% is only triggered with a race condition.
+ %% When mirroring is stopped, the backing queue of rabbit_amqqueue_process
+ %% changes from rabbit_mirror_queue_master to rabbit_priority_queue,
+ %% which shouldn't receive any invoke call. However, there might
+ %% be pending messages so the priority queue receives the
+ %% `run_backing_queue` cast message sent to the old master.
+ A = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
+ {Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, A),
+ Q = <<"gen_server2_stats_queue">>,
+ declare(Ch, Q, 3),
+ Pid = queue_pid(Config, A, rabbit_misc:r(<<"/">>, queue, Q)),
+ Metrics = rabbit_ct_broker_helpers:rpc(
+ Config, A, rabbit_core_metrics, get_gen_server2_stats,
+ [Pid]),
+ true = is_number(Metrics),
+ delete(Ch, Q),
+ rabbit_ct_client_helpers:close_channel(Ch),
+ rabbit_ct_client_helpers:close_connection(Conn),
+ passed.
+
dropwhile_fetchwhile(Config) ->
{Conn, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0),
Q = <<"dropwhile_fetchwhile-queue">>,
diff --git a/test/proxy_protocol_SUITE.erl b/test/proxy_protocol_SUITE.erl
new file mode 100644
index 0000000000..136d2bb980
--- /dev/null
+++ b/test/proxy_protocol_SUITE.erl
@@ -0,0 +1,100 @@
+%% The contents of this file are subject to the Mozilla Public License
+%% Version 1.1 (the "License"); you may not use this file except in
+%% compliance with the License. You may obtain a copy of the License at
+%% http://www.mozilla.org/MPL/
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+%% License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developer of the Original Code is GoPivotal, Inc.
+%% Copyright (c) 2017 Pivotal Software, Inc. All rights reserved.
+%%
+
+-module(proxy_protocol_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("rabbit_common/include/rabbit.hrl").
+
+-compile(export_all).
+
+-define(TIMEOUT, 5000).
+
+all() ->
+ [
+ {group, sequential_tests}
+ ].
+
+groups() -> [
+ {sequential_tests, [], [
+ proxy_protocol,
+ proxy_protocol_tls
+ ]}
+ ].
+
+init_per_suite(Config) ->
+ rabbit_ct_helpers:log_environment(),
+ Config1 = rabbit_ct_helpers:set_config(Config, [
+ {rmq_nodename_suffix, ?MODULE}
+ ]),
+ Config2 = rabbit_ct_helpers:merge_app_env(Config1, [
+ {rabbit, [
+ {proxy_protocol, true}
+ ]}
+ ]),
+ Config3 = rabbit_ct_helpers:set_config(Config2, {rabbitmq_ct_tls_verify, verify_none}),
+ rabbit_ct_helpers:run_setup_steps(Config3,
+ rabbit_ct_broker_helpers:setup_steps() ++
+ rabbit_ct_client_helpers:setup_steps()).
+
+end_per_suite(Config) ->
+ rabbit_ct_helpers:run_teardown_steps(Config,
+ rabbit_ct_client_helpers:teardown_steps() ++
+ rabbit_ct_broker_helpers:teardown_steps()).
+
+init_per_group(_, Config) -> Config.
+end_per_group(_, Config) -> Config.
+
+init_per_testcase(Testcase, Config) ->
+ rabbit_ct_helpers:testcase_started(Config, Testcase).
+
+end_per_testcase(Testcase, Config) ->
+ rabbit_ct_helpers:testcase_finished(Config, Testcase).
+
+proxy_protocol(Config) ->
+ Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp),
+ {ok, Socket} = gen_tcp:connect({127,0,0,1}, Port,
+ [binary, {active, false}, {packet, raw}]),
+ ok = inet:send(Socket, "PROXY TCP4 192.168.1.1 192.168.1.2 80 81\r\n"),
+ ok = inet:send(Socket, <<"AMQP", 0, 0, 9, 1>>),
+ {ok, _Packet} = gen_tcp:recv(Socket, 0, ?TIMEOUT),
+ ConnectionName = rabbit_ct_broker_helpers:rpc(Config, 0,
+ ?MODULE, connection_name, []),
+ match = re:run(ConnectionName, <<"^192.168.1.1:80 ">>, [{capture, none}]),
+ gen_tcp:close(Socket),
+ ok.
+
+proxy_protocol_tls(Config) ->
+ app_utils:start_applications([asn1, crypto, public_key, ssl]),
+ Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp_tls),
+ {ok, Socket} = gen_tcp:connect({127,0,0,1}, Port,
+ [binary, {active, false}, {packet, raw}]),
+ ok = inet:send(Socket, "PROXY TCP4 192.168.1.1 192.168.1.2 80 81\r\n"),
+ {ok, SslSocket} = ssl:connect(Socket, [], ?TIMEOUT),
+ ok = ssl:send(SslSocket, <<"AMQP", 0, 0, 9, 1>>),
+ {ok, _Packet} = ssl:recv(SslSocket, 0, ?TIMEOUT),
+ ConnectionName = rabbit_ct_broker_helpers:rpc(Config, 0,
+ ?MODULE, connection_name, []),
+ match = re:run(ConnectionName, <<"^192.168.1.1:80 ">>, [{capture, none}]),
+ gen_tcp:close(Socket),
+ ok.
+
+connection_name() ->
+ Pids = pg_local:get_members(rabbit_connections),
+ Pid = lists:nth(1, Pids),
+ {dictionary, Dict} = process_info(Pid, dictionary),
+ {process_name, {rabbit_reader, ConnectionName}} = lists:keyfind(process_name, 1, Dict),
+ ConnectionName. \ No newline at end of file
diff --git a/test/topic_permission_SUITE.erl b/test/topic_permission_SUITE.erl
index 57d48af4ab..7b9d9f7701 100644
--- a/test/topic_permission_SUITE.erl
+++ b/test/topic_permission_SUITE.erl
@@ -76,7 +76,7 @@ topic_permission_database_access1(_Config) ->
rabbit_auth_backend_internal:add_user(<<"dummy">>, <<"dummy">>, <<"acting-user">>),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"/">>, <<"amq.topic">>, "^a", <<"acting-user">>
+ <<"guest">>, <<"/">>, <<"amq.topic">>, "^a", "^a", <<"acting-user">>
),
1 = length(ets:tab2list(rabbit_topic_permission)),
1 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
@@ -88,7 +88,7 @@ topic_permission_database_access1(_Config) ->
1 = length(rabbit_auth_backend_internal:list_topic_permissions()),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", <<"acting-user">>
+ <<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
),
2 = length(ets:tab2list(rabbit_topic_permission)),
2 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
@@ -100,10 +100,10 @@ topic_permission_database_access1(_Config) ->
2 = length(rabbit_auth_backend_internal:list_topic_permissions()),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"/">>, <<"topic1">>, "^a", <<"acting-user">>
+ <<"guest">>, <<"/">>, <<"topic1">>, "^a", "^a", <<"acting-user">>
),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"/">>, <<"topic2">>, "^a", <<"acting-user">>
+ <<"guest">>, <<"/">>, <<"topic2">>, "^a", "^a", <<"acting-user">>
),
4 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
@@ -124,16 +124,15 @@ topic_permission_database_access1(_Config) ->
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
- <<"non-existing-user">>, <<"other-vhost">>, <<"amq.topic">>, ".*", <<"acting-user">>
+ <<"non-existing-user">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_vhost, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*", <<"acting-user">>
+ <<"guest">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
- <<"non-existing-user">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*",
- <<"acting-user">>
+ <<"non-existing-user">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:list_user_topic_permissions(
@@ -145,7 +144,7 @@ topic_permission_database_access1(_Config) ->
)),
{error, {invalid_regexp, _, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"/">>, <<"amq.topic">>, "[", <<"acting-user">>
+ <<"guest">>, <<"/">>, <<"amq.topic">>, "[", "^a", <<"acting-user">>
)),
ok.
@@ -167,7 +166,7 @@ topic_permission_checks1(_Config) ->
rabbit_auth_backend_internal:add_user(<<"dummy">>, <<"dummy">>, <<"acting-user">>),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"/">>, <<"amq.topic">>, "^a", <<"acting-user">>
+ <<"guest">>, <<"/">>, <<"amq.topic">>, "^a", "^a", <<"acting-user">>
),
1 = length(ets:tab2list(rabbit_topic_permission)),
1 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
@@ -176,7 +175,7 @@ topic_permission_checks1(_Config) ->
0 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
rabbit_auth_backend_internal:set_topic_permissions(
- <<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", <<"acting-user">>
+ <<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
),
2 = length(ets:tab2list(rabbit_topic_permission)),
2 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
@@ -188,34 +187,35 @@ topic_permission_checks1(_Config) ->
Topic = #resource{name = <<"amq.topic">>, virtual_host = <<"/">>,
kind = topic},
Context = #{routing_key => <<"a.b.c">>},
+ Permissions = [write, read],
%% user has access to exchange, routing key matches
- true = rabbit_auth_backend_internal:check_topic_access(
+ [true = rabbit_auth_backend_internal:check_topic_access(
User,
Topic,
- write,
+ Perm,
Context
- ),
+ ) || Perm <- Permissions],
%% user has access to exchange, routing key does not match
- false = rabbit_auth_backend_internal:check_topic_access(
+ [false = rabbit_auth_backend_internal:check_topic_access(
User,
Topic,
- write,
+ Perm,
#{routing_key => <<"x.y.z">>}
- ),
+ ) || Perm <- Permissions],
%% user has access to exchange but not on this vhost
%% let pass when there's no match
- true = rabbit_auth_backend_internal:check_topic_access(
+ [true = rabbit_auth_backend_internal:check_topic_access(
User,
Topic#resource{virtual_host = <<"fancyvhost">>},
- write,
+ Perm,
Context
- ),
+ ) || Perm <- Permissions],
%% user does not have access to exchange
%% let pass when there's no match
- true = rabbit_auth_backend_internal:check_topic_access(
+ [true = rabbit_auth_backend_internal:check_topic_access(
#auth_user{username = <<"dummy">>},
Topic,
- write,
+ Perm,
Context
- ),
+ ) || Perm <- Permissions],
ok.
diff --git a/test/unit_inbroker_SUITE.erl b/test/unit_inbroker_SUITE.erl
index b1ebd054cf..f2451ce5c4 100644
--- a/test/unit_inbroker_SUITE.erl
+++ b/test/unit_inbroker_SUITE.erl
@@ -1694,24 +1694,18 @@ check_variable_queue_status(VQ0, Props) ->
%% ---------------------------------------------------------------------------
credit_flow_settings(Config) ->
- passed = rabbit_ct_broker_helpers:rpc(Config, 0,
+ rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, credit_flow_settings1, [Config]).
credit_flow_settings1(_Config) ->
- %% default values
- passed = test_proc(200, 100),
-
- application:set_env(rabbit, credit_flow_default_credit, {100, 300}),
- passed = test_proc(100, 300),
-
- application:unset_env(rabbit, credit_flow_default_credit),
-
- % back to defaults
- passed = test_proc(200, 100),
+ passed = test_proc(400, 200, {400, 200}),
+ passed = test_proc(600, 300),
passed.
test_proc(InitialCredit, MoreCreditAfter) ->
- Pid = spawn(fun dummy/0),
+ test_proc(InitialCredit, MoreCreditAfter, {InitialCredit, MoreCreditAfter}).
+test_proc(InitialCredit, MoreCreditAfter, Settings) ->
+ Pid = spawn(?MODULE, dummy, [Settings]),
Pid ! {credit, self()},
{InitialCredit, MoreCreditAfter} =
receive
@@ -1719,13 +1713,13 @@ test_proc(InitialCredit, MoreCreditAfter) ->
end,
passed.
-dummy() ->
+dummy(Settings) ->
credit_flow:send(self()),
receive
{credit, From} ->
- From ! {credit, get(credit_flow_default_credit)};
+ From ! {credit, Settings};
_ ->
- dummy()
+ dummy(Settings)
end.
%% -------------------------------------------------------------------