Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add message header to the request when using default client of Azure service fabric?

I am wondering it is possible to inject custom message header to outgoing request to carry additional information without deserialize the payload to fullfill the functionality like authentication, validation or correlation of request like wcf provided by means of messagesinspector?

like image 679
Xiangdong Avatar asked Dec 08 '15 21:12

Xiangdong


People also ask

How do I send a custom request header?

For example, to send a GET request with a custom header name, you can use the "X-Real-IP" header, which defines the client's IP address. For a load balancer service, "client" is the last remote host. Your load balancer intercepts traffic between the client and your server.

Which type of services are available in Visual Studio while creating service fabric application?

The Service Fabric SDK includes an add-in for Visual Studio that provides templates and tools for creating, deploying, and debugging Service Fabric applications. This topic walks you through the process of creating your first application in Visual Studio.

What is Microsoft Azure service fabric?

Azure Service Fabric is a distributed systems platform that makes it easy to package, deploy, and manage scalable and reliable microservices and containers. Service Fabric also addresses the significant challenges in developing and managing cloud native applications.


1 Answers

Update

With SDK v2 you can now (relatively) easily modify the headers of both Reliable Services and Actors. Note in the examples below some wrapper members were omitted for brevity.

Client

We use ServiceProxyFactory to create proxies instead of the static ServiceProxy. Then we can wrap IServiceRemotingClientFactory and IServiceRemotingClient and intercept the service calls. The same can be done with ActorProxyFactory. Note this overrides the behavior of attributes such as the WcfServiceRemotingProviderAttribute, since we explicitly specify the client factory ourselves.

_proxyFactory = new ServiceProxyFactory(c => new ServiceRemotingClientFactoryWrapper(
 // we can use any factory here
 new WcfServiceRemotingClientFactory(callbackClient: c)));

    private class ServiceRemotingClientFactoryWrapper : IServiceRemotingClientFactory
    {
        private readonly IServiceRemotingClientFactory _inner;

        public ServiceRemotingClientFactoryWrapper(IServiceRemotingClientFactory inner)
        {
            _inner = inner;
        }

        public async Task<IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector,
            string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var client = await _inner.GetClientAsync(serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken).ConfigureAwait(false);
            return new ServiceRemotingClientWrapper(client);
        }
    }

    private class ServiceRemotingClientWrapper : IServiceRemotingClient
    {
        private readonly IServiceRemotingClient _inner;

        public ServiceRemotingClientWrapper(IServiceRemotingClient inner)
        {
            _inner = inner;
        }

        public Task<byte[]> RequestResponseAsync(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
        {
            // use messageHeaders.AddHeader() here
            return _inner.RequestResponseAsync(messageHeaders, requestBody);
        }

        public void SendOneWay(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
        {
            // use messageHeaders.AddHeader() here
            _inner.SendOneWay(messageHeaders, requestBody);
        }
    }

Server

Inherit from ServiceRemotingDispatcher and ActorServiceRemotingDispatcher to examine the headers.

class CustomServiceRemotingDispatcher : ServiceRemotingDispatcher
{
    public override async Task<byte[]> RequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
    {
        // read messageHeaders here
        // or alternatively put them in an AsyncLocal<T> scope
        // so they can be accessed down the call chain
        return base.RequestResponseAsync(requestContext, messageHeaders, requestBody);
    }
}

To use this class, again we need to override the ServiceRemotingProviderAttribute by directly creating the communication listener:

class MyService : StatelessService
{
     protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
          yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher());
     }
}
like image 84
Eli Arbel Avatar answered Sep 28 '22 05:09

Eli Arbel