MassTransit3 message forwarding - masstransit

I have a message consumer (IConsumer<>) that acting like a message router. To route message I use context.Forward() method. But forwarding itself doesn't happening. RabbitClient throws:
RabbitMQ.Client.Exceptions.OperationInterruptedException**: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for exchange 'query1' in vhost 'Gateways': received 'false' but current is 'true'", classId=40, methodId=10, cause=
Yes, I'm trying to forward message to the queue that has been created with auto_delete=true flag. How can I forward messages to such endpoints?

To forward to an auto-delete exchange, you need to add some additional parameters to the query string before you pass it to the GetSendEndpoint method.
rabbitmq://server/exchange_name?autodelete=true
You can't forward directly to queues, so the durable=true should not be required, but if you continue to get an error, you can add &durable=true as well to resolve it.

Related

Make Spring RabbitMQ fail on missing exchange

There is nice property spring.rabbitmq.listener.simple.missing-queues-fatal=true
it makes SimpleMessageListenerContainer and whole application fail when I set it a non existent queue - which is what I want. I don't want to have an application running in invalid state.
I can't find similar solution for exchanges like
spring.rabbitmq.listener.simple.missing-exchanges-fatal
I get in logs several
ERROR 432430 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory : Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'some-non-existent-exchange' in vhost '/', class-id=40, method-id=30)
and application starts. I would like it to fail. How can I do it?
How can I make spring boot/rabbit fail when trying to bind to any of non existing queue or exchange?
The exchange does nothing with listener. We need it along side with a routing key when we produce data into AMQP. The listener has that option to fail because it is out of end-user control and starts automatically when application is ready. The exchange is used in the RabbitTemplate when you send a data. See publisherReturns option on the CachingConnectionFactory for use-case like yours to handle such an error in case of missed exchange:
https://docs.spring.io/spring-amqp/docs/current/reference/html/#cf-pub-conf-ret
https://www.rabbitmq.com/confirms.html
You also add a ReturnsCallback into your RabbitTemplate to catch an unrouted message and its reason and handle such an error respectively: in your case stop the app, e.g. System.exit(1);.

How should an snmp client receive responses from multiple snmp agents?

I require to send get requests/ receive responses to several snmp agents from a single client/manager process.
I have implemented client/agent based on below urls:
http://www.jitendrazaa.com/blog/java/snmp/create-snmp-client-in-java-using-snmp4j/ http://www.jitendrazaa.com/blog/java/snmp/creating-snmp-agent-server-in-java-using-snmp4j/
In order to send a request to an agent, the following is carried out for each server:
TransportMapping transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
transport.listen();
...
pdu.setType(PDU.GET);
// communityTarget contains server target address.
ResponseEvent event = snmp.send(pdu, communityTarget, null);
In order to receive responses from the servers, do I require to carry out a separate transport.listen() for each server? or create
a new TransportMapping and Snmp object for each server?
I don't understand how the client process can know which server returned the response? ...since
each time transport.listen() is called, the listening port address (transport.getListenAddress()) is the same.
and 1 extra udp port is listed (netstat).
I am intending to poll each server from a different background thread (in order that the polling interval can be configured).
Thank you
You should use the same transport mapping.
From the example you provided, it seems that you are using the synchronous API.
The response is just from the agent you sent the request too.
In any case, you can get the peer (agent) address from ResponseEvent.getPeerAddress
http://www.snmp4j.org/doc/org/snmp4j/event/ResponseEvent.html#getPeerAddress()

IBM Cast Iron: MQ Put activity issues

I am trying to put a message into Websphere MQ queue from an Orchestration which is deployed on Cast Iron Live. I have used secure connector since the orchestation is deployed on Cast Iron. When I am trying to execute the flow, it fails and the message is not placed in MQ queue. The below are the errors:
Error while trying to call remote operation execute on Secure Connector for activity
com.approuter.module.mq.activity.MqPut and Secure Connector LocalSecureConnector,
error is Unable to put message on queue null. MQ returned error code 2538.
Unable to put message on queue null. MQ returned error code 2538.
Fault Name : Mq.Put.OperationActivityId : 163
Message: Unable to put message on queue null. MQ returned error code 2538.
Activity Name:Put MessageFault Time: 2015-07-15T05:40:29.711Z
Can someone please help me resolve this. Please let me know if any further details are required.
Here are the details:
Cast Iron flow is deployed on Cast Iron Cloud i.e Cast Iron Live
MQ is running on-premise
The port I am trying to connect is 1414.
Have a secure connector running on the machine where MQ is installed.
MQ version is 8.
In Cast Iron flow, I am using an MQ connector, by giving the hostname where MQ is running, port: 1414, Channel Name : SYSTEM.DEF.SVRCONN and username as mqm. Tired using my log on username, by adding it to mqm group. But this also dosent seem to work.
The return code is instructive:
2538 0x000009ea MQRC_HOST_NOT_AVAILABLE
This indicates that Cast Iron is attempting to contact MQ using a client connection and not finding a listener at the host/port that it is using.
There are a couple of possibilities here but not enough info to say which it might be. I'll explain and provide some diagnostics you can try.
The 2538 indicates an attempt to contact the QMgr has failed. This might be that, for example, the QMgr isn't listening on the configured port (1414) or that the MQ listener is not running.
The error code says the queue name is "null". The question doesn't specify which queue name the connector is configured with but presumably it's been configured with some queue name. This error code suggests the Secure Connector on the MQ server side doesn't have its configuration installed.
The Cast Iron docs advise connecting with an ID in the mqm group but do not mention that on any MQ version 7.1 or higher this is guaranteed to fail unless special provisions are made to allow the admin connection. It may be that it's actually failing for an authorization error and the connector not reporting the correct error.
If it is as simple as the listener not running, that's easy enough to fix. Just start it and make sure it's on 1414 as expected.
Next, ensure that the Secure Connector has the configuration that was created using the Cast Iron admin panel. You need to understand why the error code says the queue name is null.
Now enable Authorization Events and Channel Events in the QMgr and try to connect again. The connector on the MQ server should connect when started and if successful you can see this by looking at the MQ channel status. However, if unsuccessful, you can tell by looking at the event messages or the MQ error logs. Both of these will show authorization failures and connection attempts, if the connection has made it that far.
The reason I'm expecting 2035 Authorization Error failures is that any QMgr from v7.1 and up will by default allow an administrative connection on any channel. This is configured in the default set of CHLAUTH rules. The intent is that the MQ admin would have to explicitly provision admin access by adding one or more new CHLAUTH rules.
For reasons of security SYSTEM.DEF.* and SYSTEM.AUTO.* channels should never be used for legitimate connections. The Best Practice is to define a new SVRCONN, for example one named CAST.IRON.SVRCONN and then define a CHLAUTH rule to allow the administrative connection.
For example:
DEFINE CHL(CAST.IRON.SVRCONN) CHLTYPE(SVRCONN) TRPTYPE(TCP) REPLACE
SET CHLAUTH('CAST.IRON.SVRCONN') TYPE(ADDRESSMAP) +
ADDRESS('127.0.0.1') +
USERSRC(MAP) MCAUSER('mqm') +
ACTION(REPLACE)
SET CHLAUTH('CAST.IRON.SVRCONN') TYPE(BLOCKUSER) +
USERLIST('*NOBODY') +
WARN(NO) ACTION(REPLACE)
The first statement defines the new channel.
The next one allows the connections from 127.0.0.1 which is where the Secure Connector lives. (Presumably you installed the internal Secure Connection on the same server as MQ, yes?) Ideally the connector would use TLS on the channel and instead of IP filtering the CHLAUTH rule would filter based on the certificate Distinguished Name. This rule is not nearly so slective and allows anyone on the local host to be an MQ administrator by using this channel.
The last statement overrides the default CHLAUTH rule which blocks *MQADMIN with a new rule that blocks *NOBODY but just for that channel.

Unable to reach hostname(port) during the communication b/w queue managers and while injecting the messages with amqsputc in MQ

I am having two queue managers on my local host named QMA running on port 1414 and QMB on 1415. I have defined SDR-RCVR channel pair on both the queue managers. When I placed the messages on the remote queue, there are ending up in the transmission queue and the SDR channel is going to continuous retry. I have tried to give the Connection name as locat host, hostname of mine, IPaddress and 127.0.0.1. Nevertheless, none is working out. I have defined the SVRCONN Channel on QMB and initialized MQSERVER variable like below:
QMB.SVRCONN/TCP/AnilReddy-PC(1415). As I said above, I have changed the connection name to making it working, but it's getting aborted with the following error in the error logs:
An error occurred receiving data from 169.254.231.219(1415) over TCP/IP. This
may be due to a communications failure.
hostname is responding to pings, I could see the listener is also running. I am using amqsputc to pace the messages on a queue of QMB.
Please suggest me in resolving this issue. Thanks in advance for sparing your time to look into my issue.
It looks like your SDR/RCVR channel configuration from QMB to QMA is not correct or a listener is not defined/running in QMA. You will need have definitions like this:
In QMA:
def chl(TO.QMA) chltype(RCVR)
def listener(LISTENER.TCP2) trptype(TCP) port(2424)
start listener(LISTENER.TCP2)
In QMB
def ql(QMA) USAGE(XMITQ)
def chl(TO.QMA) chltype(SDR) conname('localhost(2424)') xmitq(QMA)
start channel(TO.QMA)
def qremote(QR.SDLQ) RNAME(SYSTEM.DEFAULT.LOCAL.QUEUE) RQMNAME(QMA) XMITQ(QMA)
Make sure you have the same name for both SDR and RCVR channels.

Set fixed rport in FreeSWITCH/Sofia subscribe message

The problem is that I know next to nothing about SIP, or FreeSWITCH, yet have been tasked with figuring this out.
The setup:
The FreeSWITCH client sends a subscribe to a remote server to receive presence updates. The client is behind a fairly restrictive firewall and NAT.
The server replies with the normal unauthorized, and Sofia replies, and we receive the SIP/2.0 200 OK message, its VIA header contains an rport for a port number we don't have open or forwarding to our FreeSWITCH installation.
We never receive the notify that ought to follow the 200 OK.
Subsequent subscribes returns different rport designations.
Is there a way to configure FreeSWITCH/Sofia to always use a specific port for the rport parameter?
Edit: We never managed to solve it, but the remote service did solve it by adding the correct routes to their firewall.
Is the far end server setup to allow NOTIFY to be sent to your client?
If you receive the 200 OK response to the initial SUBSCRIBE then that sets up the SIP dialog I believe (the dialog is a end-point to end-point association).
BTW you set up FS to be the presence watcher client? Thats cool since I tried doing that but the documentation gave me a headache and moved on to other things.
Since you sent the initial subscribe NAT shouldn't be a problem right? since rport should have the port to use. I would always use port 5060, have your FW people let udp port 5060 port in and out freely, use Fail2ban to filter your traffic.
But have no idea how FS works, and NAT firewalls are the greatest evil :-). Sorry and best of luck.

Resources