akrsmv
akrsmv

Reputation: 830

Service Fabric - A web api in cluster who' only job is to serve data from reliable collection

I am new to Service Fabric and currently I am struggling to find out how to access data from reliable collection (That is defined, and initialized in a Statefull Service context) from a WEB API (that is, also living in the Service fabric cluster, as a separate application). The problem is very basic and I am sure I am missing something very obvious. So apologies to the community if this sounds lame.

I have a large XML, a portions of which I want to expose via a WEB API endpoints as results from various queries . Searched for similar questions, but couldn't find a suitable answer.

Would be happy to see how an experienced SF developer would do such task.

EDIT I posted the solution i have came up with

Upvotes: 1

Views: 488

Answers (2)

akrsmv
akrsmv

Reputation: 830

After reading around and observing others issues and Azure's samples, I have implemented a solution. Posting here the gotchas I had, hoping that will help other devs that are new to Azure Service fabric (Disclaimer: I am still a newbie in Service Fabric, so comments and suggestions are highly appreciated):

First, pretty simple - I ended up with a stateful service and a WEB Api Stateless service in an azure service fabric application:

  • DataStoreService - Stateful service that is reading the large XMLs and stores them into Reliable dictionary (happens in the RunAsync method).
  • Web Api provides an /api/query endpoint that filters out the Collection of XElements that is stored in the rteliable dictionary and serialize it back to the requestor

3 Gotchas

1) How to get your hands on the reliable dictionary data from the Stateless service, i.e how to get an instance of the Stateful service from Stateless one :

ServiceUriBuilder builder = new ServiceUriBuilder("DataStoreService");
IDataStoreService DataStoreServiceClient = ServiceProxy.Create<IDataStoreService>(builder.ToUri(), new ServicePartitionKey("Your.Partition.Name"));

Above code is already giving you the instance. I.e - you need to use a service proxy. For that purpose you need:

  • define an interface that your stateful service will implement, and use it when invoking the Create method of ServiceProxy (IDataStoreService)

  • Pass the correct Partition Key to Create method. This article gives very good intro on Azure Service Bus partiotions

2) Registering of Replica listeners - in order to avoid errors saying

The primary or stateless instance for the partition 'a67f7afa-3370-4e6f-ae7c-15188004bfa1' has invalid address, this means that right address from the replica/instance is not registered in the system

, you need to register replica listeners as stated in this post :

    public DataStoreService(StatefulServiceContext context)
        : base(context)
    {
        configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
    }

3) Service fabric name spacing and referencing services - the ServiceUriBuilder class I took from the service-fabric-dotnet-web-reference-app. Basically you need something to generate an Uri of the form:

new Uri("fabric:/" + this.ApplicationInstance + "/" + this.ServiceInstance);, where ServiceInstance is the name of the service you want to get instance of (DataStoreService in this case)

Upvotes: 3

Ryan Wike
Ryan Wike

Reputation: 141

You can use WebAPI with OWIN to setup a communication listener and expose data from your reliable collections. See Build a web front end for your app for info on how to set that up. Take a look at the WordCount sample in the Getting started sample apps, which feeds a bunch of random words into a stateful service and keeps a count of the words processed. Hope that helps.

Upvotes: 0

Related Questions