RabbitMQ custom exchange (script-exchange installation trouble) - python

By default when I send a message with absent routing_key, the broker rejects it. How can I force RabitMQ to send one to the some 'default' queue? For example, I have 3 consumers with keys 'con1', 'con2' and 'con4'. I send a message with the key 'con3' and I need broker requeues message to some 'starter' queue that can start 'con3' consumer and requeue message again?
I found this https://github.com/tonyg/script-exchange and I sure it helps me, but I can't install it because the repository updated 4 years ago and modern umbrella dev kit is not support this old makefile.

It's necessary to use a combination of the alternate exchange protocol extension and the consistent-hash exchange plugin. So, you should declare 2 exchanges: direct and x-consistent-hash (alternative to the first one). Then all existing consumers should create their own queues bounded to the direct exchange. In this case all messages with routing keys of 'con1', 'con2' and 'con4' will be routed directly to the consumers whereas messages with another routing keys will be rerouted to the alternative exchange which can route them to the some 'managers', which starts the necessary processors (consumers).
The 'script-exchange' RabbitMQ plugin is unsupported now.

Related

Python - Mimic amqp 0.9 subscription to topics using Qpid Proton Filter

I need to interact with a the Apache Qpid C++ broker using Qpid Proton in Python. The objective is to generate a receiver that hooks to a topic exchange and receives only messages marked with a topic. I am aware that this can be easily done with Qpid API, but I needs to use Qpid Proton.
I have a horrible hack that inspects any message that arrives and check if topic (subject) of the message match some pattern, in a similar way as AMPQ 0-10 exchange binding do with routing keys. My idea is to move this to a Filter in the receiver, but after hours googling I have found no way to proceed.
My current implementation is using blocking connections, both to sender and receiver.
Any suggestion?

Do I need rabbitmq bindings for direct exchange?

I have a rabbit mq server running, with one direct exchange which all my messages go through. The messages are routed to individual non-permanent queues (they may last a couple hours). I just started reading about queue bindings to exchanges and am a bit confused as to if I actually need to bind my queues to the exchange or not. I'm using pika basic_publish and consume functions so maybe this is implied? Not really sure just wanna understand a bit more.
Thanks
If you are using the default exchange for direct routing (exchange = ''), then you don't have to declare any bindings. By default, all queues are bound to the default exchange. As long as the routing key exactly matches a queue name (and the queue exists), the queues can stay bound to the default exchange. See https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html.
Always. In fact, even though queues are strictly a consumer-side entity, they should be declared & bound to the direct exchange by the producer(s) at the time they create the exchange.
You have to bind a queue with some binding key to an exchange, else messages will be discarded.
This is how any amqp broker works, publisher publish a message to exchange with some key, amqp broker(RabbitMq) routes this message from exchange to those queue(s) which are binded with exchange with the given key.
However it's not mandatory to declare and bind a queue in publisher.
You can do that in subscriber but make sure you run your subscriber before starting your publisher.
If you think your messages are getting routed to queue without bindings than you are missing something.

Send an xmpp message to all connected clients/resources

How can I send one XMPP message to all connected clients/resources using a Python libraries for example:
xmpppy, jabber.py, jabberbot. Any other commandline solution is well.
So far I've only been able to send an echo or a single message to only one client.
The purpose is to send a message to all resources/clients connected, not grouped.
This might be triggered by a command but is not 'really' necessary.
Thank you.
I cannot give you a specific python example, but I explain how the logic works.
When you send a message to a bare Jid then it depends on the server software or configuration how its routed. Some servers send the message to the "most available resource", and some servers send it to all resources. E.g. Google Talk sends it to all resources.
If you control the server software and it allows you to route messages to a bare Jid to all connected resources then this would be the easiest way.
When your code must work on any server then you should collect all available resources of your contacts. You get them with the presence, most libraries have a callback for this. Then you can send out the messages to full Jids (with resources) in a loop.
I think If you set the same priorities for all connected resources, It would work but I did not try actually.
However in ejabberd there is a module named Mssage Carbon which do this for you, this feature or property is also available in open fire under the name of "route.all-resource".
Hint: If Message carbons used, XMPP client library should suport this too for making it working.

RabbitMQ - Game Rooms and Security Considerations

I'm programming an Android application and want to define rooms. The rooms would hold all the users of certain game. This is like poker with 4 players, where each room can hold 4 users. I also want to use rabbitmq for scalability and customobility. The problem is that the Android application uses the same username:password to connect all users to a RabbitMQ server (specific virtual host).
I guess I'm worried that one user might be able to read/write messages from different queues that it should. There are multiple solutions that are not satisfactory:
Use a different user in each Android application: This really can't be done, because the Android Market doesn't allow different applications for each user that downloads it. Even if it did, it's a stupid idea anyway.
Set appropriate access controls: http://www.rabbitmq.com/access-control.html . I guess this wouldn't prevent the problem of a malicious attacker reading/writing messages from/to queues it doesn't have access to.
Set appropriate routing keys: I guess if each user creates another queue from which it can read messages and published messages to specifically defined queue, this can work. But I guess the problem is the same, since users will be connecting to the RabbitMQ with the same username:password: therefore this user can read all queues and write to them (based on the access rules).
My question is: how to allow an attacker from reading/writing to queues that represent only the rooms he's currently joined in, and preventing access to other queues?
Perhaps I don't understand the application too well, but in my experience RabbitMQ is usually used on the backend, for example, while creating a distributed system with databases and application servers and other loosely coupled entities. Message queuing is an important tool for asynchronous application design, and the fact that each messaging queue can in theory be spawned into a separate process by RabbitMQ makes it remarkably scalable.
What you are alluding to in your question seems more like a access control mechanism for users. I would see this in the front end of a system. For example, having filtering mechanisms on the incoming messages before passing them on to the messaging queues. You might even want to consider DoS prevention via rate control per user.
Cheers!
I am working on a Poker application myself =)
I am relying on something like Akka/Actors (check out Erlang) based traffic over streaming web sockets and hoping it works out (still kind of worried about secure web sockets).
That said, I am also considering RabbitMQ for receiving player actions. I do not think you want to ever expose the username or password to the rabbit queue. As a matter of fact, you probably don't even want the queue server accessible from the outside world.
Instead, set up some server that your users can establish a connection to. This will be your "front end" that the android clients will talk to. Each user will connect to the server via a secure TCP connection and then log into your system. This is where the users will have their own usernames and passwords. If authentication is successful, keep the socket alive (this is where my knowledge of TCP is weak) and then associate the user information with this socket.
When a player makes an action, such as folding or raising, send their action over the secure TCP connection to your "front end" (this connection should still be established). The "front end" then checks which user is connected to this socket, then publishes a message to the queue that would ideally contain the user id, action taken, and the table id. In other words, the only IP allowed to hit the queue is your front end server, and the front end server just uses the single username/password for the rabbit queue.
It's up to you to handle the exchange of the queue message and routing the message to the right table (or making sure the table only handles messages that it's responsible for - which is why I am loving Akka right about now :) Once the message arrives to the table, verify that the user id in the message is the user id whose turn it actually is, and then verify that the action sent is an acceptable one based on the table's state. For example, if I receive a CHECK request and the user can only CALL/FOLD/RAISE, then I will just reply saying invalid action or just throw out the whole message.
Do not let the public get to the queue, and always make sure you do not have security holes, especially if you start dealing with real currencies.
Hope this helps...
EDIT: I just want to be clear. Any time clients make actions, they simply need to send the action and table id or whatever information you need. Do not let them send their user id or any user specific information. Your "front end" server should auto associate the user id based on the socket the request is coming in on. If they submit any user information with their request, it may be a good idea to log it, and then throw out the data. I would log it just because I don't like people trying to cheat, and that's probably what they're doing if they send you unexpected data.

Message Routing in AMQP

I'd like to do some routing magic with AMQP. My setup is Python with Pika on the consumer/producer side and RabbitMQ for the AMQP server.
What I'd like to achieve:
send a message to a single exchange
(insert magic here)
consume messages like so:
one set of subscribers should be able to retrieve based on a routing key
one set of subscribers should just get all messages.
The tricky part is that if the any server in the second set has received a message no other server from the second set will receive it. All the servers from the first set should still be able to consume this message.
Is this possible with a single basic_publish call or do I need to send the message to a routing exchange (for the first set of consumers) and to a "global" exchange for the second set of consumers?
CLARIFICATION:
What I'd like to achieve is a single
call to publish a message and have it
received by 2 distinct sets of
consumers.
Case 1: Just receive messages based on routing key (that is a
message with routing key foo will be
received by all the consumers
currently interested in that topic)
Case 2: This basically resembles the RabbitMQ Tutorial for Worker
Queues.
There are a number of workers that
will receive messages dispatched in a
round robin way. Only one worker will receive a message
Still the message that is received by the consumers that are interested in a certain
routing key should be exactly the same as the messages received by the workers, produced
by a single API call.
(Hope my question makes sense I'm not too familiar with AMQP terms)
To start with, you need to use a topic exchange and publish your messages with a different routing key for each queue. The magic happens when the consumer binds the queue with a binding key (or pattern to be matched). Some consumers just use the routing keys as their binding key. But the second set will use a wildcard pattern for their binding key.
For Case 1, you need to create a queue per consumer, and bind each queue with an appropriate routing key.
For Case 2, just create a single queue with a routing key of # and have each of your worker consumers consume from that. The broker will dispatch in a round-robin manner to the workers.
Here's a screenshot of what it would look like in RabbitMQ. In this example there are two consumers from your "case 1" (Foo and Bar) and one queue for all the workers to satisfy "case 2".
This model should be supported by all AMQP-compliant brokers and wouldn't require any vendor-specific enhancements.

Categories

Resources