4

My situation:

Problem:

I'm trying to change the communication between my Stateful Service and my Stateless WebAPI from RPC to HTTP Communication because I want to avoid using an interface to communicate between the services. Is this even possible with HTTP Communication? If so, how can my stateless WebAPI call specific methods in my Stateful application without using an interface?

UPDATE:

Thanks to alltej, I started reading up more on HttpCommunicationListeners. This tutorial (https://learn.microsoft.com/nl-nl/azure/service-fabric/service-fabric-concepts-partitioning) explained Http Communication pretty well.

In the code snippet below: "CreateServiceReplicaListeners()" calls CreateInternalListener() which then calls "ProcessInternalRequest()" which then finally calls "AddUserAsync()".

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        return new[] { new ServiceReplicaListener(context => this.CreateInternalListener(context))};
    }

    private ICommunicationListener CreateInternalListener(ServiceContext context)
    {
        EndpointResourceDescription internalEndpoint = context.CodePackageActivationContext.GetEndpoint("ProcessingServiceEndpoint");

        string uriPrefix = String.Format(
            "{0}://+:{1}/{2}/{3}-{4}/",
            internalEndpoint.Protocol,
            internalEndpoint.Port,
            context.PartitionId,
            context.ReplicaOrInstanceId,
            Guid.NewGuid());

        string nodeIP = FabricRuntime.GetNodeContext().IPAddressOrFQDN;

        string uriPublished = uriPrefix.Replace("+", nodeIP);
        return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInternalRequest);
    }

    private async Task ProcessInternalRequest(HttpListenerContext context, CancellationToken cancelRequest)
    {
        string output = null;
        string user = context.Request.QueryString["lastname"].ToString();

        try
        {
            output = await this.AddUserAsync(user);
        }
        catch (Exception ex)
        {
            output = ex.Message;
        }

        using (HttpListenerResponse response = context.Response)
        {
            if (output != null)
            {
                byte[] outBytes = Encoding.UTF8.GetBytes(output);
                response.OutputStream.Write(outBytes, 0, outBytes.Length);
            }
        }
    }

    private async Task<string> AddUserAsync(string user)
    {
        IReliableDictionary<String, String> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<String, String>>("dictionary");

        using (ITransaction tx = this.StateManager.CreateTransaction())
        {
            bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user);

            await tx.CommitAsync();

            return String.Format(
                "User {0} {1}",
                user,
                addResult ? "sucessfully added" : "already exists");
        }
    }
}
TheSugoiBoi
  • 160
  • 1
  • 13

1 Answers1

3

MyCustomHttpListener is a class that you have to create as your own custom listener that implements the ICommunicationListener. It contains the three methods you need to override. See example here for an OwinCommunicationListener: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-webapi

alltej
  • 6,787
  • 10
  • 46
  • 87
  • I've created the HttpCommunicationListener.cs which implements ICommunicationListener. I can resolve the stateful service's URI but how do i call specific methods/functions in the stateful service from my stateless webapi? – TheSugoiBoi Dec 25 '16 at 00:02
  • You need call the stateless methods from stateful service coz you need the manage the transactions in the reliable queue. You call it your inside the RunAsync method of the reliable service. – alltej Dec 25 '16 at 01:44
  • Wait...I need to call stateless methods from stateful service? shouldn't it be the other way around? I want my stateless WebApi (POST action) to call "Blah()" task in my stateful service. – TheSugoiBoi Dec 25 '16 at 02:44
  • From stateless web api gateway, call stateful service method to add request into reliable queue. In RunAsync method of stateful service, add the code that will process data in the queue. That call involve looping into queue and dequeue the records. Alternatively, that processing of data in queue can call a stateless service to actually run a long process. The stateful service is just a data store of incoming requests. – alltej Dec 26 '16 at 06:23
  • thanks @Jacky . please don't forget to upvote if you are satisfied with the answers. Thanks! – alltej Dec 27 '16 at 05:20
  • I upvoted but since I have less than 15 reps, it's recorded but not displayed. – TheSugoiBoi Dec 29 '16 at 16:51