Service Fabric Actor app ready in just 4 hours

This is a continuation of the previous blog where I played with Statefuc KVS service. This time I thought to play around with Service Fabric actor services.

8:00 pm : After fooling around with friends for quiet some time, :) I finally sat down on my couch with my laptop, thinking of what new I can learn. As it was Friday I was not bothered by any official mails, so I went to http://azure.microsoft.com. After recent build sessions the document section was filled with all the exciting things Microsoft was doing. I thought to continue the story of Service Fabric http://azure.microsoft.com/en-us/documentation/services/service-fabric/ and get some hands-on experience with Service Fabric Actor Model.

8:30 pm: After going through initial documentation, I cannot hold my nerves and created a new Stateful Fabric Actor MicroService. Please Note: you need to download the 2015 RC VSTS in order to avail Service Fabric. After goin throug initial Fabric Actor introduction I started geting my hands dirty.

9:00pm - 12:00 am: During this duration I went through many references from Reliable Actor documentation. My scenario was to get Facebook events corresponding to a particular keyword. For ex: If I search for microsoft , it should tell me all the facebook events for Microsoft in recent past as well as upcoming

9:00pm - 10:00pm: Following the basic steps I went through the doc published at http://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-actors-get-started/

This document gives an idea how the fabact registers itself to the cluster. From a user point of view this document talks about the entry point to the user logic.

Following code snippet is from the Service Project which is in my case SocialAnalyzer.cs

We are using the stateful Actor for our experiment

 public class SocialAnalyzer : Actor<SocialAnalyzerState>, ISocialAnalyzer
{
}

Here the state is mantained in SocialAnalyzerState class.

 public Task<List<FacebookMessage>> GetFacebookMessages(List<string> searchTerms)
        {
            ActorEventSource.Current.ActorMessage(this, "Getting Facebook Messages for {0}", searchTerms);
            FacebookCrawler crawler = new FacebookCrawler();
            if(this.State.SearchTerms == null)
            {
                this.State.SearchTerms = new List<string>();
            }
            
            foreach(var term in searchTerms)
            {
                if(!this.State.SearchTerms.Contains(term))
                {
                    this.State.SearchTerms.AddRange(searchTerms);
                    this.State.FbMessages.AddRange(crawler.GetMessages(term));
                }                
            }
            
            return Task.FromResult(this.State.FbMessages);

        }

Why I am using a Stateful Actor is shown in here. I don't want to search for the same query if it is already searched by someone. For ex: if Person A searches for "Microsoft" the response should get stored in Actor's State. Now if Person B searches for Microsoft, without calling the facebook graph API we can just fetch the results for Actor's state.

Above code snippet helps me fetch FB message response and store it in Actor State.

Here is the SocialAnalyzerState definition. As mentioned in the doc

[DataContract]
    public class SocialAnalyzerState
    {
        public SocialAnalyzerState()
        {
            this.FbMessages = new List<FacebookMessage>();
        }

        [DataMember]
        public int Count;

        [DataMember]
        public List<FacebookMessage> FbMessages { get; set; }

        [DataMember]
        public List<string> SearchTerms { get; set; }

        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "SocialAnalyzerState[Count = {0}]", Count);
        }
    }

Beleive me this is the only thing I had to do from Service Fabric communication point of view. Else remaining was my own logic.

10:00 pm - 11:00 pm: Till now I was enjoying the script kiddie experience. My intent was how quickly I can create an app on service fabric actor model and try to fulfil one of my need. As most of the code was already done for me, I didnot need to go through the docs line by line, instead see something in action. So without much ado I started writing my client which will help me to test and debug.

In my client I wanted to show the name of the event, Location and Date of event

 public static void Main(string[] args)
        {
            var searchQuery = new List<string>();
            var proxy = ActorProxy.Create<ISocialAnalyzer>(ActorId.NewId(), "fabric:/SocialAnalyzerApplication");

            if(args != null)
            {
                foreach(var item in args)
                {
                    searchQuery.Add(item);
                }                
            }
            else
            {
                searchQuery.Add("Microsoft");
            }

            var facebookMessages = proxy.GetFacebookMessages(searchQuery).Result;
            foreach(var message in facebookMessages)
            {
                Console.WriteLine("Name: " + message.Name);
                Console.WriteLine("Location: " + message.Location);
                Console.WriteLine("Date: " + message.Start_Time);
                Console.WriteLine("");
            }            
        }        

My intent was that user will keep adding arguments to the exe call to fetch the corresponding results.

11:00pm-12:00am:  Now my final piece of cake, which always excites me is social networking apis. I figured out that the facebook graph api knowledge I had was now obsolete, that proves that I didnot update myself from long time. The current graph api was 2.3 and they optimized some of the query syntax in this version.

In order to store the Facebook Messages in my state I had to take help of a class FacebookMessage


    public  class FacebookMessage
    {
        public string Name { get; set; }

        public string Start_Time { get; set; }

        public string Location { get; set; }

        public string ID { get; set; }

    }

Above schema fulfils all my requirements which I need to fetch the details of an event. Creating and app in facebook and getting accesstoken in graphapi has already been discussed in my previous blog. After getting an access token, search api can be performed by the following snippet. This helped in getting the list of FaceBook Messages related to events. We can perform User, Place and other types of searching too with few modification in the graph api call.

 public List<FacebookMessage> GetMessages(string query)
        {
            var facebookMessages = new List<FacebookMessage>();

            //TODO remove this to configuration xml
            var accessToken = "<<accesstoken>>";

            string getFacebookMessage = "https://graph.facebook.com/v2.3/search?q='" + query + "'&type=event&access_token=" + accessToken;

            using (HttpClient facebookClient = new HttpClient())
            using (HttpResponseMessage facebookResponse = facebookClient.GetAsync(getFacebookMessage).Result)
            {
                facebookResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                facebookResponse.EnsureSuccessStatusCode();
                string responseBody = facebookResponse.Content.ReadAsStringAsync().Result;

                
                //Add the value to key value store
                JObject json = JObject.Parse(responseBody);
                JArray array = (JArray)json["data"];
                
                foreach (var item in array)
                {
                    if (item["id"] != null)
                    {
                        var fbMsg = new FacebookMessage();
                        fbMsg.ID = item["id"].ToString();
                        fbMsg.Name = item["name"].ToString();

                        fbMsg.Start_Time = item["start_time"] != null ?item["start_time"].ToString() : string.Empty;
                        fbMsg.Location = item["location"] != null ? item["location"].ToString() : string.Empty;

                        facebookMessages.Add(fbMsg);
                    }
                }

                return facebookMessages;
            }

        }

At the stroke of midnight, I celebrated my 4 hour journey with these output



This might be a simple app, but it indeed gives a maker the confidence of creating a highly scalable distributed stateful app, which was not so simple few days ago.

I wonder what other stories can we unveil with this framework. Will keep exploring and will get back with some more experience next time.

Comments

  1. Where did you took FacebookCrawler Class? which referrence you are added to project? please help me..

    ReplyDelete
  2. FacebookCrawler is a custom class which I added which is invoking getMessages function documented in the blog

    ReplyDelete
  3. Where is the Source code of this project?

    ReplyDelete
  4. Pardon me, I am not able to understand what do you mean by source code. All snippets of code has been copied in this blog post. It will be great if you can mention what exactly are you looking for? As far as FacebookCrawler is concerned I already mentioned that this is a custom class and the getMessages function is documented in the blog post. What else do you need regarding this?

    ReplyDelete

Post a Comment

Popular posts from this blog

Firebase authentication with Ionic creator

Big Data - SWOT Analysis

LINKEDIN api call using NODE.JS OAUTH module