how to force close a client connection rabbitmq - rabbitmq

I have a client server application that uses rabbitmq broker.
Client connects to rabbitmq and send messages to server. At some point if server decides that this client should not be connected to rabbitmq i want to be able to force disconnect client from rabbitmq border.
Note that in my case I don't want to send message to client to disconnect, on server side I want to just force disconnect this client from rabbitmq.
Couldn't find api to do this. Any help is appriciated.

You can use the management console plug-in in two ways:
Manually, going to the connection and "force close".
Through the HTTP API using "delete" /api/connections/name, here an python example:
import urllib2, base64
def calljsonAPI(rabbitmqhost, api):
request = urllib2.Request("http://" + rabbitmqhost + ":15672/api/" + api);
base64string = base64.encodestring('%s:%s' % ('guest', 'guest')).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string);
request.get_method = lambda: 'DELETE';
urllib2.urlopen(request);
if __name__ == '__main__':
RabbitmqHost = "localhost";
#here you should get the connection detail through the api,
calljsonAPI(RabbitmqHost, "connections/127.0.0.1%3A49258%20-%3E%20127.0.0.1%3A5672");

You can use rabbitmqctl for close/force-close connections:
rabbitmqctl close_connection <connectionpid> <explanation>
<connectionpid> is from:
rabbitmqctl list_connections
#or
rabbitmqctl list_consumers

Related

How to read the data from MQTT Consumer from queue instead of topic using the telegraf

I have an ActiveMQ broker and data is coming to the queue inside this broker.
I am trying to read the data from the same broker but I am not able to read the data.
Below I have given my telegraf configuration. I have provided the topic name.
I tried creating a topic and sending custom data and that data I am able to read properly.
[[inputs.mqtt_consumer]]
servers = ["provided"]
qos = 0
## Topics that will be subscribed to.
topics = [
"topic_name",
]
connection_timeout = "30s"
## If unset, a random client ID will be generated.
client_id = "telegraf"
## Username and password to connect MQTT server.
username = "provided"
password = "provided"
## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
[[inputs.activemq]]
## ActiveMQ WebConsole URL
url = "provided"
## Required ActiveMQ Endpoint
## deprecated in 1.11; use the url option
# server = "192.168.50.10"
# port = 8161
## Credentials for basic HTTP authentication
username = "provided"
password = "provided"
[[outputs.file]]
## ## Files to write to, "stdout" is a specially handled file.
files = ["stdout","/etc/telegraf/metrics.out"]
The data coming from devices is going to the queue, not the topic.
As you can see the data is present inside the queue.
so now coming to my main question how I can read the data from the queue not from the topic using telegraf?
MQTT supports topics by default. You either need to change your message flow to publish to topics, or configure your ActiveMQ broker to use Virtual Topic Subscription Strategy for MQTT (where messages are stored in queues).
ref: https://activemq.apache.org/mqtt
Note: Please edit your post to hide your broker URL and admin password!

How to force disconnect from ActiveMQ connection with Stomp.py

When listening to a message queue using a durable connection I get an error in the listener. I simulate this by hitting CTRL-Z to quit the program. Trying to re-connect gives me a an error that says:
on_error! : "javax.jms.InvalidClientIDException: Broker: BMRSBROKER - Client: <Client-id> already connected from tcp://10.18.57.69:4241
at org.apache.activemq.broker.region.RegionBroker.addConnection(RegionBroker.java:255)
at org.apache.activemq.broker.jmx.ManagedRegionBroker.addConnection(ManagedRegionBroker.java:227)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.advisory.AdvisoryBroker.addConnection(AdvisoryBroker.java:116)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.security.JaasAuthenticationBroker.addConnection(JaasAuthenticationBroker.java:75)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.plugin.AbstractRuntimeConfigurationBroker.addConnection(AbstractRuntimeConfigurationBroker.java:118)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.MutableBrokerFilter.addConnection(MutableBrokerFilter.java:103)
at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:849)
at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:77)
at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)
at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:333)
at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:197)
at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:45)
at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:300)
at org.apache.activemq.transport.stomp.StompTransportFilter.sendToActiveMQ(StompTransportFilter.java:97)
at org.apache.activemq.transport.stomp.ProtocolConverter.sendToActiveMQ(ProtocolConverter.java:202)
at org.apache.activemq.transport.stomp.ProtocolConverter.onStompConnect(ProtocolConverter.java:774)
at org.apache.activemq.transport.stomp.ProtocolConverter.onStompCommand(ProtocolConverter.java:265)
at org.apache.activemq.transport.stomp.StompTransportFilter.onCommand(StompTransportFilter.java:85)
at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
at org.apache.activemq.transport.tcp.SslTransport.doConsume(SslTransport.java:108)
at org.apache.activemq.transport.stomp.StompSslTransportFactory$1$1.doConsume(StompSslTransportFactory.java:70)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
at java.lang.Thread.run(Thread.java:745)
"
I have tried to unsubscribe and disconnect my connection using the method below but it won't disconnect me.
class MyListener(stomp.ConnectionListener):
"""This is a listener class that listens for new messages using the STOMP protocol"""
def __init__(self, conn):
self.conn = conn
self.client_id = client_id
def on_error(self, headers, message):
self.disconnect()
def on_message(self, headers, message):
...
def on_disconnected(self):
self.disconnect()
def disconnect(self):
try:
self.conn.unsubscribe(
destination="/topic/bmrsTopic",
id=self.client_id
)
except:
print('unsubscribe failed')
# first disconnect before trying to reconnect
print('first disconnect before trying to reconnect')
try:
self.conn.disconnect()
except:
print('disconnect failed')
How can I force the AMQ server to forget my previous connection?
You cannot for the broker to disconnect other client resources from another connection. Instead you should be configuring the connection with an idle timeout value for both the client and the broker so that both sides handle the remote dropping without the socket detecting the close.
You can also configure the broker transport connector with Heart-Beat Grace Period values for stomp clients that don't advertise heart beats, refer to the ActiveMQ broker STOMP documentation.
The STOMP specification outlines how heart beats work:

How to get detailed log/info about rabbitmq connection action?

I have a python program connecting to a rabbitmq server. When this program starts, it connects well. But when rabbitmq server restarts, my program can not reconnect to it, and leaving error just "Socket closed"(produced by kombu), which is meaningless.
I want to know the detailed info about the connection failure. On the server side, there is nothing useful in the rabbitmq log file either, it just said "connection failed" with no reason given.
I tried the trace plugin(https://www.rabbitmq.com/firehose.html), and found there was no trace info published to amq.rabbitmq.trace exchange when the connection failure happended. I enabled the plugin with:
rabbitmq-plugins enable rabbitmq_tracing
systemctl restart rabbitmq-server
rabbitmqctl trace_on
and then i wrote a client to get message from amq.rabbitmq.trace exchange:
#!/bin/env python
from kombu.connection import BrokerConnection
from kombu.messaging import Exchange, Queue, Consumer, Producer
def on_message(self, body, message):
print("RECEIVED MESSAGE: %r" % (body, ))
message.ack()
def main():
conn = BrokerConnection('amqp://admin:pass#localhost:5672//')
channel = conn.channel()
queue = Queue('debug', channel=channel,durable=False)
queue.bind_to(exchange='amq.rabbitmq.trace', routing_key='publish.amq.rabbitmq.trace')
consumer = Consumer(channel, queue)
consumer.register_callback(on_message)
consumer.consume()
while True:
conn.drain_events()
if __name__ == '__main__':
main()
I also tried to get some debug log from rabbitmq server. I reconfigured rabbitmq.config according to https://www.rabbitmq.com/configure.html, and set
log_levels to
{log_levels, [{connection, info}]}
but as a result rabbitmq server failed to start. It seems like the official doc is not for me, my rabbitmq server version is 3.3.5. However
{log_levels, [connection,debug,info,error]}
or
{log_levels, [connection,debug]}
works, but with this there is no DEBUG info showing in the logs, which i don't know whether it is because the log_levels configuration is not effective or there is just no DEBUG log got printed all the time.
I know that this answer comes massively late, but for future purveyors, this worked for me:
[
{rabbit,
[
{log_levels, [{connection, debug}, {channel, debug}]}
]
}
].
Basically, you just need to wrap the parameters you want to set in whichever module/plugin they belong to.

How to receive sms via smpp connection - Kannel

I sent messages through smpp connection (using selenium SmppSim) from Kannel and it worked.
But somehow when I try to receive messages or in other words when I try to send messages from SmppSim It doesn't work. The MO messages of the SmppSim queue into the MO-queue.
I tried these things.
Used same port for send and receive (Kannel/SmppSim).
Used different ports for send and receive (Kannel/SmppSim).
Two groups for same smsc-smpp for send and receive. (It may be wrong)
Now I'm using port 2775 for send and port 2776 for receive.
#kannel.conf
group=smsc
smsc=smpp
....
port = 2775
receive-port = 2776
transceiver-mode = true
....
In SmppSim
#smppsim.props
SMPP_PORT=2775
....
SYSTEM_IDS=smppclient
PASSWORDS=password
OUTBIND_ENABLED=true
OUTBIND_ESME_IP_ADDRESS=127.0.0.1
OUTBIND_ESME_PORT=2776
OUTBIND_ESME_SYSTEMID=smppclient
OUTBIND_ESME_PASSWORD=password
....
When I run the bearerbox, it shows like below. (sms send is working)
....
connect failed
System error 111: Connection refused
ERROR: error connecting to server `localhost' at port `2776'
SMPP[SMPPSim]: Couldn't connect to server.
SMPP[SMPPSim]: Couldn't connect to SMS center (retrying in 10 seconds).
....
How do I configure this?
Thank you!
Please read SMPP v3.4 specification, part 2.2.1.
The purpose of the outbind operation is to allow the SMSC signal an ESME to originate a
bind_receiver request to the SMSC.
So it's used for SMSC (SMPPSim) to connect to ESME (Kannel) and request for callback connection.
However you can run few SMPPSim instances listening on different ports. Each instance should use own configuration file this case.

Authentication on a very low level TCP Server written for Node.JS?

How do I implement something similar to the HTTP Basic authentication, in a TCP server written for Node.JS ? The code for a basic TCP server is the following:
// Load the net module to create a tcp server.
var net = require('net');
// Setup a tcp server
var server = net.createServer(function (socket) {
// Every time someone connects, tell them hello and then close the connection.
socket.addListener("connect", function () {
console.log("Connection from " + socket.remoteAddress);
socket.end("Hello World\n");
});
});
// Fire up the server bound to port 7000 on localhost
server.listen(7000, "localhost");
// Put a friendly message on the terminal
console.log("TCP server listening on port 7000 at localhost.");
While there are several ways to provide authentication over a TCP connection, all require some form of "protocol" being an agreed-upon communications grammar/syntax.
For example, in the Simple Mail Transport Protocol, the following conversation occurs (where S: and C: designate lines provided by the SMTP server and email client, respectively):
S: 220 server.example.com
C: HELO client.example.com
S: 250 server.example.com
C: MAIL FROM:<sender#example.com>
S: 250 2.1.0 sender#example.com... Sender ok
C: RCPT TO:<recipient#example.com>
S: 250 recipient <recipient#example.com> OK
C: DATA
S: 354 enter mail, end with line containing only "."
C: full email message appears here, where any line
C: containing a single period is sent as two periods
C: to differentiate it from the "end of message" marker
C: .
S: 250 message sent
C: QUIT
S: 221 goodbye
In replies from the server, the initial numeric value indicates the success or failure of the requested operation, or that the reply contains an informational message. Using a three digit numeric value allows for efficient parsing as all replies beginning with 2xx indicate success, 3xx are informational, 4xx indicate protocol errors, and 5xx are reserved for server errors. See IETF RFC 5321 - https://www.rfc-editor.org/rfc/rfc5321 for the full protocol.
So in your specific case, you might consider something as simple as:
[connect to TCP server]
S: ? # indicates the server is ready for authorization
C: username password # send authentication credentials
The server would then reply with:
S: ! # indicates successful authentication and
# that server is ready for more commands
Or
S: ? # indicates authentication failure
If too many failed attempts to authenticate are seen, the server might sever the connection to reduce the potential for abuse, such as DDOS attacks.
Once authenticated, the client could send:
C: > # begin streaming
Or any other command you which to support.