Cannot connect to Azure ServiceBus with Microsoft.Azure.ServiceBus - c#

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();

Related

MQTTnet: Cannot send/receive CorrelationData

We are using the MQTTnet library in its lastes version to communicate. General communication is working. It's possible to subscribe and publish. The Payload and the Topic are received. But when publishing a message with CorrelationData set, in the received message only the payload and the topic exist. CorrelationData is Null.
We tested it with another application using some other C++ lib. This can send and receive Correlation data. So I assume that the MQTT broker is fine.
Is there anything to consider/configure to be able to use the CorrelationData?
Adding to Jeanot's answer the version can be set in the MqttClientOptionsBuilder.
Ex:
using (var mqttClient = mqttFactory.CreateMqttClient())
{
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost")
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500)
.Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
}

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.

Can't connect to EventHubs with Kafka Client

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.

Convert a Kerberos based WindowsIdentity into a Base64 string

If I have the following code:
var token = System.Security.Principal.WindowsIdentity.GetCurrent();
I get a WindowsIdentity that is Kerberos based. I need to make a call with a header like this:
Authorize: Negotiate <Kerberos Token Here>
Is there a way to convert that token object into a Base64 string?
As the maintainer of the Kerberos.NET as mentioned in the other answer, you can always go that route. However, if you want SSO using the currently signed in Windows identity you have to go through Windows' SSPI stack.
Many .NET clients already support this natively using Windows Integrated auth, its just a matter of finding the correct knobs. It's unclear what client you're using so I can't offer any suggestions beyond that.
However if this is a custom client you have to call into SSPI directly. There's a handful of really good answers for explaining how to do that such as: Client-server authentication - using SSPI?.
The aforementioned Kerberos.NET library does have a small wrapper around SSPI: https://github.com/dotnet/Kerberos.NET/blob/develop/Kerberos.NET/Win32/SspiContext.cs
It's pretty trivial:
using (var context = new SspiContext($"host/yourremoteserver.com", "Negotiate"))
{
var tokenBytes = context.RequestToken();
var header = "Negotiate " + Convert.ToBase64String(tokenBytes);
...
}
I could not get this to work, but I was able to get a token using the excellent Kerberos.NET NuGet package. With that I was able to get it like this:
var client = new KerberosClient();
var kerbCred = new KerberosPasswordCredential("UserName", "p#ssword", "domain");
await client.Authenticate(kerbCred);
Console.WriteLine(client.UserPrincipalName);
var ticket = await client.GetServiceTicket("http/ServerThatWantsTheKerberosTicket.domain.net");
return Convert.ToBase64String(ticket.EncodeGssApi().ToArray());
As an aside, I needed help figuring out what the SPN value was for the GetServiceTicket and the project maintainer was fantastically helpful (and fast!).

Sending to Azure Event Hub Error

I'm completely brand new to C#, Microsoft Azure, and basically everything. I'm trying to set up an Azure Event Hub that I can send data to. Right now I'm just following the tutorial that can be found here.
It builds just fine, but I receive the same exception every time. The message is the following: An existing connection was forcibly closed by the remote host. This question has been asked before but never answered.
Just to be sure I'm doing this right I'm attaching pictures with where I obtained the values for the Event Hub Connection String and the Hub Name.
Where I got the Event Hub Connection String from.
This one is within the namespace - not the hub itself.
Where I got the Hub Name from.
The code goes as follows:
private const string EventHubConnectionString = "<Connection String>";
private const string EventHubName = "eventhubtest";
Does the Hub Name have to be simply that or a path? Any ideas or help would be greatly appreciated. Thanks.
#Jamie Penzien, I had been stuck with this exact same error for days and my colleague asked me to change the following part and it worked.
var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString)
{
EntityPath = EventHubName,
TransportType = TransportType.AmqpWebSockets
};
I am still trying to understand the reason, and it may have something to do with the company's firewall settings.
Eventhub name or Entity Path would be simply the name of EventHub found under an EventHub namespace.
You can use below code to create client:
EventHubClient eventHubClient;
var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString)
{
EntityPath = EventHubName
};
eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
EventHubsConnectionStringBuilder can be found under Microsoft.Azure.EventHubs package.
I answered my own questions. First, I needed to change the connection string and make sure it contained the entity path within it. Then when establishing the hub client I did this:
eventHubClient = EventHubClient.CreateFromConnectionString(EventHubConnectionString);
HOWEVER, I was getting this exception specifically because of a firewall issue. I have to open ports (working on it right now) to allow outbound communication to the event hub. I believe these are ports 5671 and 5672.
Thank you to all that answered and #RayX who nailed it on the head.

Categories