Azure Service Bus connection string results in CloudStorageAccount.Parse error - c#

The following call
CloudStorageAccount.Parse(<connection-string>);
returns this error:
"No valid combination of account information found."
with the connection string copied directly from the CONNECTION STRING–PRIMARY KEY field on the Azure service Bus Access Policies -> Policy blade, which looks like this:
Endpoint=sb://xxx.servicebus.windows.net/;SharedAccessKeyName=xxx;SharedAccessKey=xxx;EntityPath=xxx
I need CloudQueueClient and CloudQueue instances to do queue manipulation.
Am I missing something obvious, or is there another way to initialise CloudStorageAccount?
Update: the following syntax allows me to add a new queue using the service level (not queue level) credentials, but I'm not sure how I get from here to a CloudQueue or CloudQueueClient instance.
var queueNamespace = NamespaceManager.CreateFromConnectionString(
"Endpoint=sb://<service-account>.servicebus.windows.net/;
SharedAccessKeyName=sharedaccess;
SharedAccessKey=xxx");

The reason you're getting this error is because you're trying to use storage client library for Service Bus resources. Microsoft.WindowsAzure.Storage is the client library for Azure Storage. Queues in Azure Storage are not a Service Bus Queues.
For Service Bus queues you would need to use its client library that you can install via Nuget from https://www.nuget.org/packages/WindowsAzure.ServiceBus/.
Once you do that, you should be able to create a NamespaceManager using the following code:
var manager = Microsoft.ServiceBus.NamespaceManager.CreateFromConnectionString(ConnectionString);
and then you will be able to perform operations on your Service Bus Queues.
You may find this link useful as well: https://azure.microsoft.com/en-in/documentation/articles/service-bus-dotnet-get-started-with-queues/.

Related

Do I need to add or rule or add Redis to VNet in Azure?

I enabled VNet integration on an Azure App Service and now when I attempt to connect to Redis, I receive this error message. However, I can connect without issues using Another Redis Desktop Manager.
"No connection is available to service this operation: It was not
possible to connect to the redis server(s); ConnectTimeout; IOCP:
(Busy=0,Free=1000,Min=2,Max=1000), WORKER:
(Busy=5,Free=32762,Min=2,Max=32767), Local-CPU: n/a
Do I need to add a rule to the VNet to allow the connection to Redis or does Redis need to be on the same VNet?
Currently, I'm using a Standard version in Azure and looks like I would need to create a new instance with Premium.
To resolve this "No connection is available to service this operation: It was not possible to connect to the redis server(s); ConnectTimeout error, try the following ways:
Downgrade StackExchange.Redis to v2.1.58
Use the Primary connection string (StackExchange.Redis) from Azure Access Keys as the parameter to ConnectionMultiplexer.Connect() instead of creating a ConfigurationOptions parameter using the Endpoint and Password separately.
If you are using a secure TLS connection set the ssl=True, sslprotocols=tls12 in your configuration to the latest version.
You can refer to RedisConnectionException: No connection is available to service this operation

This request is not authorized to perform this operation. I used the class "BlobServiceClient" to connect

I have read the page with the same problem as I met.
This request is not authorized to perform this operation. Azure blobClient
I have set the IP, and after I used the class "CloudStorageAccount", I can connect to the Azure Storage.
But I want to use another class "BlobContainerClient" which is used as sample code for connecting to Azure emulator "Azurite".
https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#azure-blob-storage
And I can successfully connect to Azurite in my Docker.
But I will only get the error "This request is not authorized to perform this operation.", when I change the connection string to connect to the real Azure Blob Storage.
var client = new BlobContainerClient(
new Uri("https://myaccount.blob.core.windows.net/container"),
new StorageSharedKeyCredential("myaccount", $"{AccountKey}"));
Here is what my connection string looks like. How can I connect to Azure Storage with this class? Or I should not use this class?
When use the "Selected network", due to some reasons, like you're using vpn or proxy etc., the client ip which is detected by azure is not very accurate sometimes.
So you can use this cmd command to find your real client ip: curl -L ip.tool.lu. Then manually add it in your azure portal. It works at my side.

how to detect connection issues to rabbit mq using mass transit?

how to detect if the message broker configuration is valid or if the connection to the message broker is lost using Mass Transit to RabbitMQ? When publishing messages when RabbitMQ is present does not seems to complain if there is no broker connection right away and seems to recover when the RabbitMQ server comes up. Is there a way to listen in on the connection events and warn if the configuration is not valid?
If you use .NET Core and configure MassTransit as per the docs, you can resolve the instance of IBusHealth and use it in your service.
The AddMassTransit method registers the default instance, which you can ask for the bus health status at any time. That's the method code:
public HealthResult CheckHealth()
{
var endpointHealthResult = _endpointHealth.CheckHealth();
var data = new Dictionary<string, object> {["Endpoints"] = endpointHealthResult.Data};
return _healthy && endpointHealthResult.Status == BusHealthStatus.Healthy
? HealthResult.Healthy("Ready", data)
: HealthResult.Unhealthy($"Not ready: {_failureMessage}", data: data);
}
As you can see, if you call busHealth.CheckHealth() it will return either Healthy or Unhealthy and in the latter case would also give you the list of failing endpoints.
Since BusHealth only monitors the bus itself and all its receive endpoints, you might not get notified when your service failed to publish messages.
You can use the diagnostics listener or create your own publish or send observer, which is called before and after publish/send and on any failure.

Call Azure Service Fabric from outside

I'm playing with Azure Service Fabric and a console app. I simply want my console app to connect to the cluster and do some stuff.
The console app try to resolve the service address with the following:
static void Main(string[] args)
{
ServicePartitionResolver resolver = null;
try
{
resolver = new ServicePartitionResolver(
new string[] {
"localhost:19000",
"localhost:19001"
});
Uri serviceUri = new Uri("fabric:/StatefullServiceTEST/MyStatefulService");
ResolvedServicePartition partition = resolver.ResolveAsync(serviceUri, new ServicePartitionKey(), CancellationToken.None).GetAwaiter().GetResult();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
Console.WriteLine();
Console.Write("Press any key to exit...");
Console.ReadKey();
}
My problem is that resolver.ResolveAsync throws an exception that doesn't seem to have any connection with Service Fabric:
Unable to cast COM object of type 'System.__ComObject' to interface
type 'IFabricApplicationManagementClient10'. This operation failed
because the QueryInterface call on the COM component for the interface
with IID '{67001225-D106-41AE-8BD4-5A0A119C5C01}' failed due to the
following error: No such interface supported (Exception from HRESULT:
0x80004002 (E_NOINTERFACE)).
Any ideas on this?
UPDATE
I was not so clear explaining my problem and what I want to achive.
I'm playing with Azure Service Fabric (both stateless and stateful services): my question is: what's the best way to call a micro service hosted in Azure Service Fabric?
Regards,
Attilio
You have to create a public facing service (such as Asp.net Core Web Api) which will expose the functionality of your service inside service fabric to outside world (outside the service fabric cluster). FabricClient approach is to be utilzied for calling services from within the service fabric cluster and not outside.
From your Asp.net Core service you will use the FabricClient to access the service hosted, so in general your asp.net core app act as reverse proxy to expose the functionality of actual service.
You can't use ServicePartitionResolver, it is a reliable service feature and must be called from within a service running in your cluster.
I couldn't understand clearly what you want.
If you want to manage the service and get details about it, like query running instances or replicas, add or remove instances, and so on, Use the Fabric Client, below is a quick snippet, check details here and here:
`
using System.Fabric;
using System.Security.Cryptography.X509Certificates;
string clientCertThumb = "71DE04467C9ED0544D021098BCD44C71E183414E";
string serverCertThumb = "A8136758F4AB8962AF2BF3F27921BE1DF67F4326";
string CommonName = "www.clustername.westus.azure.com";
string connection = "clustername.westus.cloudapp.azure.com:19000";
var xc = GetCredentials(clientCertThumb, serverCertThumb, CommonName);
var fc = new FabricClient(xc, connection);`
or,
If you want to communicate to a running service, like an API, you should use a Reverse Proxy to resolve your services via URL, like the below snippet, more details here:
http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService
You cannot access service in an ASF cluster from the outside using the ServicePartitionResolver.
You have to have a public facing endpoint on your cluster, like a stateless service acting as a web api for example.
From the docs:
Services connecting to each other inside a cluster generally can directly access the endpoints of other services because the nodes in a cluster are on the same local network. In some environments, however, a cluster may be behind a load balancer that routes external ingress traffic through a limited set of ports. In these cases, services can still communicate with each other and resolve addresses using the Naming Service, but extra steps must be taken to allow external clients to connect to services.
A Service Fabric cluster in Azure is placed behind an Azure Load Balancer. All external traffic to the cluster must pass through the load balancer. The load balancer will automatically forward traffic inbound on a given port to a random node that has the same port open. The Azure Load Balancer only knows about ports open on the nodes, it does not know about ports open by individual services.
So, unless your console app is hosted in the cluster as a guest executable, you have some more work to do.

Azure service bus paired namespace - simulate failover

I am working with azure service bus paired namespace and need to be able to simulate a failover to the secondary namespace. I did kind of have this working by entering an incorrect connection string for the primary namespace and saw it fail over and send the message to the secondary namespace. This no longer seems to do the trick. I can not find a way through the azure management portal or anywhere else to take a namespace offline. Anyone any ideas how to do this?
Here is my code for reference
var pairedNamespaceConfiguration = this.pairedNamespaceConfigurationDictionary[configurationKey];
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(pairedNamespaceConfiguration.PrimaryNamespace.ConnectionString);
MessagingFactory secondaryMessagingFactory = MessagingFactory.CreateFromConnectionString(pairedNamespaceConfiguration.SecondaryNamespace.ConnectionString);
NamespaceManager secondaryNamespaceManager = NamespaceManager.CreateFromConnectionString(pairedNamespaceConfiguration.SecondaryNamespace.ConnectionString);
SendAvailabilityPairedNamespaceOptions sendAvailabilityOptions = new SendAvailabilityPairedNamespaceOptions(secondaryNamespaceManager, secondaryMessagingFactory, pairedNamespaceConfiguration.BacklogQueueCount, TimeSpan.FromSeconds(pairedNamespaceConfiguration.FailoverIntervalSeconds), false);
factory.PairNamespaceAsync(sendAvailabilityOptions).Wait();
MessageSender messageSender = factory.CreateMessageSender(pairedNamespaceConfiguration.PathName);
string messageContent = JsonConvert.SerializeObject(message);
using(BrokeredMessage brokeredMessage = new BrokeredMessage(messageContent))
{
messageSender.Send(brokeredMessage);
}
Modify your \Windows\system32\drivers\etc\hosts file to point the original namespace to something like 127.0.0.1. This will make the original namespace connection fail.
I'm using this example Geo-replication with Service Bus Relayed Messages to implement the same think. Maybe it's useful for you also.
All Service Bus entities reside in a namespace. A namespace is affiliated to a datacenter. To allow for a failover between datacenters, the user must create one Service Bus and ACS namespace (in case ACS is used) per datacenter. Any Service Bus relay that needs to remain accessible in the presence of datacenter failures must be created in both namespaces.
The server opens two NetTcp relay endpoints, one in each of the two namespaces. The server processes any request that is received via one of these endpoints. Note that the two relays have to have different names (.e.g, address of primary relay is sb://myPrimaryNamespace.servicebus.windows.net/myService-primary and b://mySecondaryNamespace.servicebus.windows.net/myService-secondary).
The client considers one of the two replicated relays as the active relay and the other one as a backup. It opens a channel to the active relay and invokes methods on the service. If the invocation fails with any exception that is not part of the service contract, the client abandons the channel, opens a channel to the backup relay, and invokes the service method again. The client will consider the new channel to be the active channel and continues to use that channel until the next fault occurs.

Categories