Can't connect to EventHubs with Kafka Client - c#

I have an event hubs instance with a “test” eventhub.
I can connect to this and publish messages with the native client "Azure.Messaging.EventHubs"
However when I try to connect with the Confluent.Kafka (v1.1.0) client I get
“Unknown error (after 21286ms in state CONNECT)”
%3|1655301022.374|ERROR|rdkafka#producer-1|
[thrd:sasl_plaintext://my-event-hub-namespace.servicebus.windows.net:9093/bootstra]:
1/1 brokers are down
I'm setting the producer config, and creating producer as below
var config = new ProducerConfig
{
BootstrapServers = "my-eventhub-namespace.servicebus.windows.net:9093",
SecurityProtocol = SecurityProtocol.SaslSsl,
SaslMechanism = SaslMechanism.Plain,
SaslUsername = "$ConnectionString",
SaslPassword = "Endpoint=sb://my-eventhub-namespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=MySharedAccessKey==",
};
using (var producer = new ProducerBuilder<long, string>(config).SetKeySerializer(Serializers.Int64).SetValueSerializer(Serializers.Utf8).Build())
{
Any ideas as to where I'm going wrong?
Update :
When connecting with the native client it's connecting using WebSockets, so it's probably networking/firewall issue.
Thanks for your time.

A couple of things to try
Firewall check for EH endpoint. Make sure the client can connect to my-eventhub-namespace.servicebus.windows.net:9093.
Try with a namespace-level connection string if you used entity-level SAS.

Related

IBMMQDotnet client retry mechanism

Hi everyone i am completely new to queues and especialy to IBMMQDotnet cleint library. Currently my application trying to send DTO object to the queue and sometimes it could faailed for various reasons like exception occuring or network issue. Is there any retrie mechanism ?i would like to implement retry mechansim, i tried to google it but could not found any example. Bellow is the current code
if (!TryConnectToQueueManager())
{
return;
}
using var destination = GetMqObjectForWrite(message.Destination, message.DestinationType);
var mqMessage = new MQMessage
{
Format = MQC.MQFMT_STRING,
CharacterSet = 1208
};
if (message.Headers?.Count > 0)
{
foreach (var (key, value) in message.Headers)
{
mqMessage.SetStringProperty(key, value);
}
}
mqMessage.WriteString(JsonSerializer.Serialize(message.Data));
destination.Put(mqMessage);
destination.Close();
IBM MQ provides a feature called as Client Auto Reconnect.You could refer the following KC page Client Auto Reconnect
If there is a connection failure because of the network issue, the IBM MQ client will try to re-establish a connection to the Queue Manager for a specific time period(which is configurable) before throwing an exception to the application
You could refer to the sample "SimpleClientAutoReconnectPut" & "SimpleClientAutoReconnectGet" which are available as part of the client installation.

Cannot connect to Azure ServiceBus with Microsoft.Azure.ServiceBus

I have created a very simple console application that connects to Azure ServiceBus and sends one message. I tried the latest library from Microsoft (Microsoft.Azure.ServiceBus) but no matter what I do I just get this error:
No connection could be made because the target machine actively
refused it ErrorCode: ConnectionRefused
I have tried exactly the same connection string in Service Bus Explorer and it does work just fine. Moreover I connected without problems using the older library from Microsoft (WindowsAzure.ServiceBus).
var sender = new MessageSender("endpoint", "topicName");
sender.SendAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject("test"))));
I tried with .NET Framework 4.6.2 and Core, same exception. I suspect there may be some differences in the default protocol that these libraries use, but I could not figure out that for sure.
P.S. Have tried the example from Microsoft docs but result is still the same exception
The old client supported ConnectivityMode using TCP, HTTP, HTTPS, and AutoDetect. ServiceBus Explorer is using AutoDetect, trying TCP first and then failing over to HTTPS, regardless of the TransportMode you were using (SBMP or AMQP).
With the new client this has changed. TransportMode now combines both options and offers Amqp (AMQP over TCP) or AmqpWebSockets (AMQP over WebSockets). There's no AutoDetect mode. You will have to create your clients and specify TransportType as AmqpWebSockets to bypass blocked TCP port 5671 and instead use port 443.
It seems that the documentation is lacking a lot on how to connect using HTTPS (Amqp over WebSockets) but after some help from Sean Feldman in the accepted answer I managed to connect. Here is the code that I used if someone is interested:
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
"RootManageSharedAccessKey", // SharedAccessKeyName
"SomeToken");
var sender = new MessageSender(
"sb://mydomain.servicebus.windows.net/",
"topicName",
tokenProvider,
TransportType.AmqpWebSockets);
Or a variant that let's you have the whole connection string in one piece
var builder = new ServiceBusConnectionStringBuilder("YouConnectionString");
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
builder.SasKeyName,
builder.SasKey);
var sender = new MessageSender(
builder.Endpoint,
"TopicName",
tokenProvider,
TransportType.AmqpWebSockets);
It is actually possible to use ConnectionString directly but then it has to be augmented to use the right protocol.
var sender = new MessageSender("TransportType=AmqpWebSockets;Endpoint=...", "TopicName")
Or the version that allows to embed EntityPath into the ConnectionString
var connectionBuilder = new ServiceBusConnectionStringBuilder("EntityPath=MyTopic;TransportType=AmqpWebSockets;Endpoint=...")
var sender = new MessageSender(connectionBuilder);
I was having the same issue but his worked for me
var clientOptions = new ServiceBusClientOptions();
clientOptions.TransportType = ServiceBusTransportType.AmqpWebSockets;
client = new ServiceBusClient(connectionString, clientOptions);
sender = client.CreateSender(topicName);
// create a batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

Azure and SignalR: System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions

I'm currently experiencing this issue at a high frequency:
System.Net.Sockets.SocketException: An attempt was made to access a
socket in a way forbidden by its access permissions
Sometimes it happens when connecting to Azure Storage from my web app (code below), but most of the time it happens with SignalR.
Based on debug diag, I see the following:
394 client connections in w3p.dmp have been executing a request for more than 90 seconds.
Based on the memory dump, there are a significant number of connections being made to /signalr/connect and /signalr/reconnect.
It looks like I'm using AspNet.SignalR.WebSockets.WebSocketHandler to make SignalR connections from within code. At this point I'm not sure what to look for though - what could be the culprit? We have a web service living in Azure, with web apps and mobile apps connecting to a SignalR backplane (redis).
Screen from debug diag
Code for Azure Storage
public void EnqueueRequest(int requestId)
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings.Get("AzureStorageConnectionString"));
// Create the queue client.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// Retrieve a reference to a queue.
CloudQueue queue = queueClient.GetQueueReference(ConfigurationManager.AppSettings.Get("requestQueueName"));
// Create a message and add it to the queue.
CloudQueueMessage message = new CloudQueueMessage(castingCallId.ToString(CultureInfo.InvariantCulture));
queue.AddMessage(message);
}
Hub Proxy Code
var baseUrl = _dbContext.CurrentTenant.BaseUrl;
_hubConnection = new HubConnection(baseUrl);
_hubProxy = _hubConnection.CreateHubProxy("appHub");
await _hubConnection.Start();
string serialized = null;
try
{
serialized = JsonSerializerExtensions.SerializeObject(data).SanitizeData();
await _hubProxy.Invoke((isTypingNotification ? "SendTypingNotification" : "SendClientNotification"), serialized, username);
}
catch (Exception exception)
{
LogError("1: " + exception);
}
SB2055 and I worked on this and made the following changes to eliminate this issue:
Do not create a HubConnection for each message to send. A HubConnection is a heavyweight object and should be created once and reused. You can recreate the IHubProxy multiple times if needed. You can accomplish this by setting the HubConnection as a class static member variable.
We changed the connection type from web sockets to long polling.

Unacknowledged message on ActiveMQ with fail over setup is not redelivered to subscriber

I am implementing Active MQ publisher and subscriber in c#. I am using Apache.NMS.ActiveMQ .net client library to communicate with the broker.
<package id="Apache.NMS" version="1.7.1" targetFramework="net461" />
<package id="Apache.NMS.ActiveMQ" version="1.7.2" targetFramework="net461" />
ActiveMQ is configured with a fail over setup on 4 servers (.225, .226, .346, .347 - last parts of IP for reference) . The broker url looks something like
failover://tcp://103.24.34.225:61616,tcp://103.24.34.226:61616,tcp://103.24.34.346:61616,tcp://103.24.34.347:61616
Here is how I am publishing
var brokerUrl = "failover://tcp://103.24.34.225:61616,tcp://103.24.34.226:61616,tcp://103.24.34.346:61616,tcp://103.24.34.347:61616";
var connectionFactory = new ConnectionFactory(brokerUrl);
using (var connection = connectionFactory.CreateConnection("conn1", "conn$34"))
{
connection.ClientId = "TESTPUBLISHER";
connection.AcknowledgementMode = AcknowledgementMode.ClientAcknowledge;
connection.Start();
var session = connection.CreateSession();
var topic = new ActiveMQTopic("ACCOUNT.UPDATE");
var producer = session.CreateProducer(topic);
var msg = "43342_test"; //DateTime.Now.ToString("yyyyMdHHmmss_fff") + "-TEST";
var textMessage = producer.CreateTextMessage(msg);
textMessage.Properties.SetString("Topic", "ACCOUNT.UPDATE");
textMessage.Properties.SetString("Action", "UPDATE");
textMessage.Properties.SetString("DataContractType", "Account");
producer.Send(textMessage, MsgDeliveryMode.Persistent, MsgPriority.Normal, new TimeSpan(0, 0, 60, 0, 0));
}
Here is how I am subscribing to the topic. This code is setup such that, multiple shared subscribers can listen for incoming messages. I was told I have to use Virtual Topics to accomplish that. So I configured my subscriber to use Virtual Topic and it is hosted inside a Windows Service project. I am using Acknowledgement Mode to be ClientAcknowledge, so that unless a message is acknowledged, it should keep coming back. Below code snippet is representing just the important subscriber portion of the windows service.
var brokerUrl = "failover://tcp://103.24.34.225:61616,tcp://103.24.34.226:61616,tcp://103.24.34.346:61616,tcp://103.24.34.347:61616";
IConnectionFactory factory = new ConnectionFactory(new Uri(brokerUrl));
IConnection connection = factory.CreateConnection("conn1", "conn$34"))
connection.ClientId = "TESTSUBSCRIBER";
connection.AcknowledgementMode = AcknowledgementMode.ClientAcknowledge;
connection.ConnectionInterruptedListener += OnConnectionInturrupted;
connection.ExceptionListener += OnConnectionExceptionListener;
connection.ConnectionResumedListener += OnConnectionResumedListener;
connection.Start();
ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
var queue = new ActiveMQQueue("VT.TESTSUBSCRIBER.ACCOUNT.UPDATE");
ActiveMQTopic topic = new ActiveMQTopic();
IMessageConsumer consumer = session.CreateConsumer(queue);
consumer.Listener += OnMessage;
private void OnMessage(IMessage message)
{
var payload = ((ITextMessage)message).Text;
Log.Info($"Received message for Client TESTSUBSCRIBER - [{payload}]");
if(payload != "43342_test")
{
message.Acknowledge();
Log.Info($"Message acknowledged for Client TESTSUBSCRIBER - [{payload}]");
}
}
private void OnConnectionResumedListener()
{
Log.Info($"Subscriber connection resumed for Client TESTSUBSCRIBER");
}
private void OnConnectionExceptionListener(Exception exception)
{
Log.Error(exception);
}
private void OnConnectionInturrupted()
{
Log.Error($"Subscriber connection interrupted for Client TESTSUBSCRIBER");
}
I am able to publish and subscriber messages. I am running into an issue with one particular case. Lets say the subscriber established connection to the (.225 broker server) from the pool of fail over servers. The publisher published a message. Subscriber received it and it is in the middle of processing. But due to some server patch maintenance, the windows service had to shutdown. As a result the subscriber connection to the broker got disconnected. When windows service came back up, this time subscriber established connection to a different broker server (.346 broker server) from the fail over pool. When that happened, the unacknowledged message never got re-delivered. But If I restart the windows service and by any luck If connection was established to .225 broker (same server to which subscriber was originally connected to), now the subscriber receives the unacknowledged message.
My assumption is that when ActiveMQ is configured in a fail over setup, no matter which broker server from the fail over pool the subscriber is able to establish a connection to, it should always receive the unacknowledged messages.
In some situations fail over setup appears to be working. Lets assume the subscriber was connected to .346 broker server from the fail over pool. The publisher is connected to different broker server (.225 broker) from the same pool and publish a message, subscriber is receiving messages. This proves that Fail over setup is working.
But once a subscriber receives a message from a broker server and if the subscriber is disconnected prior to acknowledging the message, it has to reestablish connection to the same broker server to receive the unacknowledged message. This does not sound right to me.
Is there any additional configuration required on the Active MQ server setup to make this use case work?
The solution to this problem was not on the client side, but rather with the Active MQ server configuration.
For Producer flow control destination policy, add ConditionalNetworkBridgeFilter and enable replayWhenNoConsumers.

Publishing to a Cloud hosted Azure service bus from behind proxy

Ive read through the other service bus related questions but cant find a solution so sorry if this is in fact a duplicate.
Im trying to connect and publish to a Cloud hosted Azure Service Bus from behind my workplace's proxy. I understand I need to set the Connectivity mode to http to get the post through the firewall but how do I give the namespaceManager object the credentials and IP required for our proxy server to get the message sent out to the net?
at the moment I have:
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
// Configure Topic Settings
TopicDescription td = new TopicDescription("TestTopic");
td.MaxSizeInMegabytes = 5120;
td.DefaultMessageTimeToLive = new TimeSpan(0, 1, 0);
//Establish connection to service bus
string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
Console.WriteLine("Setting up NamespaceManager");
var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
Console.WriteLine("NamespaceManager created for " + namespaceManager.Address.ToString());
Console.WriteLine("Attempting to access topic on " + namespaceManager.Address.ToString());
//Create a topic
Console.WriteLine("Creating topic");
if (!namespaceManager.TopicExists("TestTopic")) {
namespaceManager.CreateTopic(td);
Console.WriteLine("Topic created successfully");
}
else {
Console.WriteLine("Topic already exists");
}
I've seen some examples but none seem to apply any proxy settings to the outgoing requests . Thank you in advance :)

Categories