init.
This commit is contained in:
commit
a8b2727ac3
|
@ -0,0 +1,12 @@
|
|||
.sw?
|
||||
.*.sw?
|
||||
*.beam
|
||||
/.erlang.mk/
|
||||
/cover/
|
||||
/deps/
|
||||
/doc/
|
||||
/ebin/
|
||||
/logs/
|
||||
/plugins/
|
||||
|
||||
/rabbitmq_auth_backend_cache.d
|
|
@ -0,0 +1,15 @@
|
|||
PROJECT = rabbitmq_auth_backend_cache
|
||||
|
||||
DEPS = rabbit_common
|
||||
|
||||
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
|
||||
|
||||
# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be
|
||||
# reviewed and merged.
|
||||
|
||||
ERLANG_MK_REPO = https://github.com/rabbitmq/erlang.mk.git
|
||||
ERLANG_MK_COMMIT = rabbitmq-tmp
|
||||
|
||||
include rabbitmq-components.mk
|
||||
include erlang.mk
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# Do *not* comment or remove core modules
|
||||
# unless you know what you are doing.
|
||||
#
|
||||
# Feel free to comment plugins out however.
|
||||
|
||||
# Core modules.
|
||||
core/core
|
||||
index/*
|
||||
core/index
|
||||
core/deps
|
||||
|
||||
# Plugins that must run before Erlang code gets compiled.
|
||||
plugins/erlydtl
|
||||
plugins/protobuffs
|
||||
|
||||
# Core modules, continued.
|
||||
core/erlc
|
||||
core/docs
|
||||
core/rel
|
||||
core/test
|
||||
core/compat
|
||||
|
||||
# Plugins.
|
||||
plugins/asciidoc
|
||||
plugins/bootstrap
|
||||
plugins/c_src
|
||||
plugins/ci
|
||||
plugins/ct
|
||||
plugins/dialyzer
|
||||
plugins/edoc
|
||||
plugins/elvis
|
||||
plugins/escript
|
||||
# plugins/eunit
|
||||
plugins/relx
|
||||
plugins/shell
|
||||
plugins/triq
|
||||
plugins/xref
|
||||
|
||||
# Plugins enhancing the functionality of other plugins.
|
||||
plugins/cover
|
||||
|
||||
# Core modules which can use variables from plugins.
|
||||
core/deps-tools
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,335 @@
|
|||
ifeq ($(.DEFAULT_GOAL),)
|
||||
# Define default goal to `all` because this file defines some targets
|
||||
# before the inclusion of erlang.mk leading to the wrong target becoming
|
||||
# the default.
|
||||
.DEFAULT_GOAL = all
|
||||
endif
|
||||
|
||||
# Automatically add rabbitmq-common to the dependencies, at least for
|
||||
# the Makefiles.
|
||||
ifneq ($(PROJECT),rabbit_common)
|
||||
ifneq ($(PROJECT),rabbitmq_public_umbrella)
|
||||
ifeq ($(filter rabbit_common,$(DEPS)),)
|
||||
DEPS += rabbit_common
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# RabbitMQ components.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# For RabbitMQ repositories, we want to checkout branches which match
|
||||
# the parent project. For instance, if the parent project is on a
|
||||
# release tag, dependencies must be on the same release tag. If the
|
||||
# parent project is on a topic branch, dependencies must be on the same
|
||||
# topic branch or fallback to `stable` or `master` whichever was the
|
||||
# base of the topic branch.
|
||||
|
||||
dep_amqp_client = git_rmq rabbitmq-erlang-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbit = git_rmq rabbitmq-server $(current_rmq_ref) $(base_rmq_ref) master
|
||||
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_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
|
||||
dep_rabbitmq_boot_steps_visualiser = git_rmq rabbitmq-boot-steps-visualiser $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_clusterer = git_rmq rabbitmq-clusterer $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_codegen = git_rmq rabbitmq-codegen $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_delayed_message_exchange = git_rmq rabbitmq-delayed-message-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_dotnet_client = git_rmq rabbitmq-dotnet-client $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_federation = git_rmq rabbitmq-federation $(current_rmq_ref) $(base_rmq_ref) master
|
||||
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_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
|
||||
dep_rabbitmq_management_agent = git_rmq rabbitmq-management-agent $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_exchange = git_rmq rabbitmq-management-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_themes = git_rmq rabbitmq-management-themes $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_management_visualiser = git_rmq rabbitmq-management-visualiser $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_message_timestamp = git_rmq rabbitmq-message-timestamp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_metronome = git_rmq rabbitmq-metronome $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_mqtt = git_rmq rabbitmq-mqtt $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_recent_history_exchange = git_rmq rabbitmq-recent-history-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_rtopic_exchange = git_rmq rabbitmq-rtopic-exchange $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_shovel = git_rmq rabbitmq-shovel $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_stomp = git_rmq rabbitmq-stomp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_toke = git_rmq rabbitmq-toke $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_top = git_rmq rabbitmq-top $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_tracing = git_rmq rabbitmq-tracing $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_test = git_rmq rabbitmq-test $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_dispatch = git_rmq rabbitmq-web-dispatch $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_stomp = git_rmq rabbitmq-web-stomp $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_stomp_examples = git_rmq rabbitmq-web-stomp-examples $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_mqtt = git_rmq rabbitmq-web-mqtt $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_web_mqtt_examples = git_rmq rabbitmq-web-mqtt-examples $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_rabbitmq_website = git_rmq rabbitmq-website $(current_rmq_ref) $(base_rmq_ref) live master
|
||||
dep_sockjs = git_rmq sockjs-erlang $(current_rmq_ref) $(base_rmq_ref) master
|
||||
dep_toke = git_rmq toke $(current_rmq_ref) $(base_rmq_ref) master
|
||||
|
||||
dep_rabbitmq_public_umbrella = git_rmq rabbitmq-public-umbrella $(current_rmq_ref) $(base_rmq_ref) master
|
||||
|
||||
# FIXME: As of 2015-11-20, we depend on Ranch 1.2.1, but erlang.mk
|
||||
# defaults to Ranch 1.1.0. All projects depending indirectly on Ranch
|
||||
# needs to add "ranch" as a BUILD_DEPS. The list of projects needing
|
||||
# this workaround are:
|
||||
# o rabbitmq-web-stomp
|
||||
dep_ranch = git https://github.com/ninenines/ranch 1.2.1
|
||||
|
||||
RABBITMQ_COMPONENTS = amqp_client \
|
||||
rabbit \
|
||||
rabbit_common \
|
||||
rabbitmq_amqp1_0 \
|
||||
rabbitmq_auth_backend_amqp \
|
||||
rabbitmq_auth_backend_http \
|
||||
rabbitmq_auth_backend_ldap \
|
||||
rabbitmq_auth_mechanism_ssl \
|
||||
rabbitmq_boot_steps_visualiser \
|
||||
rabbitmq_clusterer \
|
||||
rabbitmq_codegen \
|
||||
rabbitmq_consistent_hash_exchange \
|
||||
rabbitmq_delayed_message_exchange \
|
||||
rabbitmq_dotnet_client \
|
||||
rabbitmq_event_exchange \
|
||||
rabbitmq_federation \
|
||||
rabbitmq_federation_management \
|
||||
rabbitmq_java_client \
|
||||
rabbitmq_lvc \
|
||||
rabbitmq_management \
|
||||
rabbitmq_management_agent \
|
||||
rabbitmq_management_exchange \
|
||||
rabbitmq_management_themes \
|
||||
rabbitmq_management_visualiser \
|
||||
rabbitmq_message_timestamp \
|
||||
rabbitmq_metronome \
|
||||
rabbitmq_mqtt \
|
||||
rabbitmq_recent_history_exchange \
|
||||
rabbitmq_rtopic_exchange \
|
||||
rabbitmq_sharding \
|
||||
rabbitmq_shovel \
|
||||
rabbitmq_shovel_management \
|
||||
rabbitmq_stomp \
|
||||
rabbitmq_test \
|
||||
rabbitmq_toke \
|
||||
rabbitmq_top \
|
||||
rabbitmq_tracing \
|
||||
rabbitmq_web_dispatch \
|
||||
rabbitmq_web_mqtt \
|
||||
rabbitmq_web_mqtt_examples \
|
||||
rabbitmq_web_stomp \
|
||||
rabbitmq_web_stomp_examples \
|
||||
rabbitmq_website
|
||||
|
||||
# Several components have a custom erlang.mk/build.config, mainly
|
||||
# to disable eunit. Therefore, we can't use the top-level project's
|
||||
# erlang.mk copy.
|
||||
NO_AUTOPATCH += $(RABBITMQ_COMPONENTS)
|
||||
|
||||
ifeq ($(origin current_rmq_ref),undefined)
|
||||
ifneq ($(wildcard .git),)
|
||||
current_rmq_ref := $(shell (\
|
||||
ref=$$(git branch --list | awk '/^\* \(.*detached / {ref=$$0; sub(/.*detached [^ ]+ /, "", ref); sub(/\)$$/, "", ref); print ref; exit;} /^\* / {ref=$$0; sub(/^\* /, "", ref); print ref; exit}');\
|
||||
if test "$$(git rev-parse --short HEAD)" != "$$ref"; then echo "$$ref"; fi))
|
||||
else
|
||||
current_rmq_ref := master
|
||||
endif
|
||||
endif
|
||||
export current_rmq_ref
|
||||
|
||||
ifeq ($(origin base_rmq_ref),undefined)
|
||||
ifneq ($(wildcard .git),)
|
||||
base_rmq_ref := $(shell \
|
||||
(git rev-parse --verify -q stable >/dev/null && \
|
||||
git merge-base --is-ancestor $$(git merge-base master HEAD) stable && \
|
||||
echo stable) || \
|
||||
echo master)
|
||||
else
|
||||
base_rmq_ref := master
|
||||
endif
|
||||
endif
|
||||
export base_rmq_ref
|
||||
|
||||
# Repository URL selection.
|
||||
#
|
||||
# First, we infer other components' location from the current project
|
||||
# repository URL, if it's a Git repository:
|
||||
# - We take the "origin" remote URL as the base
|
||||
# - The current project name and repository name is replaced by the
|
||||
# target's properties:
|
||||
# eg. rabbitmq-common is replaced by rabbitmq-codegen
|
||||
# eg. rabbit_common is replaced by rabbitmq_codegen
|
||||
#
|
||||
# If cloning from this computed location fails, we fallback to RabbitMQ
|
||||
# upstream which is GitHub.
|
||||
|
||||
# Maccro to transform eg. "rabbit_common" to "rabbitmq-common".
|
||||
rmq_cmp_repo_name = $(word 2,$(dep_$(1)))
|
||||
|
||||
# Upstream URL for the current project.
|
||||
RABBITMQ_COMPONENT_REPO_NAME := $(call rmq_cmp_repo_name,$(PROJECT))
|
||||
RABBITMQ_UPSTREAM_FETCH_URL ?= https://github.com/rabbitmq/$(RABBITMQ_COMPONENT_REPO_NAME).git
|
||||
RABBITMQ_UPSTREAM_PUSH_URL ?= git@github.com:rabbitmq/$(RABBITMQ_COMPONENT_REPO_NAME).git
|
||||
|
||||
# Current URL for the current project. If this is not a Git clone,
|
||||
# default to the upstream Git repository.
|
||||
ifneq ($(wildcard .git),)
|
||||
git_origin_fetch_url := $(shell git config remote.origin.url)
|
||||
git_origin_push_url := $(shell git config remote.origin.pushurl || git config remote.origin.url)
|
||||
RABBITMQ_CURRENT_FETCH_URL ?= $(git_origin_fetch_url)
|
||||
RABBITMQ_CURRENT_PUSH_URL ?= $(git_origin_push_url)
|
||||
else
|
||||
RABBITMQ_CURRENT_FETCH_URL ?= $(RABBITMQ_UPSTREAM_FETCH_URL)
|
||||
RABBITMQ_CURRENT_PUSH_URL ?= $(RABBITMQ_UPSTREAM_PUSH_URL)
|
||||
endif
|
||||
|
||||
# Macro to replace the following pattern:
|
||||
# 1. /foo.git -> /bar.git
|
||||
# 2. /foo -> /bar
|
||||
# 3. /foo/ -> /bar/
|
||||
subst_repo_name = $(patsubst %/$(1)/%,%/$(2)/%,$(patsubst %/$(1),%/$(2),$(patsubst %/$(1).git,%/$(2).git,$(3))))
|
||||
|
||||
# Macro to replace both the project's name (eg. "rabbit_common") and
|
||||
# repository name (eg. "rabbitmq-common") by the target's equivalent.
|
||||
#
|
||||
# This macro is kept on one line because we don't want whitespaces in
|
||||
# the returned value, as it's used in $(dep_fetch_git_rmq) in a shell
|
||||
# single-quoted string.
|
||||
dep_rmq_repo = $(if $(dep_$(2)),$(call subst_repo_name,$(PROJECT),$(2),$(call subst_repo_name,$(RABBITMQ_COMPONENT_REPO_NAME),$(call rmq_cmp_repo_name,$(2)),$(1))),$(pkg_$(1)_repo))
|
||||
|
||||
dep_rmq_commits = $(if $(dep_$(1)), \
|
||||
$(wordlist 3,$(words $(dep_$(1))),$(dep_$(1))), \
|
||||
$(pkg_$(1)_commit))
|
||||
|
||||
define dep_fetch_git_rmq
|
||||
fetch_url1='$(call dep_rmq_repo,$(RABBITMQ_CURRENT_FETCH_URL),$(1))'; \
|
||||
fetch_url2='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_FETCH_URL),$(1))'; \
|
||||
if test "$$$$fetch_url1" != '$(RABBITMQ_CURRENT_FETCH_URL)' && \
|
||||
git clone -q -n -- "$$$$fetch_url1" $(DEPS_DIR)/$(call dep_name,$(1)); then \
|
||||
fetch_url="$$$$fetch_url1"; \
|
||||
push_url='$(call dep_rmq_repo,$(RABBITMQ_CURRENT_PUSH_URL),$(1))'; \
|
||||
elif git clone -q -n -- "$$$$fetch_url2" $(DEPS_DIR)/$(call dep_name,$(1)); then \
|
||||
fetch_url="$$$$fetch_url2"; \
|
||||
push_url='$(call dep_rmq_repo,$(RABBITMQ_UPSTREAM_PUSH_URL),$(1))'; \
|
||||
fi; \
|
||||
cd $(DEPS_DIR)/$(call dep_name,$(1)) && ( \
|
||||
$(foreach ref,$(call dep_rmq_commits,$(1)), \
|
||||
git checkout -q $(ref) >/dev/null 2>&1 || \
|
||||
) \
|
||||
(echo "error: no valid pathspec among: $(call dep_rmq_commits,$(1))" \
|
||||
1>&2 && false) ) && \
|
||||
(test "$$$$fetch_url" = "$$$$push_url" || \
|
||||
git remote set-url --push origin "$$$$push_url")
|
||||
endef
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Component distribution.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
list-dist-deps::
|
||||
@:
|
||||
|
||||
prepare-dist::
|
||||
@:
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Run a RabbitMQ node (moved from rabbitmq-run.mk as a workaround).
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# Add "rabbit" to the build dependencies when the user wants to start
|
||||
# a broker or to the test dependencies when the user wants to test a
|
||||
# project.
|
||||
#
|
||||
# NOTE: This should belong to rabbitmq-run.mk. Unfortunately, it is
|
||||
# loaded *after* erlang.mk which is too late to add a dependency. That's
|
||||
# why rabbitmq-components.mk knows the list of targets which start a
|
||||
# broker and add "rabbit" to the dependencies in this case.
|
||||
|
||||
ifneq ($(PROJECT),rabbit)
|
||||
ifeq ($(filter rabbit,$(DEPS) $(BUILD_DEPS)),)
|
||||
RUN_RMQ_TARGETS = run-broker \
|
||||
run-background-broker \
|
||||
run-node \
|
||||
run-background-node \
|
||||
start-background-node
|
||||
|
||||
ifneq ($(filter $(RUN_RMQ_TARGETS),$(MAKECMDGOALS)),)
|
||||
BUILD_DEPS += rabbit
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(filter rabbit,$(DEPS) $(BUILD_DEPS) $(TEST_DEPS)),)
|
||||
ifneq ($(filter check tests tests-with-broker test,$(MAKECMDGOALS)),)
|
||||
TEST_DEPS += rabbit
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(filter rabbit_public_umbrella amqp_client rabbit_common rabbitmq_test,$(PROJECT)),)
|
||||
ifeq ($(filter rabbitmq_test,$(DEPS) $(BUILD_DEPS) $(TEST_DEPS)),)
|
||||
TEST_DEPS += rabbitmq_test
|
||||
endif
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# rabbitmq-components.mk checks.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
ifeq ($(PROJECT),rabbit_common)
|
||||
else ifdef SKIP_RMQCOMP_CHECK
|
||||
else ifeq ($(IS_DEP),1)
|
||||
else ifneq ($(filter co up,$(MAKECMDGOALS)),)
|
||||
else
|
||||
# In all other cases, rabbitmq-components.mk must be in sync.
|
||||
deps:: check-rabbitmq-components.mk
|
||||
fetch-deps: check-rabbitmq-components.mk
|
||||
endif
|
||||
|
||||
# If this project is under the Umbrella project, we override $(DEPS_DIR)
|
||||
# to point to the Umbrella's one. We also disable `make distclean` so
|
||||
# $(DEPS_DIR) is not accidentally removed.
|
||||
|
||||
ifneq ($(wildcard ../../UMBRELLA.md),)
|
||||
UNDER_UMBRELLA = 1
|
||||
else ifneq ($(wildcard UMBRELLA.md),)
|
||||
UNDER_UMBRELLA = 1
|
||||
endif
|
||||
|
||||
ifeq ($(UNDER_UMBRELLA),1)
|
||||
ifneq ($(PROJECT),rabbitmq_public_umbrella)
|
||||
DEPS_DIR ?= $(abspath ..)
|
||||
|
||||
distclean:: distclean-components
|
||||
@:
|
||||
|
||||
distclean-components:
|
||||
endif
|
||||
|
||||
ifneq ($(filter distclean distclean-deps,$(MAKECMDGOALS)),)
|
||||
SKIP_DEPS = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
UPSTREAM_RMQ_COMPONENTS_MK = $(DEPS_DIR)/rabbit_common/mk/rabbitmq-components.mk
|
||||
|
||||
check-rabbitmq-components.mk:
|
||||
$(verbose) cmp -s rabbitmq-components.mk \
|
||||
$(UPSTREAM_RMQ_COMPONENTS_MK) || \
|
||||
(echo "error: rabbitmq-components.mk must be updated!" 1>&2; \
|
||||
false)
|
||||
|
||||
ifeq ($(PROJECT),rabbit_common)
|
||||
rabbitmq-components-mk:
|
||||
@:
|
||||
else
|
||||
rabbitmq-components-mk:
|
||||
$(gen_verbose) cp -a $(UPSTREAM_RMQ_COMPONENTS_MK) .
|
||||
ifeq ($(DO_COMMIT),yes)
|
||||
$(verbose) git diff --quiet rabbitmq-components.mk \
|
||||
|| git commit -m 'Update rabbitmq-components.mk' rabbitmq-components.mk
|
||||
endif
|
||||
endif
|
|
@ -0,0 +1,82 @@
|
|||
%% 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) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_auth_backend_cache).
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
|
||||
-behaviour(rabbit_authn_backend).
|
||||
-behaviour(rabbit_authz_backend).
|
||||
|
||||
-export([user_login_authentication/2, user_login_authorization/1,
|
||||
check_vhost_access/3, check_resource_access/3]).
|
||||
|
||||
%% Implementation of rabbit_auth_backend
|
||||
|
||||
user_login_authentication(Username, AuthProps) ->
|
||||
with_cache({user_login_authentication, [Username, AuthProps]},
|
||||
fun({ok, _}) -> success;
|
||||
({refused, _}) -> refusal;
|
||||
({error, _} = Err) -> Err
|
||||
end).
|
||||
|
||||
user_login_authorization(Username) ->
|
||||
with_cache({user_login_authorization, [Username]},
|
||||
fun({ok, _}) -> success;
|
||||
({ok, _, _}) -> success;
|
||||
({refused, _}) -> refusal;
|
||||
({error, _} = Err) -> Err
|
||||
end).
|
||||
|
||||
check_vhost_access(#auth_user{} = AuthUser, VHostPath, Sock) ->
|
||||
with_cache({check_vhost_access, [AuthUser, VHostPath, Sock]},
|
||||
fun(true) -> success;
|
||||
(false) -> refusal;
|
||||
({error, _} = Err) -> Err
|
||||
end).
|
||||
|
||||
check_resource_access(#auth_user{} = AuthUser,
|
||||
#resource{} = Resource, Permission) ->
|
||||
with_cache({check_resource_access, [AuthUser, Resource, Permission]},
|
||||
fun(true) -> success;
|
||||
(false) -> refusal;
|
||||
({error, _} = Err) -> Err
|
||||
end).
|
||||
|
||||
with_cache({F, A}, Fun) ->
|
||||
{ok, AuthCache} = application:get_env(rabbitmq_auth_backend_cache,
|
||||
cache_module),
|
||||
case AuthCache:get({F, A}) of
|
||||
{ok, Result} ->
|
||||
Result;
|
||||
{error, not_found} ->
|
||||
{ok, Backend} = application:get_env(rabbitmq_auth_backend_cache,
|
||||
cached_backend),
|
||||
BackendResult = apply(Backend, F, A),
|
||||
case should_cache(BackendResult, Fun) of
|
||||
true -> ok = AuthCache:put({F, A}, BackendResult);
|
||||
false -> ok
|
||||
end,
|
||||
BackendResult
|
||||
end.
|
||||
|
||||
should_cache(Result, Fun) ->
|
||||
{ok, CacheRefusals} = application:get_env(rabbitmq_auth_backend_cache,
|
||||
cache_refusals),
|
||||
case {Fun(Result), CacheRefusals} of
|
||||
{success, _} -> true;
|
||||
{refusal, true} -> true;
|
||||
_ -> false
|
||||
end.
|
|
@ -0,0 +1,37 @@
|
|||
%% 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 HTTP authentication.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is VMware, Inc.
|
||||
%% Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_auth_backend_cache_app).
|
||||
|
||||
-behaviour(application).
|
||||
-export([start/2, stop/1]).
|
||||
|
||||
-behaviour(supervisor).
|
||||
-export([init/1]).
|
||||
|
||||
start(_Type, _StartArgs) ->
|
||||
supervisor:start_link({local,?MODULE},?MODULE,[]).
|
||||
|
||||
stop(_State) ->
|
||||
ok.
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
init([]) ->
|
||||
{ok, AuthCache} = application:get_env(rabbitmq_auth_backend_cache,
|
||||
cache_module),
|
||||
{ok, {{one_for_one,3,10},[{auth_cache, {AuthCache, start_link, []},
|
||||
permanent, 5000, worker, [AuthCache]}]}}.
|
|
@ -0,0 +1,71 @@
|
|||
%% 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) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_auth_cache_dict).
|
||||
-behaviour(gen_server2).
|
||||
-compile({no_auto_import,[get/1]}).
|
||||
-compile({no_auto_import,[put/2]}).
|
||||
|
||||
-export([start_link/0,
|
||||
get/1, put/2, delete/1]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-record(state, {ttl}).
|
||||
|
||||
start_link() -> gen_server2:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
get(Key) -> gen_server2:call(?MODULE, {get, Key}).
|
||||
put(Key, Value) -> gen_server2:cast(?MODULE, {put, Key, Value}).
|
||||
delete(Key) -> gen_server2:call(?MODULE, {delete, Key}).
|
||||
|
||||
init(_Args) ->
|
||||
{ok, TTL} = application:get_env(rabbitmq_auth_backend_cache, cache_ttl),
|
||||
{ok, #state{ttl = TTL}}.
|
||||
|
||||
handle_call({get, Key}, _From, State = #state{}) ->
|
||||
Result = case erlang:get({item, Key}) of
|
||||
{ok, Val} -> {ok, Val};
|
||||
error -> {error, not_found}
|
||||
end,
|
||||
{reply, Result, State};
|
||||
handle_call({delete, Key}, _From, State = #state{}) ->
|
||||
do_delete(Key),
|
||||
{reply, ok, State}.
|
||||
|
||||
handle_cast({put, Key, Value}, State = #state{ttl = TTL}) ->
|
||||
erlang:put({items, Key}, Value),
|
||||
{ok, TRef} = timer:apply_after(TTL, auth_cache_dict, delete, Key),
|
||||
put({timers, Key}, TRef),
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
terminate(_Reason, State = #state{}) ->
|
||||
State.
|
||||
|
||||
do_delete(Key) ->
|
||||
erase({items, Key}),
|
||||
case get({timers, Key}) of
|
||||
{ok, Tref} -> erlang:cancel_timer(Tref),
|
||||
erase({timers, Key});
|
||||
error -> ok
|
||||
end.
|
|
@ -0,0 +1,86 @@
|
|||
%% 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) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_auth_cache_ets).
|
||||
-behaviour(gen_server2).
|
||||
-compile({no_auto_import,[get/1]}).
|
||||
-compile({no_auto_import,[put/2]}).
|
||||
-compile(export_all).
|
||||
|
||||
-export([start_link/0,
|
||||
get/1, put/2, delete/1]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-record(state, {cache, timers, ttl}).
|
||||
|
||||
start_link() -> gen_server2:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
get(Key) -> gen_server2:call(?MODULE, {get, Key}).
|
||||
put(Key, Value) -> gen_server2:cast(?MODULE, {put, Key, Value}).
|
||||
delete(Key) -> gen_server2:call(?MODULE, {delete, Key}).
|
||||
|
||||
init(_Args) ->
|
||||
{ok, TTL} = application:get_env(rabbitmq_auth_backend_cache, cache_ttl),
|
||||
{ok, #state{ttl = TTL,
|
||||
cache = ets:new(?MODULE, [set, private]),
|
||||
timers = ets:new(auth_cache_ets_timers, [set, private])}}.
|
||||
|
||||
handle_call({get, Key}, _From, State = #state{cache = Table}) ->
|
||||
Result = case ets:lookup(Table, Key) of
|
||||
[{Key, {Exp, Val}}] -> case expired(Exp) of
|
||||
true -> {error, not_found};
|
||||
false -> {ok, Val}
|
||||
end;
|
||||
[] -> {error, not_found}
|
||||
end,
|
||||
{reply, Result, State};
|
||||
handle_call({delete, Key}, _From, State = #state{cache = Table, timers = Timers}) ->
|
||||
do_delete(Key, Table, Timers),
|
||||
{reply, ok, State}.
|
||||
|
||||
handle_cast({put, Key, Value}, State = #state{cache = Table, ttl = TTL, timers = Timers}) ->
|
||||
do_delete(Key, Table, Timers),
|
||||
Expiration = expiration(TTL),
|
||||
ets:insert(Table, {Key, {Expiration, Value}}),
|
||||
{ok, TRef} = timer:apply_after(TTL, auth_cache_dict, delete, Key),
|
||||
ets:insert(Timers, {Key, TRef}),
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
terminate(_Reason, State = #state{}) ->
|
||||
State.
|
||||
|
||||
|
||||
do_delete(Key, Table, Timers) ->
|
||||
true = ets:delete(Table, Key),
|
||||
case ets:lookup(Timers, Key) of
|
||||
[{Key, Tref}] -> erlang:cancel_timer(Tref),
|
||||
true = ets:delete(Timers, Key);
|
||||
[] -> ok
|
||||
end.
|
||||
|
||||
expiration(TTL) ->
|
||||
time_compat:erlang_system_time(milli_seconds) + TTL.
|
||||
|
||||
expired(Exp) ->
|
||||
time_compat:erlang_system_time(milli_seconds) > Exp.
|
|
@ -0,0 +1,118 @@
|
|||
%% 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) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_auth_cache_ets_segmented).
|
||||
-behaviour(gen_server2).
|
||||
|
||||
-export([start_link/0,
|
||||
get/1, put/2, delete/1]).
|
||||
-export([gc/0]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-record(state, {boundary, old_segment, current_segment, garbage, gc_timer}).
|
||||
|
||||
start_link() -> gen_server2:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
get(Key) ->
|
||||
case get_from_segments(Key) of
|
||||
[] -> {error, not_found};
|
||||
[V|_] -> {ok, V}
|
||||
end.
|
||||
|
||||
put(Key, Value) ->
|
||||
TTL = cache_ttl(),
|
||||
Expiration = expiration(TTL),
|
||||
Segment = gen_server2:call(?MODULE, {get_write_segment, Expiration}),
|
||||
ets:insert(Segment, {Key, {Expiration, Value}}),
|
||||
ok.
|
||||
|
||||
delete(Key) ->
|
||||
[ets:delete(Table, Key) || Table <- gen_server2:call(?MODULE, get_segments)].
|
||||
|
||||
gc() ->
|
||||
case whereis(?MODULE) of
|
||||
undefined -> ok;
|
||||
Pid -> Pid ! gc
|
||||
end.
|
||||
|
||||
init(_Args) ->
|
||||
Segment = ets:new(segment, [set, protected]),
|
||||
SegmentSize = segment_size(),
|
||||
Boundary = expiration(SegmentSize),
|
||||
{ok, Timer} = timer:send_interval(SegmentSize * 2, gc),
|
||||
{ok, #state{boundary = Boundary, current_segment = Segment, garbage = [], gc_timer = Timer}}.
|
||||
|
||||
handle_call({get_write_segment, Expiration}, _From,
|
||||
State = #state{boundary = Boundary,
|
||||
current_segment = CurrentSegment,
|
||||
old_segment = OldSegment,
|
||||
garbage = Garbage}) when Boundary =< Expiration ->
|
||||
NewSegment = ets:new(segment, [set, protected]),
|
||||
NewBoundary = Boundary + segment_size(),
|
||||
{reply, NewSegment, State#state{boundary = NewBoundary,
|
||||
current_segment = NewSegment,
|
||||
old_segment = CurrentSegment,
|
||||
garbage = [OldSegment | Garbage]}};
|
||||
handle_call({get_write_segment, _}, _From, State = #state{current_segment = CurrentSegment}) ->
|
||||
{reply, CurrentSegment, State};
|
||||
handle_call(get_segments, _From, State = #state{old_segment = Old, current_segment = Current}) ->
|
||||
{reply, [Current, Old], State}.
|
||||
|
||||
handle_cast(_, State = #state{}) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(gc, State = #state{ garbage = Garbage }) ->
|
||||
[ets:delete(Segment) || Segment <- Garbage, Segment =/= undefined],
|
||||
{noreply, State#state{ garbage = [] }};
|
||||
handle_info(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
terminate(_Reason, State = #state{gc_timer = Timer}) ->
|
||||
erlang:cancel_timer(Timer),
|
||||
State.
|
||||
|
||||
segment_size() ->
|
||||
cache_ttl() * 2.
|
||||
|
||||
cache_ttl() ->
|
||||
application:get_env(rabbitmq_auth_backend_cache, cache_ttl).
|
||||
|
||||
expiration(TTL) ->
|
||||
time_compat:erlang_system_time(milliseconds) + TTL.
|
||||
|
||||
expired(Exp) ->
|
||||
time_compat:erlang_system_time(milliseconds) > Exp.
|
||||
|
||||
get_from_segments(Key) ->
|
||||
Segments = gen_server2:call(?MODULE, get_segments),
|
||||
lists:flatmap(
|
||||
fun(T) ->
|
||||
case ets:lookup(T, Key) of
|
||||
[{Key, {Exp, Val}}] ->
|
||||
case expired(Exp) of
|
||||
true -> [];
|
||||
false -> [Val]
|
||||
end;
|
||||
[] -> []
|
||||
end
|
||||
end,
|
||||
Segments).
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
%% -*- erlang -*-
|
||||
{application, rabbitmq_auth_backend_cache,
|
||||
[{description, "RabbitMQ Authentication Backend cache"},
|
||||
{vsn, ""},
|
||||
{modules, [rabbit_auth_backend_cache_app]},
|
||||
{registered, []},
|
||||
{mod, {rabbit_auth_backend_cache_app, []}},
|
||||
{env, [{cache_ttl, 15000},
|
||||
{cache_module, rabbit_auth_cache_ets},
|
||||
{cached_backend, rabbit_auth_backend_internal},
|
||||
{cache_refusals, false}] },
|
||||
{applications, [kernel, stdlib, rabbit_common]}]}.
|
Loading…
Reference in New Issue