BizTalk receiving from RabbitMQ - wcf

I'm new to RabbitMQ but I have now installed onto a Windows server and have a couple of demo console apps (C#) that happily write to a read from a queue.
The following code works to pull messages from a queue called "RabbitPoCQueue_2" on the local server:
string queueName = "RabbitPoCQueue_2";
var factory = new ConnectionFactory();
bool keepGoing = true;
factory.HostName = "127.0.0.1";
try
{
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
const bool durable = false;
channel.QueueDeclare(queueName, durable, false, false, null);
System.Console.WriteLine(" [*] Waiting for messages.");
while (keepGoing)
{
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
System.Console.WriteLine(" [x] Received {0}", message);
};
channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
channel.BasicGet(queue: queueName, autoAck: true);
System.Console.WriteLine("Press Y to continue or any other key to exit");
keepGoing = System.Console.ReadKey().Key == ConsoleKey.Y;
}
}
}
I now need to configure a BizTalk (2016 FP3 CU5) receive location to do the same. I have ensured I've stopped the console receiver and that I have messages sat on the queue for BizTalk to collect.
I followed the article https://social.technet.microsoft.com/wiki/contents/articles/7401.biztalk-server-and-rabbitmq.aspx
Problem is, when I start the receive location, I get no errors but nothing is received.
The config for the WCF receive location can be seen below:
and here:
and here's a pic from the RabbitMQ management console showing messages sat on the queue:
When I look in the RabbitMQ log file, I see 2 rows on starting the receive location. I see 3 rows when starting the .Net console app (using RabbitMQ API), as shown below - first 2 rows are from BizTalk, last 3 from the console app:
2019-08-28 16:17:45.693 [info] <0.13361.2> connection <0.13361.2> ([::1]:16807 -> [::1]:5672): user 'guest' authenticated and granted access to vhost '/' ** Start of Receive location
2019-08-28 16:19:57.958 [info] <0.13452.2> accepting AMQP connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672)
2019-08-28 16:19:58.026 [info] <0.13452.2> connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/' ** Receive from command line
2019-08-28 18:56:26.267 [info] <0.13452.2> closing AMQP connection <0.13452.2> (127.0.0.1:17173 -> 127.0.0.1:5672, vhost: '/', user: 'guest')
2019-08-28 18:56:39.815 [info] <0.17923.2> accepting AMQP connection <0.17923.2> (127.0.0.1:41103 -> 127.0.0.1:5672)
Can anyone spot where I went wrong?

Related

Sending message to queue in SingleActiveConsumer mode in MassTransit

I have registered receive endpoint in SingleActiveConsumer mode. However I can't find a way to send a message directly to queue by using sendEndpoint. I receive following error:
The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text='PRECONDITION_FAILED - inequivalent arg 'x-single-active-consumer' for queue 'test' in vhost '/': received none but current is the value 'true' of type 'bool'',
I tried setting header "x-single-active-consumer"=true by using bus configurer:
var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.Host("localhost", "/", h =>
{
h.Username("guest");
h.Password("guest");
});
cfg.ConfigureSend(a => a.UseSendExecute(c => c.Headers.Set("x-single-active-consumer", true)));
});
and directly on sendEndpoint:
await sendEndpoint.Send(msg, context => {
context.Headers.Set("x-single-active-consumer", true);
});
If you want to send directly to a receive endpoint in MassTransit, you can use the short address exchange:test instead, which will send to the exchange without trying to create/bind the queue to the exchange with the same name. That way, you decouple the queue configuration from the message producer.
Or, you could just use Publish, and let the exchange bindings route the message to the receive endpoint queue.

Prevent MassTransit from creating a RabbitMQ exchange for a consumer host

Is it possible to configure MassTransit to not create a RabbitMQ exchange for a consumer host? My RabbitMQ user has not enough rights to declare an exchange at the host where the consuming queue is located, so MassTransit fails to start with the following error:
Unhandled Exception: MassTransit.RabbitMqTransport.RabbitMqConnectionException:
Operation interrupted ---> RabbitMQ.Client.Exceptions.OperationInterruptedExcept
ion: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, c
ode=403, text="ACCESS_REFUSED - access to exchange '***' i
n vhost '***' refused for user '***'", classId=
40, methodId=10, cause=
Here is the code that I use:
var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
{
var host = sbc.Host(host: "***", port: 5671, virtualHost: "***", configure: configurator =>
{
configurator.UseSsl(sslConfigurator =>
{
sslConfigurator.Certificate = certificate;
sslConfigurator.UseCertificateAsAuthenticationIdentity = true;
sslConfigurator.ServerName = "***";
});
});
sbc.ReceiveEndpoint(host, "***", endpointConfigurator =>
{
endpointConfigurator.Consumer<UpdateCustomerConsumer>();
});
});

When publishing to invalid queue, ReturnCallback is called but why is ConfirmCallback called for the same message

I am testing the ConfirmCallback, ReturnCallback flows for a simple Publisher->Exchange->queue and listener model. I have set the publisherConfirms, publisherReturns, mandatory to true . I published a new message to an existing exchange with an invalid queue name. As expected, I received the callback to the ReturnCallback.returnedMessage method. However I received a callback to the ConfirmCallback.confirm method as well. As i understand since the queue name is invalid only the ReturnCallback.returnedMessage method should have received the callback. Why does ConfirmCallback.confirm method gets invoked? I have tested the scenario many times and I have received the same result. Please check the below code snippets and the log file for your understanding and let me know if something is wrong.
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(new ConfirmCallback() {
#Override
public void confirm(final CorrelationData correlationData, final boolean ack,
final String cause) {
System.out.println("confirmCallback received with correlationData, ack, cause" + correlationData+ cause + ack);
if (null != confirmCallbackUser) {
confirmCallbackUser.confirm(correlationData.getId(), ack, cause);
} });
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback()
#Override
public void returnedMessage(final Message message, final int replyCode,
final String replyText, final String exchange, final String routingKey) {
Message msg = new Message(message);
try {
System.out.println("returnCallBackUser received with message, replyCode, replyText, exchange, routingKey" + message + replyCode + replyText+ exchange + routingKey);
returnCallBackUser.returnedMessage(msg, replyCode, replyText, exchange,
routingKey);
} catch (MessagingException e) {
System.out.println("returnCallBackUser exception : " + e.getMessage());
e.printStackTrace();
}
System.err.println(" Message Returned");
}
Logs
40053 [https-openssl-nio-8443-exec-6] DEBUG c.s.n.f.s.messaging.MessImpl **- Control reached send()**
40056 [https-openssl-nio-8443-exec-6] DEBUG o.s.a.r.c.CachingConnectionFactory - Creating cached Rabbit Channel from PublisherCallbackChannelImpl: AMQChannel(amqp://guest#127.0.0.1:5672/,2)
40056 [https-openssl-nio-8443-exec-6] DEBUG o.s.a.r.s.PublisherCallbackChannelImpl - Added listener org.springframework.amqp.rabbit.core.RabbitTemplate#7c8f1db1
40057 [https-openssl-nio-8443-exec-6] DEBUG o.s.amqp.rabbit.core.RabbitTemplate - Added pubsub channel: Cached Rabbit Channel: PublisherCallbackChannelImpl: AMQChannel(amqp://guest#127.0.0.1:5672/,2), conn: Proxy#6bc6056e Shared Rabbit Connection: SimpleConnection#69225b5 [delegate=amqp://guest#127.0.0.1:5672/, localPort= 60962] to map, size now 1
40057 [https-openssl-nio-8443-exec-6] DEBUG o.s.amqp.rabbit.core.RabbitTemplate **- Executing callback on RabbitMQ Channel: Cached Rabbit Channel:** PublisherCallbackChannelImpl: AMQChannel(amqp://guest#127.0.0.1:5672/,2), conn: Proxy#6bc6056e Shared Rabbit Connection: SimpleConnection#69225b5 [delegate=amqp://guest#127.0.0.1:5672/, localPort= 60962]
40061 [https-openssl-nio-8443-exec-6] DEBUG o.s.amqp.rabbit.core.RabbitTemplate **- Publishing message on exchange [ControlExchange], routingKey = [invalidQueue]**
40064 [https-openssl-nio-8443-exec-6] DEBUG c.s.n.f.s.messaging.MessImpl - **Control moving out of send()**
***returnCallBackUser received with message,*** replyCode, replyText, exchange, routingKey(Body:'[B#294b5bb4(byte[91])' MessageProperties [headers={IDENTITY=TOMCAT_CONTROL}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=[80, 114, 111, 100, 117, 99, 101, 114], correlationIdString=null, replyTo=ControlExchange/ComAckQueue, contentType=application/octet-stream, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=null, receivedExchange=null, receivedRoutingKey=null, receivedDelay=null, deliveryTag=0, messageCount=null, consumerTag=null, consumerQueue=null])312NO_ROUTEControlExchangeinvalidQueue
40066 [AMQP Connection 127.0.0.1:5672] INFO c.s.n.f.s.m.CallBackRecReplyInterfaceTemplate - Message {"Test":"abcd","Role":"abcd","Id":"1111","request":"Accepted","De":"invalidQueue"} replyCode-> 312breplyText-> NO_ROUTE exchange-> Exchange routingKey-> invalidQueue
**Message Returned**
40066 [AMQP Connection 127.0.0.1:5672] DEBUG o.s.a.r.s.PublisherCallbackChannelImpl - **PublisherCallbackChannelImpl: AMQChannel(amqp://guest#127.0.0.1:5672/,2) PC:Ack:1:false**
40067 [AMQP Connection 127.0.0.1:5672] DEBUG o.s.a.r.s.PublisherCallbackChannelImpl - **Sending confirm PendingConfirm [correlationData=CorrelationData [id=corrlDat]]
confirmCallback received with correlationData, ack, causeCorrelationData [id=corrlDat]nulltrue**
40067 [AMQP Connection 127.0.0.1:5672] INFO c.s.n.f.s.m.CallbackConfirmImplTempl - **ACK->truecause->nullcorr id corrlDat
40067 [AMQP Connection 127.0.0.1:5672] INFO c.s.n.f.s.messaging.MessagingImpl - ACK->truecause->nullcorr id corrlDat**
Publisher Confirms calls when broker finished handle it. In case of wrong queue, broker sends confirm when it will verify that message won't route. See documentation in section "When will messages be confirmed".

RabbitMQ new consumer hangs

I'm using rabbitmq 3.6.6 using the docker image "rabbitmq:3"
Whenever I add a new consumer to my RabbitMQ queue it hangs from anywhere to 10 seconds 10 hours.
Below is an example of code used to get the error. I also get this error in Go. So it's not library dependant.
<?php
include(__DIR__."/vendor/autoload.php");
print "Start" . PHP_EOL;
$connection = new \PhpAmqpLib\Connection\AMQPStreamConnection('xxxx', 5697, 'guest', 'guest');
$channel = $connection->channel();
$callback = function($msg) {
echo " [x] Received ", $msg->body, "\n";
};
$channel->basic_consume('repositories', '', false, false, false, false, $callback);
while(count($channel->callbacks)) {
$channel->wait();
}
When I look at the logs I see
=INFO REPORT==== 31-Jan-2017::21:14:33 ===
accepting AMQP connection <0.891.0> (10.32.0.1:54216 -> 10.44.0.3:5672)
=INFO REPORT==== 31-Jan-2017::21:14:34 ===
accepting AMQP connection <0.902.0> (10.32.0.1:54247 -> 10.44.0.3:5672)
When I do list_consumer during via rabbitmqctl I see the consumer in the list, yet no messages are processed by it.
It turns out I needed to set the Qos setting.
Some more information can be found at:
http://www.rabbitmq.com/consumer-prefetch.html
https://github.com/streadway/amqp/blob/master/channel.go#L576

RabbitMQ STOMP connection

I am working on a fun project which requires me to learn message queues and websockets. I am trying to connect browsers via websockets to an instance of rabbitmq using sockjs rather than pure websockets. On rabbit I have activated the plugins for stomp and web_stomp (web_stomp is required when using sockjs).
The problem I am running into is that while the call from the browser seems to be working properly because a very brief connection to Rabbit is made through the webstomp/stomp connection but after 2 or 3 seconds the connection is dropped by Rabbit.
This is confirmed by the rabbitmq logs:
=INFO REPORT==== 11-Jul-2016::23:01:54 ===
accepting STOMP connection (192.168.1.10:49746 -> 192.168.1.100:55674)
=INFO REPORT==== 11-Jul-2016::23:02:02 ===
closing STOMP connection (192.168.1.10:49746 -> 192.168.1.100:55674)
This is the browser code that connects to RabbitMQ via the webstomp plugin:
var url = "http://192.168.1.100:55674/stomp";
var ws = new SockJS(url);
var client = Stomp.over(ws);
var header = {
login: 'test',
passcode: 'test'
};
client.connect(header,
function(){
console.log('Hooray! Connected');
},
function(error){
console.log('Error connecting to WS via stomp:' + JSON.stringify(error));
}
);
Here is the Rabbit config:
[
{rabbitmq_stomp, [{default_user, [{login, "test"},
{passcode, "test"}
]
},
{tcp_listeners, [{"192.168.1.100", 55674}]},
{heartbeat, 0}
]
}
]
I have been over the Rabbit docs a million times but this feels like something simple that I am overlooking.
Resolved. After combing through the logs I realized that web_stomp was listening on port 15674 so I changed the config file to reflect that. I swear I had made that change at some point but it did not seem to make a difference.
One of the late changes I made before sending out my request was to turn off heartbeat. Everything I have read states that sockjs does not support heartbeat and that there were suggestions to turn it off rather than use the default. In addition to turning off heartbeat in the config file I also added this to the browser code:
client.heartbeat.outgoing=0;
client.heartbeat.incoming=0;