When we initiate a Close, we get a CloseOk in response and on receipt of
the CloseOk, we mark the channel as closed and emit a signal to notify
everyone else.
Great. Now what happens when the server closes the channel? We emit a
CloseOk, then… nothing. We do nothing. This fixes this problem, moving
the notification/marking logic to a new function and calling that on
both Close (sent from server) and CloseOk.
- DON'T rely on sender()
- DON'T expect to be able to cast the QObject to a QAmqpChannel and have
name() work.
This isn't as efficient as I'd like, but it doesn't crash either.
How on earth did I expect that to work? Morning cup of tea hasn't
kicked in yet, of course I can't assign a const QString passed by
reference.
Fix egregious PEBKAC-caused compile error.
Since there will be probably many requests for that one. If we're
passed in QString() instead of QString(""), we overwrite that with the
latter to ensure the name field is never NULL.
Just discovered you *CAN* delete them yourself safely, and one of the
tests does. So best to not assume they'll get deleted by other parties.
QPointer takes care of this problem for us.
Previously if multiple attempts to call consume were made, then
QAmqpQueue would send a frame for each of them leading to multiple
consumer tags and general confusion. This guards from calling
consume multiple times.
On socket errors we always close the socket per amqp specification,
however there is no need to do so if the connection has already been
forcibly closed from the server side. This causes recursive loops
when using SSL connections
Provides an accessor and change signal for the state of QAmqpClients
internal ssl socket. This also defaults the internal socket to low
latency mode, as well as keep alive.
This gives an example of how you can use QMetaObject::invokeMethod to
call a QAmqpExchange from another thread. Also, moved the qRegisterMetaType
for QAmqpMessage::PropertyHash to the ctor of QAmqpClientPrivate
tuneOk was only properly tuning the heartbeat delay value for values
larger than the default delay sent by the server. This changes that
behavior to send back the requested heartbeat delay if one was provided
QAmqpExchange and QAmqpQueue both have a number of actions associated
with them that should be defined as slots (especially for a potential
future where they are exported as QML objects). This is a step in the
direction of fully making these classes scriptable
nextChannelNumber is being incremented twice. When the counter wraps
around it starts declaring already existing channels and the AMQP server
disconnects the client. This patch doubles the number of channels that
can be created before this happens.
A public accessor and mutator was provided for using a QSslConfiguration
with a QAmqpClient, however the configuration was never actually assigned
to the internal socket. This patch fixes that, and removes the needless
storage of a copy of the QSslConfiguration as well
In cases where exchanges and queues are added and deleted during
an extended use of a QAmqpClient, the client should internally cleanup
the frame handlers registered for those objects. This patch does that
as well as providing two test cases verifying this behavior for both
QAmqpQueue and QAmqpExchange.
When a socket error occurs the string version of the error is now
stored in QAmqpClient's internal errorString variable, providing
access to the string to users of the client.
This adds preliminary support for SSL connections to a RabbitMQ
server. Instead of providing two clients (QAmqpClient/QAmqpSslClient),
the SSL support was directly rolled into QAmqpClient itself, providing
signals/slots to deal with errors (sslErrors/ignoreSslErrors), and
the ability to assign a QSslConfiguration. Travis testing for ssl
support is currently disabled, pending a solution to a travis
limitation for starting ssl listeners
Since you can provide amqps endpoints, it makes no sense to have a
separate class for SSL client support. This functionality will be
merged directly into QAmqpClient
QAmqpQueue and QAmqpExchange both now have an isDeclared property,
and QAmqpChannel::isOpened was renamed to isOpen to more closely follow
Qt style/api guidelines
RabbitMQ supports publish confirms (Publisher Acknowledgements) on
a given channel. This enables the user to toggle this functionality
and ensure that published messages are in fact published.
- opt for QDataStream overloads instead of read ctor and toStream methods
- removed some unneccesary prefixes to Type and MethodClass enums
- removed documentation from header (this is coming back!)
- cleaned up some confusing code paths, removed unneccessary methods (like readHeader/writeHeader)
This is a very small library, so there is no real pressing need for
a library namespace. Further, the namespacing actually makes it rather
difficult to work with in some cases. Opting for a more "Qt" style
class naming scheme, using the QAmqp class prefix
The internal buffer should not be used blindly when reading
Frame::HEADER_SIZE, as it is error prone and adds nothing over reading
on the stack (and it's only 7 bytes). There are places in this class
where buffer.clear() is called.
amqp_<filename> is used in at least two other C/C++ projects related
to amqp, so this commit changes all our source to use a qamqp header.
This avoids potential clashes, and is more in line with Qt style
QAMQP::Frame used to be public API mostly for MessageProperties. There
is no longer a need to keep this API public, as it should all be wrapped
with the cleaner Message/Queue/Exchange/Client API set
Though it's not necessarily recommended (per spec), Channels can be
shared by multiple Exchanges and Queues. I've added a test here showing
that's possible with QAMQP
We had frame handlers for Close messages from the server, but were not
doing our due diligence and sending a corresponding CloseOk back to the
server after processing. It seems RabbitMQ is generous in this case, but
at least we're doing it the right way now
Fleshed out the previously unimplemented flow control frame handling,
added an auto test for it. Also refactored out the stateChanged ChannelPrivate
method, if we need proper state support in the future it will be added with
a better implementation
There are two distinctive type sets in AMQP, the basic AMQP types
and then the superset of Table value types. This commit attempts to
make that distinction more clear by the addition of a Table class.
Basically, AMQP value type read/write support is left in Frame for the
time being, while table value field read/write support has been moved
to the Table class. Also, a number of type differences exist between
the spec and rabbitmq's binary parser (noted in the errata page) which
were not previously honored.
the message was being needlessly duplicated into the Content frame,
now we only store the size there to be sent out, rather than the whole
message
remove QAMQP prefix in authenticator
MessageProperties is currently defined in Frame::Content, which makes it
cumbersome to use when working directly with a Message itself. I attempted
to make this easier by using typedefs, but it's become pretty obvious that
it belongs in the Message class itself.
AMQP Basic qos support added to Channel class. There is an option
for global qos which is currently not added. Also, added auto tests
for qos definition, proper qos operation and verifying that RabbitMQ
does not support prefetchSize.
removed noAck as it relates only to the synchronous get AMQP api
moved noAck to get method
applied visual separation in headers between AMQP Queue and AMQP Basic methods
a Queue can act as a consumer in QAMQP, but previously we did no checks
to ensure that a Queue sent a request to consume only once. This commit
adds API for checking and ensuring that this is the case. Also, I reverted
the changes to allow multiple consumer tags because this was incorrect.
Also included is a new signal "consuming" to notify when consumption occurs,
and auto tests have been updated to use this, as well as verify that it
can only occur once per-consumer
- add publish options to Exchange (these need to move to a Basic abstraction)
- listen for bmReturn in Exchange to catch errors
- added auto tests to check behavior of an invalid mandatory publish
- cleaned up bit fields in exchange and queue
Messages used to be "delivered" and pushed right onto the queue, which
is where the requirement for Message to be explicitly shared came from.
Now messages that are incomplete come in and are stored in a "currentMessage"
private member (there is a requirement that messages are delivered in this
fashion, by the spec). Once the message body has come in, it is put into
the local queue and the messageReceived signal is emitted.
Also, modified Queue to be able to track a number of consumer tags. This
was exposed by the "routing" tutorial, where a single consumer can bind
to a number of exchanges with a generated consumer tag. The previous example
did not run into this problem because it used an explicitly set consumer tag
and therefore there were no conflicts.