MassTransit connecting to RabbitMQ vhost starting with slash - rabbitmq

I am currently trying to implement RabbitMQ in .NET Core 3.1 using MassTransit. I am running into an issue getting started, the RabbitMQ server is running 3.8.5 and Erlang 22.0.7.
The issue occurs during the connection to the RabbitMQ Server. The vhost starts with a / and according the documentation
RabbitMQ URI Specification Image
That should be percent encoded into the URI as %2f
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMassTransit(x =>
{
x.AddConsumer<RequestConsumer>();
x.AddBus(provider =>
{
var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var uri = new Uri("amqps://rmq.domain.net:5671/%2ftestvhost");
cfg.Host(uri, host =>
{
host.Username("testuser");
host.Password("testpassword");
});
});
return bus;
});
});
services.AddMassTransitHostedService();
}
After attempting to run the connection is closed and the following error is outputted
---> RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=530, text='NOT_ALLOWED - vhost %2ftestvhost not found', classId=10, methodId=40
The output from the rabbitmq server is
[error] <0.11481.4> Error on AMQP connection <0.11481.4> (IP -> IP - iisexpress, user: 'testuser', state: opening):
vhost %2ftestvhost not found
[info] <0.11481.4> closing AMQP connection <0.11481.4> (IP -> IP - iisexpress, vhost: 'none', user: 'testuser')
The final message about vhost being 'none' is a little interesting I suspect that 'none' is a default for unknown vhosts.
My question is am I missing something, the URI doesn't seem to map properly to the vhost?
Is their an explicit setting I am missing for a vhost starting with a slash?
I've tried
Adding a second slash in the front
Changing the configuration to use cfg.Host(hostname, port, vhost)

Related

MassTransit: Using default RabbitMQ exchange?

Using MassTransit with RabbitMQ trying to use default exchange.
With RabbitMQ library is was fine as it was default behaviour, but with MassTransit seems to make this is difficult?
I found out how to configure custom exchange name:
...
serviceCollection.AddMassTransit(x =>
{
x.UsingRabbitMq((rabbitContext, rabbitConfig) =>
{
rabbitConfig.Host(config.GetConnectionString("RabbitMq"));
Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.Message<TestMessage>(x => x.SetEntityName(""));
});
rabbitConfig.ConfigureEndpoints(rabbitContext);
rabbitConfig.Durable = true;
});
});
Then I get:
RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=403, text='ACCESS_REFUSED - operation not permitted on the default exchange', classId=40, methodId=10
Operation is not permitted? I'm a little confused here, why is this so toublesum, am I doing something wrong? I only want one consumer to ever pick up one message from the queue, so the default exchange Masstransit created which is fanout doesn't work for me here.

spring cloud stream consumer exchange connection retry

I have rabbitmq consumer with reactive spring cloud stream
#Bean
public <T> Consumer<Flux<Message<Subscription>>> exportConsumer() {
return new ExportSubscriptionConsumer<>();
}
and below are the configurations
spring:
cloud:
function:
definition: exportConsumer
stream:
rabbit:
bindings:
exportConsumer-in-0:
consumer:
bindQueue: true
queueNameGroupOnly: true
declareExchange: false
bindingRoutingKey: smfexportconsumer
function:
bindings:
exportConsumer-in-0:
destination: jms.durable.queues
bindings:
exportConsumer-in-0:
group: smfexportconsumer
Issue i have is it, after application consuming the few messages suddenly it throws me a error.
Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'exportConsumer-in-0' in vhost '9509bf37-8afc-486e-ac98-61034066671d', class-id=50, method-id=20)
If i restart the application it works for a while but again same issue!
Do i have option to configure retry here, couldn't found any such configurations here
or
Do i have option to configure my custom retry logic.
Kindly help.
[EDIT]
messageFlux
.doOnNext(s -> logger.info("Got message: {}", s))
.map(Message::getPayload)
.flatMap(this::converToCharacters)
.map(User::getId)
.flatMap(this::getUser)
.onErrorContinue((throwable, o) -> logger.error(throwable.getMessage()))
Inside the convert method, I have an API call.
return webClient.get()
.uri(uriBuilderFactory.builder().path("/authorize").build())
.retrieve().bodyToMono(String.class)
.publishOn(Schedulers.immediate())
.timeout(Duration.ofSeconds(10))
.map(s1 -> new User(s, s1));
Now the question I have is if I get a time out with the above endpoint, how do I handle it? is it using
onErrorContinue
or do I have the option of global error handling?
[EDIT-2]
Sample code here

Why is the Ignite port listening not authenticated?

org.apache.ignite.internal.util.nio.GridNioServer#createSelector
// Create a new selector
selector = SelectorProvider.provider().openSelector();
if (addr != null) {
// Create a new non-blocking server socket channel
srvrCh = ServerSocketChannel.open();
srvrCh.configureBlocking(false);
if (sockRcvBuf > 0)
srvrCh.socket().setReceiveBufferSize(sockRcvBuf);
// Bind the server socket to the specified address and port
srvrCh.socket().bind(addr);
// Register the server socket channel, indicating an interest in
// accepting new connections
srvrCh.register(selector, SelectionKey.OP_ACCEPT);
}
return selector;
Why is the Ignite port listening not authenticated?
How can I set authentication?
Two parts:
It has to open the connection so that it can be told what the credentials are. If they're not valid, Ignite will disconnect
Ignite can only authenticate thin-clients out-of-the-box. I have not checked the code, but this could be a server or thick-client code path

Camel RabbitMQ connection using camel amqp

I am trying to connect to rabbitmq in my camel route using camel-amqp (version 2.17) component.
I have configured it as below :
#Bean
CachingConnectionFactory jmsCachingConnectionFactory(){
JmsConnectionFactory pool = new JmsConnectionFactory();
pool.setRemoteURI("amqp://127.0.0.1:5672");
pool.setUsername("guest");
pool.setPassword("guest");
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(pool);
return cachingConnectionFactory;
}
#Bean
JmsConfiguration jmsConfig(){
JmsConfiguration configuration = new JmsConfiguration();
configuration.setConnectionFactory(jmsCachingConnectionFactory());
// configuration.setCacheLevelName("CACHE_CONSUMER");
return configuration;
}
#Bean
AMQPComponent amqp(){
AMQPComponent component = new AMQPComponent();
component.setConfiguration(jmsConfig());
return component;
}
The error I am getting is
javax.jms.JMSException: An existing connection was forcibly closed by
the remote host
at
org.apache.qpid.jms.exceptions.JmsExceptionSupport.create(JmsExceptionSupport.java:66)
~[qpid-jms-client-0.8.0.jar:0.8.0]
In my rabbitmq log I can see the below message which I am not able to understand
*
** Reason for termination ==
** {function_clause,
[{rabbit_amqp1_0_link_util,'-outcomes/1-lc$^0/1-0-',
[{list,
[{symbol,<<"amqp:accepted:list">>},
{symbol,<<"amqp:rejected:list">>},
{symbol,<<"amqp:released:list">>},
{symbol,<<"amqp:modified:list">>}]}],
[{file,"src/rabbit_amqp1_0_link_util.erl"},{line,49}]},
{rabbit_amqp1_0_link_util,outcomes,1,
[{file,"src/rabbit_amqp1_0_link_util.erl"},{line,49}]},
{rabbit_amqp1_0_outgoing_link,attach,3,
[{file,"src/rabbit_amqp1_0_outgoing_link.erl"},{line,41}]},
{rabbit_amqp1_0_session_process,with_disposable_channel,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,377}]},
{rabbit_amqp1_0_session_process,handle_control,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,197}]},
{rabbit_amqp1_0_session_process,handle_cast,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,134}]},
{gen_server2,handle_msg,2,[{file,"src/gen_server2.erl"},{line,1049}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]}
=ERROR REPORT==== 8-Jul-2016::17:09:27 ===
closing AMQP connection <0.29082.0> (127.0.0.1:55479 -> 127.0.0.1:5672):
{handshake_error,running,<0.29104.0>,
{{symbol,<<"amqp:internal-error">>},
"Session error: ~p~n~p~n",
[function_clause,
[{rabbit_amqp1_0_link_util,'-outcomes/1-lc$^0/1-0-',
[{list,
[{symbol,<<"amqp:accepted:list">>},
{symbol,<<"amqp:rejected:list">>},
{symbol,<<"amqp:released:list">>},
{symbol,<<"amqp:modified:list">>}]}],
[{file,"src/rabbit_amqp1_0_link_util.erl"},{line,49}]},
{rabbit_amqp1_0_link_util,outcomes,1,
[{file,"src/rabbit_amqp1_0_link_util.erl"},{line,49}]},
{rabbit_amqp1_0_outgoing_link,attach,3,
[{file,"src/rabbit_amqp1_0_outgoing_link.erl"},{line,41}]},
{rabbit_amqp1_0_session_process,with_disposable_channel,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,377}]},
{rabbit_amqp1_0_session_process,handle_control,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,197}]},
{rabbit_amqp1_0_session_process,handle_cast,2,
[{file,"src/rabbit_amqp1_0_session_process.erl"},{line,134}]},
{gen_server2,handle_msg,2,[{file,"src/gen_server2.erl"},{line,1049}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]]}}
*
I have enabled amqp_1_0 plugin in rabbitmq.
Can someone help me resolve this.
This seems a bug in rabbitmq amqp 1.0 plugin. An issue has been logged with rabbitmq.
https://github.com/rabbitmq/rabbitmq-amqp1.0/issues/31

Paho Rabitmqq connection getting failed

Here is my paho client code
// Create a client instance
client = new Paho.MQTT.Client('127.0.0.1', 1883, "clientId");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({onSuccess:onConnect});
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
client.subscribe("/World");
message = new Paho.MQTT.Message("Hello");
message.destinationName = "/World";
client.send(message);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
On Rabbitmq server everything is default seetings. When i run this code i get WebSocket connection to 'ws://127.0.0.1:1883/mqtt' failed: Connection closed before receiving a handshake response
What i am missing ?
From my personal experience with Paho MQTT JavaScript library and RabbitMQ broker on windows, here is a list of things that you need to do to be able to use MQTT from JS from within a browser:
Install rabbitmq_web_mqtt plugin (you may find latest binary here, copy it to "c:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.2\plugins\", and enable from command line using "rabbitmq-plugins enable rabbitmq_web_mqtt".
Of course, MQTT plugin also needs to be enabled on broker
For me, client was not working with version 3.6.1 of RabbitMQ, while it works fine with version 3.6.2 (Windows)
Port to be used for connections is 15675, NOT 1883!
Make sure to specify all 4 parameters when making instance of Paho.MQTT.Client. In case when you omit one, you get websocket connection error which may be quite misleading.
Finally, here is a code snippet which I tested and works perfectly (just makes connection):
client = new Paho.MQTT.Client("localhost", 15675, "/ws", "client-1");
//set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
//connect the client
client.connect({
onSuccess : onConnect
});
//called when the client connects
function onConnect() {
console.log("Connected");
}
//called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
}
//called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:" + message.payloadString);
}
It's not clear in the question but I assume you are running the code above in a web browser.
This will be making a MQTT connection over Websockets (as shown in the error). This is different from a native MQTT over TCP connection.
The default pure MQTT port if 1883, Websocket support is likely to be on a different port.
You will need to configure RabbitMQ to accept MQTT over Websockets as well as pure MQTT, this pull request for RabbitMQ seams to talk about adding this capability. It mentions that this capability was only added in version 3.6.x and that the documentaion is still outstanding (as of 9th Feb 2016)