web-serviceswcfendpointsidispatchmessageinspectorazure-eventhub

Sending to Service Bus Event Hubs from a WCF Message Inspector


I've got a working web service and test client and i can intercept the messages between them. but when i add the code to send to my event hub the client shows a fault:

An unhandled exception of type 'System.ServiceModel.FaultException`1' occurred in mscorlib.dll

Additional information: The argument Endpoints is null or empty.

Parameter name: Endpoints

The more detailed exception:

System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]:    The argument Endpoints is null or empty.
Parameter name: Endpoints (Fault Detail is equal to An ExceptionDetail,  likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.ArgumentException: The argument Endpoints is null or empty.
Parameter name: Endpoints
at Microsoft.ServiceBus.ServiceBusConnectionStringBuilder.Validate()
at Microsoft.ServiceBus.ServiceBusConnectionStringBuilder.ToString()
at  Microsoft.ServiceBus.Messaging.Configuration.KeyValueConfigurationManager.
Initialize(String connection, Nullable`1 transportType)
at Microsoft.ServiceBus.Messaging.Configuration.KeyValueConfigurationManager.
.ctor(Nullable`1 transportType)
at Microsoft.ServiceBus.Messaging.EventHubClient.Create(String path)
at WCFInterceptor.MessageInspector.AfterReceiveRequest(Message& request,  ICli
entChannel channel, InstanceContext instanceContext)
at  System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.AfterReceiveReques
tCore(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(Me
ssageRpc& rpc)
at System.ServiceModel.Dispatc...).

And heres the code i add:

try
        {
            NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(GetServiceBusConnectionString());
            Manage.CreateEventHub(hubName, 16, namespaceManager);
        }
        catch (Exception e)
        {
            Console.WriteLine("SetupEHError" + e);
        }
        EventHubClient client = EventHubClient.Create(hubName);
        Console.WriteLine("eventhubclient iniciado");
        EventData messageData = new EventData(Encoding.UTF8.GetBytes(serializedString));

        try
        {
            client.Send(messageData);
            Console.WriteLine("MessageData enviada");
        }
        catch (Exception e)
        {

            Console.WriteLine("ErrorMessage:" + e);
        }

Here is the CreateEventHub Method:

public static void CreateEventHub(string eventHubName, int        numberOfPartitions, NamespaceManager manager)
    {
        try
        {
            // Create the Event Hub
            Console.WriteLine("Creating Event Hub...");
            EventHubDescription ehd = new EventHubDescription(eventHubName);
            ehd.PartitionCount = numberOfPartitions;
            manager.CreateEventHubIfNotExistsAsync(ehd).Wait();
            Console.WriteLine("Created");
        }
        catch (AggregateException agexp)
        {
            Console.WriteLine(agexp.Flatten());
        }
    }

The WebService Console App prints up to

Creating Event Hub
Created

So i was thinking i might need to add Endpoints for the MessageInspector in the WebService to be able to send data to a Service Bus Event Hub. if so, how is the configuration?

Thanks in Advance


Solution

  • Background:

    ServiceBus SDK has 2 major interfaces:

    1. NamespaceManager: for all Management operations (aka Control Plane) like Create Delete Topics/EHubs etc
    2. EntityClients (TopicClient, EventHubClient etc) : for runtime operations (aka Data Plane) - to Send/Recv from Topics/EventHubs.

    Both these interfaces will need their own connection strings for connecting to ServiceBus. For ex: The connection string specified to NamespaceManager will need ManageClaims and for EntityClients will just need Send/Recv claims.

    You created EventHubClient with just EventHub Name and didn't pass connection string there. In this case, the above error is thrown from our ServiceBus client sdk - when the connection string is not passed via app.config. To fix this, change this line (as you are using ConnectionString directly for NamespaceManager and not using any app.config):

    EventHubClient client = EventHubClient.Create(hubName);
    

    Change it to:

    ----edit-----
        var eHubConnStr = GetServiceBusConnectionString();
        eHubConnStr.EntityPath = eventHubName;
        // Evaluate here, if you have to populate the Security related properties from the ConnectionString
        // eHubConnStr.SasKey and SasKeyName to Send only or Recv only
    ----edit-----
        EventHubClient client = EventHubClient.CreateFromConnectionString(eHubConnStr); // this connection string should be the EventHub Send conn str.
    

    HTH! Sree