最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Cannot connect to Azure Event Hub - Stack Overflow

programmeradmin1浏览0评论

I am trying to use azure-sdk-for-cpp to connect to Azure Event Hub. But it is not working, I get error "Could not open Claims Based Security object." I am following samples in the sources. I have just this simple code and exception is thrown in GetEventHubProperties:

Azure::Messaging::EventHubs::ProducerClient producerClient(connectionString, eventhubName);
Azure::Messaging::EventHubs::Models::EventHubProperties eventhubProperties = producerClient.GetEventHubProperties();

In Azure Portal I have created resource group with Event Hubs Namespace. In it I have Event Hub called "tolp-985-event-hub" which I am using as eventhubName. I was trying various things as connectionString: From Event Hubs Namespace - Settings - Shared Access Policies - RootManageSharedAccessKey - Connection string–primary key. I tried also from Event Hub itself - Settings - Shared Access Policies - it was empty, I created a new policy with Manage+Send+Listen and from there Connection string–primary key. I tried without "EntityPath" in the connection string. I tried with it and with empty eventhubName, I tried various combinations but none working. I am probably missing some simple configuration or something...

To test if this is no fundamental problem with my environment etc. I tried something different from samples, to create a blob container with some content such as:

auto containerClient = Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connectionString, containerName);
containerClient.CreateIfNotExists();
for (int j = 0; j < 3; ++j) {
    Azure::Storage::Blobs::BlockBlobClient blobClient = containerClient.GetBlockBlobClient(blobName + std::to_string(j));
    blobClient.UploadFrom(reinterpret_cast<const uint8_t*>(blobContent.data()), blobContent.size());
}

There I use connection string from Storage Account and it works fine. But connection string from Storage Account starts with "DefaultEndpointsProtocol=https;AccountName=" and maybe it is something very different from connection string for Event Hub, which starts with "Endpoint=sb://tolp-985-event-hubs-namespace.servicebus.windows/;SharedAccessKeyName=".

Thanks for any hint to get over this initial problem.

EDIT, code and images:

try {
    string connectionString = "Endpoint=sb://tolp-985-event-hubs-namespace.servicebus.windows/;SharedAccessKeyName=tolp-985-policy;SharedAccessKey=GGQyg...;EntityPath=tolp-985-event-hub";
    string eventhubName = "tolp-985-event-hub";
    Azure::Messaging::EventHubs::ProducerClient producerClient(connectionString, eventhubName);
    Azure::Messaging::EventHubs::Models::EventHubProperties eventhubProperties = producerClient.GetEventHubProperties();
} catch (std::exception &e) {
    std::cout << e.what() << std::endl;
}

Event Hubs Namespace with Event Hub in it:

SAS Policy in the Event Hub:

I am trying to use azure-sdk-for-cpp to connect to Azure Event Hub. But it is not working, I get error "Could not open Claims Based Security object." I am following samples in the sources. I have just this simple code and exception is thrown in GetEventHubProperties:

Azure::Messaging::EventHubs::ProducerClient producerClient(connectionString, eventhubName);
Azure::Messaging::EventHubs::Models::EventHubProperties eventhubProperties = producerClient.GetEventHubProperties();

In Azure Portal I have created resource group with Event Hubs Namespace. In it I have Event Hub called "tolp-985-event-hub" which I am using as eventhubName. I was trying various things as connectionString: From Event Hubs Namespace - Settings - Shared Access Policies - RootManageSharedAccessKey - Connection string–primary key. I tried also from Event Hub itself - Settings - Shared Access Policies - it was empty, I created a new policy with Manage+Send+Listen and from there Connection string–primary key. I tried without "EntityPath" in the connection string. I tried with it and with empty eventhubName, I tried various combinations but none working. I am probably missing some simple configuration or something...

To test if this is no fundamental problem with my environment etc. I tried something different from samples, to create a blob container with some content such as:

auto containerClient = Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connectionString, containerName);
containerClient.CreateIfNotExists();
for (int j = 0; j < 3; ++j) {
    Azure::Storage::Blobs::BlockBlobClient blobClient = containerClient.GetBlockBlobClient(blobName + std::to_string(j));
    blobClient.UploadFrom(reinterpret_cast<const uint8_t*>(blobContent.data()), blobContent.size());
}

There I use connection string from Storage Account and it works fine. But connection string from Storage Account starts with "DefaultEndpointsProtocol=https;AccountName=" and maybe it is something very different from connection string for Event Hub, which starts with "Endpoint=sb://tolp-985-event-hubs-namespace.servicebus.windows/;SharedAccessKeyName=".

Thanks for any hint to get over this initial problem.

EDIT, code and images:

try {
    string connectionString = "Endpoint=sb://tolp-985-event-hubs-namespace.servicebus.windows/;SharedAccessKeyName=tolp-985-policy;SharedAccessKey=GGQyg...;EntityPath=tolp-985-event-hub";
    string eventhubName = "tolp-985-event-hub";
    Azure::Messaging::EventHubs::ProducerClient producerClient(connectionString, eventhubName);
    Azure::Messaging::EventHubs::Models::EventHubProperties eventhubProperties = producerClient.GetEventHubProperties();
} catch (std::exception &e) {
    std::cout << e.what() << std::endl;
}

Event Hubs Namespace with Event Hub in it:

SAS Policy in the Event Hub:

Share Improve this question edited Nov 19, 2024 at 15:35 MartinD asked Nov 19, 2024 at 7:36 MartinDMartinD 215 bronze badges 4
  • 1 The issue is with the connection to your Azure Event Hub, often related to the connection string or permissions. Check the Shared Access Policy has Manage, Send, and Listen permissions. – Dasari Kamali Commented Nov 19, 2024 at 9:34
  • 1 EventHub and Storage connection string formate is different. – Dasari Kamali Commented Nov 19, 2024 at 10:01
  • As stated, I tried connection strings both for Event Hub Namespace (there was already SAS Policy: RootManageSharedAccessKey) and for Event Hub itself in the namespace (there was no policy, I created new SAS Policy: test-985-policy). For both policies I have Manage checked, which automatically checks also Send and Listen. I copied "Connection string–primary key" (not just "Primary key") from each of them, none worked for some reason. – MartinD Commented Nov 19, 2024 at 11:05
  • The code is really just those two lines quoted above. Creating ProducerClient with connectionString and calling GetEventHubProperties on it. connectionString is what I wrote I tried. eventhubName is the name of the event hub (I tried just the name, tried also with namespace prefix). It throws mentioned exception. I can provide any more details of course, but it seems so simple. Test code is from samples, so probably portal side of configuration is wrong, I have no idea. I build it on Ubuntu, I used vcpkg to get sdk and it is working with blob container sample, but I need event hub... – MartinD Commented Nov 19, 2024 at 11:56
Add a comment  | 

2 Answers 2

Reset to default 0

I have tried the sample code in my environment, it worked fine for me to send the messages to the Azure Event Hub.

  • Make sure to use the Event Hubs Namespace > Event Hub > Shared Access Policies > connection string with proper Manage, Send, and Listen permissions.

The Azure Event Hub connection string must be in the below format,

Endpoint=sb://<namespace>.servicebus.windows/;SharedAccessKeyName=<poli-name>;SharedAccessKey=<key>;EntityPath=<eventhub-name>

main.cpp :

#include <azure/messaging/eventhubs.hpp>
#include <iostream>
#include <cstdlib> 

int main()
{
  const char* eventhubConnectionString = std::getenv("EVENTHUB_CONNECTION_STRING");
  const char* eventhubName = std::getenv("EVENTHUB_NAME");

  if (eventhubConnectionString == nullptr)
  {
    std::cerr << "Missing environment variable EVENTHUB_CONNECTION_STRING" << std::endl;
    return 1;  
  }
  if (eventhubName == nullptr)
  {
    std::cerr << "Missing environment variable EVENTHUB_NAME" << std::endl;
    return 1; 
  }

  try
  {
    Azure::Messaging::EventHubs::ProducerClient producerClient(eventhubConnectionString, eventhubName);
    Azure::Messaging::EventHubs::Models::EventHubProperties eventhubProperties = producerClient.GetEventHubProperties();
    Azure::Messaging::EventHubs::EventDataBatchOptions batchOptions;
    batchOptions.PartitionId = eventhubProperties.PartitionIds[0];
    Azure::Messaging::EventHubs::EventDataBatch batch(producerClient.CreateBatch(batchOptions));
    {
      Azure::Messaging::EventHubs::Models::EventData event;
      event.Body = {1, 3, 5, 7};
      event.MessageId = "test-message-id-1";
      if (!batch.TryAdd(event))
      {
        std::cerr << "Failed to add the event to the batch (Event 1)" << std::endl;
        return 1;
      }
    }
    {
      Azure::Messaging::EventHubs::Models::EventData event;
      event.Body = {2, 4, 6, 8, 10};
      event.MessageId = "test-message-id-2";
      if (!batch.TryAdd(event))
      {
        std::cerr << "Failed to add the event to the batch (Event 2)" << std::endl;
        return 1;
      }
    }
    {
      Azure::Messaging::EventHubs::Models::EventData event{1, 1, 2, 3, 5, 8};  
      event.MessageId = "test-message-id-fibonacci";
      if (!batch.TryAdd(event))
      {
        std::cerr << "Failed to add the event to the batch (Fibonacci)" << std::endl;
        return 1;
      }
    }
    {
      Azure::Messaging::EventHubs::Models::EventData event{"Hello Eventhubs!"};
      event.MessageId = "test-message-id-helloworld";
      if (!batch.TryAdd(event))
      {
        std::cerr << "Failed to add the event to the batch (Hello Eventhubs)" << std::endl;
        return 1;
      }
    }

    producerClient.Send(batch);
    std::cout << "Events successfully sent to Event Hub!" << std::endl;
  }
  catch (const std::exception& e)
  {
    std::cerr << "An error occurred: " << e.what() << std::endl;
    return 1; 
  }
  return 0; 
}

CMakeLists.txt :

cmake_minimum_required(VERSION 3.10)
project(MyAzureEventHubsProject)

set(CMAKE_TOOLCHAIN_FILE "C:/Users/kamali/Documents/xxxxxx/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Toolchain file for vcpkg")

find_package(azure-messaging-eventhubs-cpp CONFIG REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE Azure::azure-messaging-eventhubs)

Output :

I ran the below command to set the Azure EventHub connection string and Event Hub Name in the env varaibles.

set EVENTHUB_CONNECTION_STRING="<EventHubConneString>"
set EVENTHUB_NAME="<HubName>"

The following code ran successfully and sent the messages to the Azure Event Hub as shown below.

Azure Event Hub :

The approach was correct. Configuration of Azure Portal was proper as verified by Python script doing the same operations. Connection string was used properly.

There was also no problem in the code itself built using Azure SDK for cpp.

Problem was in refused certificates. Although it worked from Python script and from C++ with BlobStorage, connection was refused from C++ with EventHub. Problem was in environment configuration related to Certificate Authority, SSL_CERT_FILE had to be set properly. Could be set in environment or in the code itself like

setenv("SSL_CERT_FILE", "/etc/ssl/certs/ca-certificates.crt", 1);

The test was done in Ubuntu.

To pinpoint the problem, detailed logs were activated by:

Azure::Core::Diagnostics::Logger::SetLevel(Azure::Core::Diagnostics::Logger::Level::Verbose);
Azure::Core::Diagnostics::Logger::SetListener([](Azure::Core::Diagnostics::Logger::Level, std::string const& message) {
    std::cout << "LOG: " << message << std::endl;
});
发布评论

评论列表(0)

  1. 暂无评论