summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2010-06-24 16:55:14 +0100
committerSimon MacMullen <simon@rabbitmq.com>2010-06-24 16:55:14 +0100
commit6ffed4950c8e99d33858b615dd4ea144fe6cdc61 (patch)
tree8f0dbdfcf7cf9874d9cafa850df62e66a7d5985c
parentc66e8d1f66a0bdbba4a5584d62cd98eb6837b642 (diff)
downloadrabbitmq-server-6ffed4950c8e99d33858b615dd4ea144fe6cdc61.tar.gz
Codegen up two different versions of rabbit_framing and provide a dispatcher to choose. The codegen now builds header files that are the union of 0-8 and 0-9-1.
-rw-r--r--.hgignore2
-rw-r--r--Makefile22
-rw-r--r--codegen.py9
-rw-r--r--src/rabbit_basic.erl8
-rw-r--r--src/rabbit_binary_generator.erl14
-rw-r--r--src/rabbit_channel.erl6
-rw-r--r--src/rabbit_framing.erl102
-rw-r--r--src/rabbit_framing_channel.erl22
-rw-r--r--src/rabbit_reader.erl26
-rw-r--r--src/rabbit_tests.erl2
10 files changed, 150 insertions, 63 deletions
diff --git a/.hgignore b/.hgignore
index 7b796b66..03b60914 100644
--- a/.hgignore
+++ b/.hgignore
@@ -11,7 +11,7 @@ syntax: regexp
^dist/
^include/rabbit_framing\.hrl$
^include/rabbit_framing_spec\.hrl$
-^src/rabbit_framing\.erl$
+^src/rabbit_framing_amqp.*\.erl$
^src/.*\_usage.erl$
^rabbit\.plt$
^basic.plt$
diff --git a/Makefile b/Makefile
index d715db74..102fe1fb 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ EBIN_DIR=ebin
INCLUDE_DIR=include
DOCS_DIR=docs
INCLUDES=$(wildcard $(INCLUDE_DIR)/*.hrl) $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl
-SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) $(SOURCE_DIR)/rabbit_framing.erl $(USAGES_ERL)
+SOURCES=$(wildcard $(SOURCE_DIR)/*.erl) $(SOURCE_DIR)/rabbit_framing_amqp_0_9_1.erl $(SOURCE_DIR)/rabbit_framing_amqp_0_8.erl $(USAGES_ERL)
BEAM_TARGETS=$(patsubst $(SOURCE_DIR)/%.erl, $(EBIN_DIR)/%.beam, $(SOURCES))
TARGETS=$(EBIN_DIR)/rabbit.app $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl $(BEAM_TARGETS)
WEB_URL=http://stage.rabbitmq.com/
@@ -56,7 +56,8 @@ TARGET_SRC_DIR=dist/$(TARBALL_NAME)
SIBLING_CODEGEN_DIR=../rabbitmq-codegen/
AMQP_CODEGEN_DIR=$(shell [ -d $(SIBLING_CODEGEN_DIR) ] && echo $(SIBLING_CODEGEN_DIR) || echo codegen)
-AMQP_SPEC_JSON_FILES=$(AMQP_CODEGEN_DIR)/amqp-rabbitmq.json
+AMQP_SPEC_JSON_FILES_0_9_1=$(AMQP_CODEGEN_DIR)/amqp-rabbitmq.json
+AMQP_SPEC_JSON_FILES_0_8=$(AMQP_CODEGEN_DIR)/amqp-0.8.json $(AMQP_CODEGEN_DIR)/rabbitmq-0.8-extensions.json
ERL_CALL=erl_call -sname $(RABBITMQ_NODENAME) -e
@@ -87,14 +88,17 @@ $(EBIN_DIR)/rabbit.app: $(EBIN_DIR)/rabbit_app.in $(BEAM_TARGETS) generate_app
$(EBIN_DIR)/%.beam:
erlc $(ERLC_OPTS) -pa $(EBIN_DIR) $<
-$(INCLUDE_DIR)/rabbit_framing.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
- $(PYTHON) codegen.py header $(AMQP_SPEC_JSON_FILES) $@
+$(INCLUDE_DIR)/rabbit_framing.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES_0_9_1)
+ $(PYTHON) codegen.py header $(AMQP_SPEC_JSON_FILES_0_9_1) $(AMQP_SPEC_JSON_FILES_0_8) $@
-$(INCLUDE_DIR)/rabbit_framing_spec.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
- $(PYTHON) codegen.py spec $(AMQP_SPEC_JSON_FILES) $@
+$(INCLUDE_DIR)/rabbit_framing_spec.hrl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES_0_9_1)
+ $(PYTHON) codegen.py spec $(AMQP_SPEC_JSON_FILES_0_9_1) $(AMQP_SPEC_JSON_FILES_0_8) $@
-$(SOURCE_DIR)/rabbit_framing.erl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES)
- $(PYTHON) codegen.py body $(AMQP_SPEC_JSON_FILES) $@
+$(SOURCE_DIR)/rabbit_framing_amqp_0_9_1.erl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES_0_9_1)
+ $(PYTHON) codegen.py body $(AMQP_SPEC_JSON_FILES_0_9_1) $@
+
+$(SOURCE_DIR)/rabbit_framing_amqp_0_8.erl: codegen.py $(AMQP_CODEGEN_DIR)/amqp_codegen.py $(AMQP_SPEC_JSON_FILES_0_8)
+ $(PYTHON) codegen.py body $(AMQP_SPEC_JSON_FILES_0_8) $@
dialyze: $(BEAM_TARGETS) $(BASIC_PLT)
$(ERL_EBIN) -eval \
@@ -119,7 +123,7 @@ $(BASIC_PLT): $(BEAM_TARGETS)
clean:
rm -f $(EBIN_DIR)/*.beam
rm -f $(EBIN_DIR)/rabbit.app $(EBIN_DIR)/rabbit.boot $(EBIN_DIR)/rabbit.script $(EBIN_DIR)/rabbit.rel
- rm -f $(INCLUDE_DIR)/rabbit_framing.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl $(SOURCE_DIR)/rabbit_framing.erl codegen.pyc
+ rm -f $(INCLUDE_DIR)/rabbit_framing*.hrl $(INCLUDE_DIR)/rabbit_framing_spec.hrl $(SOURCE_DIR)/rabbit_framing_amqp_*.erl codegen.pyc
rm -f $(DOCS_DIR)/*.[0-9].gz $(DOCS_DIR)/*.man.xml $(DOCS_DIR)/*.erl $(USAGES_ERL)
rm -f $(RABBIT_PLT)
rm -f $(DEPS_FILE)
diff --git a/codegen.py b/codegen.py
index 467b0285..9596f5b1 100644
--- a/codegen.py
+++ b/codegen.py
@@ -315,8 +315,13 @@ def genErl(spec):
methods = spec.allMethods()
printFileHeader()
- print """-module(rabbit_framing).
--include("rabbit_framing.hrl").
+ module = "rabbit_framing_amqp_%d_%d" % (spec.major, spec.minor)
+ if spec.revision != '0':
+ module = "%s_%d" % (module, spec.revision)
+ if module == "rabbit_framing_amqp_8_0":
+ module = "rabbit_framing_amqp_0_8"
+ print "-module(%s)." % module
+ print """-include("rabbit_framing.hrl").
-export([lookup_method_name/1]).
diff --git a/src/rabbit_basic.erl b/src/rabbit_basic.erl
index 4ab7a2a0..5e2d7d9a 100644
--- a/src/rabbit_basic.erl
+++ b/src/rabbit_basic.erl
@@ -80,7 +80,9 @@ delivery(Mandatory, Immediate, Txn, Message) ->
sender = self(), message = Message}.
build_content(Properties, BodyBin) ->
- {ClassId, _MethodId} = rabbit_framing:method_id('basic.publish'),
+ %% TODO - is this ever used? If so remove hard coded amqp_0_9_1
+ {ClassId, _MethodId} =
+ rabbit_framing:method_id('basic.publish', amqp_0_9_1),
#content{class_id = ClassId,
properties = Properties,
properties_bin = none,
@@ -91,7 +93,9 @@ from_content(Content) ->
properties = Props,
payload_fragments_rev = FragmentsRev} =
rabbit_binary_parser:ensure_content_decoded(Content),
- {ClassId, _MethodId} = rabbit_framing:method_id('basic.publish'),
+ %% TODO - is this ever used? If so remove hard coded amqp_0_9_1
+ {ClassId, _MethodId} =
+ rabbit_framing:method_id('basic.publish', amqp_0_9_1),
{Props, list_to_binary(lists:reverse(FragmentsRev))}.
message(ExchangeName, RoutingKeyBin, RawProperties, BodyBin) ->
diff --git a/src/rabbit_binary_generator.erl b/src/rabbit_binary_generator.erl
index 28f34e7c..04251d11 100644
--- a/src/rabbit_binary_generator.erl
+++ b/src/rabbit_binary_generator.erl
@@ -72,19 +72,11 @@
%%----------------------------------------------------------------------------
build_simple_method_frame(ChannelInt, MethodRecord, Protocol) ->
- MethodFields = rabbit_framing:encode_method_fields(MethodRecord),
- MethodName = adjust_close(rabbit_misc:method_record_type(MethodRecord),
- Protocol),
- {ClassId, MethodId} = rabbit_framing:method_id(MethodName),
+ MethodFields = rabbit_framing:encode_method_fields(MethodRecord, Protocol),
+ MethodName = rabbit_misc:method_record_type(MethodRecord),
+ {ClassId, MethodId} = rabbit_framing:method_id(MethodName, Protocol),
create_frame(1, ChannelInt, [<<ClassId:16, MethodId:16>>, MethodFields]).
-adjust_close('connection.close', amqp_0_8) ->
- 'connection.close08';
-adjust_close('connection.close_ok', amqp_0_8) ->
- 'connection.close08_ok';
-adjust_close(MethodName, _Protocol) ->
- MethodName.
-
build_simple_content_frames(ChannelInt,
#content{class_id = ClassId,
properties = ContentProperties,
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index 7c0b94d4..d337df29 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -499,7 +499,7 @@ handle_method(#'basic.get'{queue = QueueNameBin,
Content),
{noreply, State1#ch{next_tag = DeliveryTag + 1}};
empty ->
- {reply, #'basic.get_empty'{deprecated_cluster_id = <<>>}, State}
+ {reply, #'basic.get_empty'{cluster_id = <<>>}, State}
end;
handle_method(#'basic.consume'{queue = QueueNameBin,
@@ -656,8 +656,8 @@ handle_method(#'exchange.declare'{exchange = ExchangeNameBin,
type = TypeNameBin,
passive = false,
durable = Durable,
- deprecated_auto_delete = AutoDelete,
- deprecated_internal = false,
+ auto_delete = AutoDelete,
+ internal = false,
nowait = NoWait,
arguments = Args},
_, State = #ch{ virtual_host = VHostPath }) ->
diff --git a/src/rabbit_framing.erl b/src/rabbit_framing.erl
new file mode 100644
index 00000000..2d4d1ce4
--- /dev/null
+++ b/src/rabbit_framing.erl
@@ -0,0 +1,102 @@
+%% 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 Developers of the Original Code are LShift Ltd,
+%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
+%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
+%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
+%% Technologies LLC, and Rabbit Technologies Ltd.
+%%
+%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+%% Ltd. Portions created by Cohesive Financial Technologies LLC are
+%% Copyright (C) 2007-2010 Cohesive Financial Technologies
+%% LLC. Portions created by Rabbit Technologies Ltd are Copyright
+%% (C) 2007-2010 Rabbit Technologies Ltd.
+%%
+%% All Rights Reserved.
+%%
+%% Contributor(s): ______________________________________.
+%%
+-module(rabbit_framing).
+-include("rabbit.hrl").
+-include("rabbit_framing.hrl").
+
+
+-export([encode_method_fields/2]).
+-export([decode_method_fields/3]).
+-export([lookup_method_name/2]).
+-export([method_id/2]).
+
+-export([method_has_content/1]).
+-export([is_method_synchronous/1]).
+-export([method_record/1]).
+-export([method_fieldnames/1]).
+-export([decode_properties/2]).
+-export([encode_properties/1]).
+-export([lookup_amqp_exception/1]).
+-export([amqp_exception/1]).
+
+%% Method signatures
+-ifdef(use_specs).
+-spec(encode_method_fields/2 :: (amqp_method_record(), protocol()) -> binary()).
+-spec(decode_method_fields/3 :: (amqp_method_name(), binary(), protocol()) ->
+ amqp_method_record()).
+-spec(lookup_method_name/2 :: (amqp_method(), protocol()) ->
+ amqp_method_name()).
+-spec(method_id/2 :: (amqp_method_name(), protocol()) -> amqp_method()).
+
+-spec(method_has_content/1 :: (amqp_method_name()) -> boolean()).
+-spec(is_method_synchronous/1 :: (amqp_method_record()) -> boolean()).
+-spec(method_record/1 :: (amqp_method_name()) -> amqp_method_record()).
+-spec(method_fieldnames/1 :: (amqp_method_name()) ->
+ [amqp_method_field_name()]).
+-spec(decode_properties/2 :: (non_neg_integer(), binary()) ->
+ amqp_property_record()).
+-spec(encode_properties/1 :: (amqp_method_record()) -> binary()).
+-spec(lookup_amqp_exception/1 ::
+ (amqp_exception()) -> {boolean(), amqp_exception_code(), binary()}).
+-spec(amqp_exception/1 :: (amqp_exception_code()) -> amqp_exception()).
+-endif. % use_specs
+
+encode_method_fields(MethodRecord, amqp_0_9_1) ->
+ rabbit_framing_amqp_0_9_1:encode_method_fields(MethodRecord);
+encode_method_fields(MethodRecord, amqp_0_8) ->
+ rabbit_framing_amqp_0_8:encode_method_fields(MethodRecord).
+
+decode_method_fields(MethodName, FieldsBin, amqp_0_9_1) ->
+ rabbit_framing_amqp_0_9_1:decode_method_fields(MethodName, FieldsBin);
+decode_method_fields(MethodName, FieldsBin, amqp_0_8) ->
+ rabbit_framing_amqp_0_8:decode_method_fields(MethodName, FieldsBin).
+
+lookup_method_name(ClassMethod, amqp_0_9_1) ->
+ rabbit_framing_amqp_0_9_1:lookup_method_name(ClassMethod);
+lookup_method_name(ClassMethod, amqp_0_8) ->
+ rabbit_framing_amqp_0_8:lookup_method_name(ClassMethod).
+
+method_id(MethodName, amqp_0_9_1) ->
+ rabbit_framing_amqp_0_9_1:method_id(MethodName);
+method_id(MethodName, amqp_0_8) ->
+ rabbit_framing_amqp_0_8:method_id(MethodName).
+
+
+
+%% These ones don't make any difference, let's just use 0-9-1.
+method_has_content(X) -> rabbit_framing_amqp_0_9_1:method_has_content(X).
+method_record(X) -> rabbit_framing_amqp_0_9_1:method_record(X).
+method_fieldnames(X) -> rabbit_framing_amqp_0_9_1:method_fieldnames(X).
+encode_properties(X) -> rabbit_framing_amqp_0_9_1:encode_properties(X).
+amqp_exception(X) -> rabbit_framing_amqp_0_9_1:amqp_exception(X).
+lookup_amqp_exception(X) -> rabbit_framing_amqp_0_9_1:lookup_amqp_exception(X).
+is_method_synchronous(X) -> rabbit_framing_amqp_0_9_1:is_method_synchronous(X).
+decode_properties(X, Y) -> rabbit_framing_amqp_0_9_1:decode_properties(X, Y).
diff --git a/src/rabbit_framing_channel.erl b/src/rabbit_framing_channel.erl
index 648a3fdd..c30cf451 100644
--- a/src/rabbit_framing_channel.erl
+++ b/src/rabbit_framing_channel.erl
@@ -74,7 +74,8 @@ read_frame(ChannelPid) ->
mainloop(ChannelPid, Protocol) ->
{method, MethodName, FieldsBin} = read_frame(ChannelPid),
- Method = decode_method_fields(MethodName, FieldsBin, Protocol),
+ Method = rabbit_framing:decode_method_fields(MethodName, FieldsBin,
+ Protocol),
case rabbit_framing:method_has_content(MethodName) of
true -> rabbit_channel:do(ChannelPid, Method,
collect_content(ChannelPid, MethodName));
@@ -82,24 +83,9 @@ mainloop(ChannelPid, Protocol) ->
end,
?MODULE:mainloop(ChannelPid, Protocol).
-%% Handle 0-8 version of channel.open-ok. In 0-9-1 it gained a longstr
-%% "deprecated_channel_id".
-decode_method_fields('channel.open_ok', FieldsBin, amqp_0_8) ->
- Len = 0,
- rabbit_framing:decode_method_fields(
- 'channel.open_ok', <<FieldsBin/binary, Len:32/unsigned>>);
-%% Handle 0-8 version of basic.consume. In 0-9-1 it gained a table
-%% "filter".
-decode_method_fields('basic.consume', FieldsBin, amqp_0_8) ->
- T = rabbit_binary_generator:generate_table([]),
- TLen = size(T),
- rabbit_framing:decode_method_fields(
- 'basic.consume', <<FieldsBin/binary, TLen:32/unsigned, T:TLen/binary>>);
-decode_method_fields(MethodName, FieldsBin, _Protocol) ->
- rabbit_framing:decode_method_fields(MethodName, FieldsBin).
-
collect_content(ChannelPid, MethodName) ->
- {ClassId, _MethodId} = rabbit_framing:method_id(MethodName),
+ %% Protocol does not matter as we only want the class ID to match
+ {ClassId, _MethodId} = rabbit_framing:method_id(MethodName, amqp_0_9_1),
case read_frame(ChannelPid) of
{content_header, HeaderClassId, 0, BodySize, PropertiesBin} ->
if HeaderClassId == ClassId ->
diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl
index 98b4d647..c324d008 100644
--- a/src/rabbit_reader.erl
+++ b/src/rabbit_reader.erl
@@ -508,9 +508,7 @@ handle_frame(Type, Channel, Payload,
analyze_frame(?FRAME_METHOD, <<ClassId:16, MethodId:16, MethodFields/binary>>,
Protocol) ->
- {method, adjust_close(
- rabbit_framing:lookup_method_name({ClassId, MethodId}),
- Protocol),
+ {method, rabbit_framing:lookup_method_name({ClassId, MethodId}, Protocol),
MethodFields};
analyze_frame(?FRAME_HEADER,
<<ClassId:16, Weight:16, BodySize:64, Properties/binary>>,
@@ -523,13 +521,6 @@ analyze_frame(?FRAME_HEARTBEAT, <<>>, _Protocol) ->
analyze_frame(_Type, _Body, _Protocol) ->
error.
-adjust_close('connection.close08', amqp_0_8) ->
- 'connection.close';
-adjust_close('connection.close08_ok', amqp_0_8) ->
- 'connection.close_ok';
-adjust_close(MethodName, _Protocol) ->
- MethodName.
-
handle_input(frame_header, <<Type:8,Channel:16,PayloadSize:32>>, State) ->
%%?LOGDEBUG("Got frame header: ~p/~p/~p~n", [Type, Channel, PayloadSize]),
{State, {frame_payload, Type, Channel, PayloadSize}, PayloadSize + 1};
@@ -589,10 +580,11 @@ check_version(ClientVersion, ServerVersion) ->
%%--------------------------------------------------------------------------
-handle_method0(MethodName, FieldsBin, State) ->
+handle_method0(MethodName, FieldsBin,
+ State = #v1{connection = #connection{protocol = Protocol}}) ->
try
handle_method0(rabbit_framing:decode_method_fields(
- MethodName, FieldsBin),
+ MethodName, FieldsBin, Protocol),
State)
catch exit:Reason ->
CompleteReason = case Reason of
@@ -653,7 +645,7 @@ handle_method0(#'connection.open'{virtual_host = VHostPath},
NewConnection = Connection#connection{vhost = VHostPath},
ok = send_on_channel0(
Sock,
- #'connection.open_ok'{deprecated_known_hosts = <<>>},
+ #'connection.open_ok'{known_hosts = <<>>},
Protocol),
State#v1{connection_state = running,
connection = NewConnection};
@@ -755,7 +747,8 @@ handle_exception(State = #v1{connection_state = CS}, Channel, Reason) ->
send_exception(State = #v1{connection = #connection{protocol = Protocol}},
Channel, Reason) ->
- {ShouldClose, CloseChannel, CloseMethod} = map_exception(Channel, Reason),
+ {ShouldClose, CloseChannel, CloseMethod} =
+ map_exception(Channel, Reason, Protocol),
NewState = case ShouldClose of
true -> terminate_channels(),
close_connection(State);
@@ -765,14 +758,15 @@ send_exception(State = #v1{connection = #connection{protocol = Protocol}},
NewState#v1.sock, CloseChannel, CloseMethod, Protocol),
NewState.
-map_exception(Channel, Reason) ->
+map_exception(Channel, Reason, Protocol) ->
{SuggestedClose, ReplyCode, ReplyText, FailedMethod} =
lookup_amqp_exception(Reason),
ShouldClose = SuggestedClose or (Channel == 0),
{ClassId, MethodId} = case FailedMethod of
{_, _} -> FailedMethod;
none -> {0, 0};
- _ -> rabbit_framing:method_id(FailedMethod)
+ _ -> rabbit_framing:method_id(FailedMethod,
+ Protocol)
end,
{CloseChannel, CloseMethod} =
case ShouldClose of
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index ecc2613d..fc7beedd 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -913,7 +913,7 @@ test_memory_pressure() ->
%% if we publish at this point, the channel should die
Content = #content{class_id = element(1, rabbit_framing:method_id(
- 'basic.publish')),
+ 'basic.publish', amqp_0_9_1)),
properties = none,
properties_bin = <<>>,
payload_fragments_rev = []},