Merge branch 'stable' into rabbitmq-management-236

This commit is contained in:
Jean-Sébastien Pédron 2016-09-27 12:49:01 +02:00
commit 3331c48ca7
11 changed files with 723 additions and 682 deletions

View File

@ -8,15 +8,23 @@ addons:
packages: packages:
- xsltproc - xsltproc
otp_release: otp_release:
- "R16B03-1" #- "R16B03-1" # sockjs doesn't build with R16B03
- "17.5" - "17.5"
- "18.0" - "18.0"
- "19.0"
# The checkout made by Travis is a "detached HEAD". We switch back # The checkout made by Travis is a "detached HEAD" and branches
# to a tag or a branch. This pleases our git_rmq fetch method in # information is missing. Our Erlang.mk's git_rmq fetch method relies on
# rabbitmq-components.mk and the proper tag/branch is selected in # it, so we need to restore it.
# dependencies too. #
before_script: (test "$TRAVIS_TAG" && git checkout "$TRAVIS_TAG") || (test "$TRAVIS_BRANCH" && git checkout "$TRAVIS_BRANCH") # We simply fetch master and, if it exists, stable branches. A branch is
# created, pointing to the detached HEAD.
before_script:
- |
git checkout -B "${TRAVIS_TAG:-${TRAVIS_BRANCH}}"
git remote add upstream https://github.com/$TRAVIS_REPO_SLUG.git
git fetch upstream stable:stable || :
git fetch upstream master:master || :
script: make tests script: make tests

View File

@ -1,13 +1,9 @@
PROJECT = rabbitmq_web_stomp PROJECT = rabbitmq_web_stomp
DEPS = cowboy sockjs rabbitmq_stomp DEPS = cowboy sockjs rabbit_common rabbit rabbitmq_stomp
TEST_DEPS := $(filter-out rabbitmq_test,$(TEST_DEPS)) TEST_DEPS = rabbitmq_ct_helpers
dep_cowboy_commit = 1.0.3 dep_cowboy_commit = 1.0.3
# FIXME: Add Ranch as a BUILD_DEPS to be sure the correct version is picked.
# See rabbitmq-components.mk.
BUILD_DEPS += ranch
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
# FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be # FIXME: Use erlang.mk patched for RabbitMQ, while waiting for PRs to be

View File

@ -1,43 +0,0 @@
# 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

View File

@ -5,16 +5,6 @@ ifeq ($(.DEFAULT_GOAL),)
.DEFAULT_GOAL = all .DEFAULT_GOAL = all
endif 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. # RabbitMQ components.
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -38,6 +28,7 @@ dep_rabbitmq_boot_steps_visualiser = git_rmq rabbitmq-boot-steps-visualiser $
dep_rabbitmq_clusterer = git_rmq rabbitmq-clusterer $(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_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_consistent_hash_exchange = git_rmq rabbitmq-consistent-hash-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_ct_helpers = git_rmq rabbitmq-ct-helpers $(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_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_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_event_exchange = git_rmq rabbitmq-event-exchange $(current_rmq_ref) $(base_rmq_ref) master
@ -59,6 +50,7 @@ dep_rabbitmq_objc_client = git_rmq rabbitmq-objc-client $(current_r
dep_rabbitmq_recent_history_exchange = git_rmq rabbitmq-recent-history-exchange $(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_routing_node_stamp = git_rmq rabbitmq-routing-node-stamp $(current_rmq_ref) $(base_rmq_ref) master dep_rabbitmq_routing_node_stamp = git_rmq rabbitmq-routing-node-stamp $(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_rtopic_exchange = git_rmq rabbitmq-rtopic-exchange $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_server_release = git_rmq rabbitmq-server-release $(current_rmq_ref) $(base_rmq_ref) master
dep_rabbitmq_sharding = git_rmq rabbitmq-sharding $(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 = 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_shovel_management = git_rmq rabbitmq-shovel-management $(current_rmq_ref) $(base_rmq_ref) master
@ -98,6 +90,7 @@ RABBITMQ_COMPONENTS = amqp_client \
rabbitmq_clusterer \ rabbitmq_clusterer \
rabbitmq_codegen \ rabbitmq_codegen \
rabbitmq_consistent_hash_exchange \ rabbitmq_consistent_hash_exchange \
rabbitmq_ct_helpers \
rabbitmq_delayed_message_exchange \ rabbitmq_delayed_message_exchange \
rabbitmq_dotnet_client \ rabbitmq_dotnet_client \
rabbitmq_event_exchange \ rabbitmq_event_exchange \
@ -119,11 +112,11 @@ RABBITMQ_COMPONENTS = amqp_client \
rabbitmq_recent_history_exchange \ rabbitmq_recent_history_exchange \
rabbitmq_routing_node_stamp \ rabbitmq_routing_node_stamp \
rabbitmq_rtopic_exchange \ rabbitmq_rtopic_exchange \
rabbitmq_server_release \
rabbitmq_sharding \ rabbitmq_sharding \
rabbitmq_shovel \ rabbitmq_shovel \
rabbitmq_shovel_management \ rabbitmq_shovel_management \
rabbitmq_stomp \ rabbitmq_stomp \
rabbitmq_test \
rabbitmq_toke \ rabbitmq_toke \
rabbitmq_top \ rabbitmq_top \
rabbitmq_tracing \ rabbitmq_tracing \
@ -246,59 +239,10 @@ list-dist-deps::
prepare-dist:: 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. # 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) # 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 # to point to the Umbrella's one. We also disable `make distclean` so
# $(DEPS_DIR) is not accidentally removed. # $(DEPS_DIR) is not accidentally removed.
@ -312,11 +256,6 @@ endif
ifeq ($(UNDER_UMBRELLA),1) ifeq ($(UNDER_UMBRELLA),1)
ifneq ($(PROJECT),rabbitmq_public_umbrella) ifneq ($(PROJECT),rabbitmq_public_umbrella)
DEPS_DIR ?= $(abspath ..) DEPS_DIR ?= $(abspath ..)
distclean:: distclean-components
@:
distclean-components:
endif endif
ifneq ($(filter distclean distclean-deps,$(MAKECMDGOALS)),) ifneq ($(filter distclean distclean-deps,$(MAKECMDGOALS)),)

View File

@ -67,22 +67,19 @@ init_processor_state(Conn) ->
StompConfig = case UseHTTPAuth of StompConfig = case UseHTTPAuth of
true -> true ->
{Login, PassCode} = case lists:keyfind(authorization, 1, Headers) of case lists:keyfind(authorization, 1, Headers) of
false -> false ->
%% We fall back to the default STOMP credentials. %% We fall back to the default STOMP credentials.
UserConfig = application:get_env(rabbitmq_stomp, StompConfig0;
default_user, []),
{proplists:get_value(login, UserConfig),
proplists:get_value(passcode, UserConfig)};
{_, AuthHd} -> {_, AuthHd} ->
{<<"basic">>, {HTTPLogin, HTTPPassCode}} {<<"basic">>, {HTTPLogin, HTTPPassCode}}
= cowboy_http:token_ci(list_to_binary(AuthHd), = cowboy_http:token_ci(list_to_binary(AuthHd),
fun cowboy_http:authorization/2), fun cowboy_http:authorization/2),
{HTTPLogin, HTTPPassCode} StompConfig0#stomp_configuration{
end, default_login = HTTPLogin,
StompConfig0#stomp_configuration{default_login = Login, default_passcode = HTTPPassCode,
default_passcode = PassCode, force_default_creds = true}
force_default_creds = true}; end;
false -> false ->
StompConfig0 StompConfig0
end, end,
@ -96,7 +93,7 @@ init_processor_state(Conn) ->
additional_info=[{state, running}|Extra]}, additional_info=[{state, running}|Extra]},
ProcessorState = rabbit_stomp_processor:initial_state( ProcessorState = rabbit_stomp_processor:initial_state(
StompConfig, StompConfig,
{SendFun, AdapterInfo, none, PeerAddr}), {SendFun, AdapterInfo, none, PeerAddr}),
{ok, ProcessorState}. {ok, ProcessorState}.
@ -136,8 +133,8 @@ handle_info(#'basic.cancel_ok'{}, State) ->
{noreply, State}; {noreply, State};
handle_info(#'basic.ack'{delivery_tag = Tag, multiple = IsMulti}, State) -> handle_info(#'basic.ack'{delivery_tag = Tag, multiple = IsMulti}, State) ->
ProcState = processor_state(State), ProcState = processor_state(State),
NewProcState = rabbit_stomp_processor:flush_pending_receipts(Tag, NewProcState = rabbit_stomp_processor:flush_pending_receipts(Tag,
IsMulti, IsMulti,
ProcState), ProcState),
{noreply, processor_state(NewProcState, State)}; {noreply, processor_state(NewProcState, State)};
handle_info({Delivery = #'basic.deliver'{}, handle_info({Delivery = #'basic.deliver'{},
@ -145,9 +142,9 @@ handle_info({Delivery = #'basic.deliver'{},
DeliveryCtx}, DeliveryCtx},
State) -> State) ->
ProcState = processor_state(State), ProcState = processor_state(State),
NewProcState = rabbit_stomp_processor:send_delivery(Delivery, NewProcState = rabbit_stomp_processor:send_delivery(Delivery,
Props, Props,
Payload, Payload,
DeliveryCtx, DeliveryCtx,
ProcState), ProcState),
{noreply, processor_state(NewProcState, State)}; {noreply, processor_state(NewProcState, State)};
@ -160,14 +157,14 @@ handle_info(#'basic.cancel'{consumer_tag = Ctag}, State) ->
{stop, Reason, processor_state(NewProcState, State)} {stop, Reason, processor_state(NewProcState, State)}
end; end;
handle_info({start_heartbeats, _}, handle_info({start_heartbeats, _},
State = #state{heartbeat_mode = no_heartbeat}) -> State = #state{heartbeat_mode = no_heartbeat}) ->
{noreply, State}; {noreply, State};
handle_info({start_heartbeats, {0, 0}}, State) -> handle_info({start_heartbeats, {0, 0}}, State) ->
{noreply, State}; {noreply, State};
handle_info({start_heartbeats, {SendTimeout, ReceiveTimeout}}, handle_info({start_heartbeats, {SendTimeout, ReceiveTimeout}},
State = #state{conn = Conn, State = #state{conn = Conn,
heartbeat_sup = SupPid, heartbeat_sup = SupPid,
heartbeat_mode = heartbeat}) -> heartbeat_mode = heartbeat}) ->
Info = Conn:info(), Info = Conn:info(),
@ -187,7 +184,7 @@ handle_info({'EXIT', From, Reason}, State) ->
case rabbit_stomp_processor:handle_exit(From, Reason, ProcState) of case rabbit_stomp_processor:handle_exit(From, Reason, ProcState) of
{stop, Reason, NewProcState} -> {stop, Reason, NewProcState} ->
{stop, Reason, processor_state(NewProcState, State)}; {stop, Reason, processor_state(NewProcState, State)};
unknown_exit -> unknown_exit ->
{stop, {connection_died, Reason}, State} {stop, {connection_died, Reason}, State}
end; end;
%%---------------------------------------------------------------------------- %%----------------------------------------------------------------------------
@ -232,7 +229,7 @@ process_received_bytes(Bytes, ProcessorState, ParseState, ConnPid) ->
end. end.
processor_state(#state{ proc_state = ProcState }) -> ProcState. processor_state(#state{ proc_state = ProcState }) -> ProcState.
processor_state(ProcState, #state{} = State) -> processor_state(ProcState, #state{} = State) ->
State#state{ proc_state = ProcState}. State#state{ proc_state = ProcState}.
%%---------------------------------------------------------------------------- %%----------------------------------------------------------------------------

View File

@ -14,5 +14,5 @@
{sockjs_opts, []}, {sockjs_opts, []},
{ws_frame, text}, {ws_frame, text},
{use_http_auth, false}]}, {use_http_auth, false}]},
{applications, [kernel, stdlib, rabbit, rabbitmq_stomp, cowboy, sockjs]} {applications, [kernel, stdlib, rabbit_common, rabbit, rabbitmq_stomp, cowboy, sockjs]}
]}. ]}.

View File

@ -36,10 +36,11 @@ init_per_suite(Config) ->
[{rmq_nodename_suffix, ?MODULE}]), [{rmq_nodename_suffix, ?MODULE}]),
rabbit_ct_helpers:log_environment(), rabbit_ct_helpers:log_environment(),
rabbit_ct_helpers:run_setup_steps(Config1, rabbit_ct_helpers:run_setup_steps(Config1,
rabbit_ct_broker_helpers:setup_steps()). rabbit_ct_broker_helpers:setup_steps()).
end_per_suite(Config) -> end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config). rabbit_ct_helpers:run_teardown_steps(Config,
rabbit_ct_broker_helpers:teardown_steps()).
init_per_testcase(pubsub_binary, Config) -> init_per_testcase(pubsub_binary, Config) ->
rabbit_ws_test_util:update_app_env(Config, ws_frame, binary), rabbit_ws_test_util:update_app_env(Config, ws_frame, binary),
@ -165,4 +166,4 @@ http_auth(Config) ->
{ok, _} = rfc6455_client:open(WS2), {ok, _} = rfc6455_client:open(WS2),
ok = raw_send(WS2, "CONNECT", [{"login", "bad"}, {"passcode", "bad"}]), ok = raw_send(WS2, "CONNECT", [{"login", "bad"}, {"passcode", "bad"}]),
{<<"ERROR">>, _, _} = raw_recv(WS2), {<<"ERROR">>, _, _} = raw_recv(WS2),
{close, _} = rfc6455_client:close(WS2). {close, _} = rfc6455_client:close(WS2).

View File

@ -37,10 +37,11 @@ init_per_suite(Config) ->
[{rmq_nodename_suffix, ?MODULE}]), [{rmq_nodename_suffix, ?MODULE}]),
rabbit_ct_helpers:log_environment(), rabbit_ct_helpers:log_environment(),
rabbit_ct_helpers:run_setup_steps(Config1, rabbit_ct_helpers:run_setup_steps(Config1,
rabbit_ct_broker_helpers:setup_steps()). rabbit_ct_broker_helpers:setup_steps()).
end_per_suite(Config) -> end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config). rabbit_ct_helpers:run_teardown_steps(Config,
rabbit_ct_broker_helpers:teardown_steps()).
init_per_testcase(http_auth, Config) -> init_per_testcase(http_auth, Config) ->
rabbit_ws_test_util:update_app_env(Config, use_http_auth, true), rabbit_ws_test_util:update_app_env(Config, use_http_auth, true),

View File

@ -35,10 +35,11 @@ init_per_suite(Config) ->
[{rmq_nodename_suffix, ?MODULE}]), [{rmq_nodename_suffix, ?MODULE}]),
rabbit_ct_helpers:log_environment(), rabbit_ct_helpers:log_environment(),
rabbit_ct_helpers:run_setup_steps(Config1, rabbit_ct_helpers:run_setup_steps(Config1,
rabbit_ct_broker_helpers:setup_steps()). rabbit_ct_broker_helpers:setup_steps()).
end_per_suite(Config) -> end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config). rabbit_ct_helpers:run_teardown_steps(Config,
rabbit_ct_broker_helpers:teardown_steps()).
init_per_testcase(http_auth, Config) -> init_per_testcase(http_auth, Config) ->
rabbit_ws_test_util:update_app_env(Config, use_http_auth, true), rabbit_ws_test_util:update_app_env(Config, use_http_auth, true),
@ -75,7 +76,9 @@ sjs_recv(WS) ->
{ok, stomp:unmarshal(StompFrame)}; {ok, stomp:unmarshal(StompFrame)};
<<"c", JsonArr/binary>> -> <<"c", JsonArr/binary>> ->
{ok, CloseReason} = sockjs_json:decode(JsonArr), {ok, CloseReason} = sockjs_json:decode(JsonArr),
{close, CloseReason} {close, CloseReason};
<<"h">> ->
sjs_recv(WS)
end. end.
pubsub(Config) -> pubsub(Config) ->

View File

@ -68,10 +68,6 @@ send(WS, IoData) ->
WS ! {send, IoData}, WS ! {send, IoData},
ok. ok.
send_binary(WS, IoData) ->
WS ! {send_binary, IoData},
ok.
close(WS) -> close(WS) ->
close(WS, {1000, ""}). close(WS, {1000, ""}).
@ -176,7 +172,7 @@ do_recv2(State = #state{phase = Phase, socket = Socket, ppid = PPid}, R) ->
ok ok
end, end,
die(Socket, PPid, WsReason, normal); die(Socket, PPid, WsReason, normal);
{_, _, _, Rest2} -> {_, _, _, _Rest} ->
io:format("Unknown frame type~n"), io:format("Unknown frame type~n"),
die(Socket, PPid, {1006, "Unknown frame type"}, normal) die(Socket, PPid, {1006, "Unknown frame type"}, normal)
end. end.
@ -200,10 +196,6 @@ do_send(State = #state{socket = Socket}, Payload) ->
gen_tcp:send(Socket, encode_frame(1, 1, Payload)), gen_tcp:send(Socket, encode_frame(1, 1, Payload)),
State. State.
do_send_binary(State = #state{socket = Socket}, Payload) ->
gen_tcp:send(Socket, encode_frame(1, 2, Payload)),
State.
do_close(State = #state{socket = Socket}, {Code, Reason}) -> do_close(State = #state{socket = Socket}, {Code, Reason}) ->
Payload = iolist_to_binary([<<Code:16>>, Reason]), Payload = iolist_to_binary([<<Code:16>>, Reason]),
gen_tcp:send(Socket, encode_frame(1, 8, Payload)), gen_tcp:send(Socket, encode_frame(1, 8, Payload)),
@ -218,8 +210,6 @@ loop(State = #state{socket = Socket, ppid = PPid, data = Data,
loop(do_recv(State1)); loop(do_recv(State1));
{send, Payload} when Phase == open -> {send, Payload} when Phase == open ->
loop(do_send(State, Payload)); loop(do_send(State, Payload));
{send_binary, Payload} when Phase == open ->
loop(do_send_binary(State, Payload));
{tcp_closed, Socket} -> {tcp_closed, Socket} ->
die(Socket, PPid, {1006, "Connection closed abnormally"}, normal); die(Socket, PPid, {1006, "Connection closed abnormally"}, normal);
{close, WsReason} when Phase == open -> {close, WsReason} when Phase == open ->