Sunday, February 26, 2017

Azure Search #2–Creating Search Service

 

Let’s see how we can create a azure search service and how we can manage and scale it.

Step 1: Select Search service from add new

Log in to Azure portal

Click New –> Web & Mobile

Under that select Azure Search .

1

Step 2: Give a name & select pricing tier

after selecting the Azure Search you will get the following blade.

enter the name you need to use for the search service.

2

then you have to select the pricing tier, by clicking on Pricing tier option in the blade.

3

when selecting pricing tier you need to identify your application requirements and select it. Anyway it is always better you start with a lower tier and scale it up when the application need varies. Azure provides you the facility of scaling up or down the tier based on you need. Then click create search service will be created for you.

Pricing Tiers

mainly contains 3 categories.

1.Free

multi-tenant shared service

2.Basic

provides dedicated computing resources for production workloads at a smaller scale

3.Standard

runs on dedicated machines, with more storage and processing capacity at every level, including the minimum configuration

each category will have sub categories as well with different level of resources. so you can choose it based on your application requirement.Under each category you might see this following terms.

1. Replicas

Instances of the search service, used primarily to load balance query operations. Each replica always hosts one copy of an index. If you have 12 replicas, you will have 12 copies of every index loaded on the service.

By adding more replicas you can get High availability of your search service. It is generally recommend that you start with one partition and one or two replicas, and then scale up as query volumes build.

General recommendations for high availability are:

  • Two replicas for high availability of read-only workloads (queries)
  • Three or more replicas for high availability of read/write workloads (queries plus indexing as individual documents are added, updated, or deleted)

2. partitions

A partition is a mechanism for splitting your data across extra resources. For this reason, when you add a second partition, your data gets split into two. A third partition splits your index into three.

 

Step 3: Scale Up your service

Go to your search service. There you will see Scale Up option. once you select it you will get the following blade. In that blade you can change the Replicas & Partitions for the search service

4

In my next post I will discuss what is azure index is. Until that…..

 

Happy Coding !!!!

Saturday, February 25, 2017

Azure Search #3 - Azure Search Index

 

When you want to have Azure Search integrated with your application data first thing you have to do is creating a Azure Search index under your search service. One Search service can contain multiple indexes.

An index is a persistent store of documents and other constructs used by an Azure Search service.

A document is a single unit searchable data in your index.

Index is like a table in SQL database. But there are some differences. When creating a index a given data field has set of attributes and a field type. Lets first look at what are the possible data types we can store in Azure search index.

 

Type Description
Edm.String

Text that can optionally be tokenized for full-text search

Collection(Edm.String)

A list of strings that can optionally be tokenized for full-text search

Edm.Boolean

Contains true/false values

Edm.Int32

32-bit integer values

Edm.Int64

64-bit integer values

Edm.Double

Double-precision numeric data

Edm.DateTimeOffset

Date time values represented in the OData V4 format

Edm.GeographyPoint

A point representing a geographic location on the globe

for more details about search index datatypes visit here

Next you have to define the attributes, which is used to describe the fields to the azure search service. following are the attributes included in a given data field. if value is not defined it is default set to false.

 

Attribute Description
Key

A string that provides the unique ID of each document, used for document look up. Every index must have one key. Only one field can be the key, and its type must be set to Edm.String.

Retrievable Specifies whether a field can be returned in a search result
Filterable Allows the field to be used in filter queries
Sortable Allows a query to sort search results using this field
Facetable Allows a field to be used in a faceted navigation structure for user self-directed filtering. Typically fields containing repetitive values that you can use to group multiple documents together (for example, multiple documents that fall under a single brand or service category) work best as facets
Searchable Marks the field as full-text searchable

 

for an example if you mark some data fields are “Searchable” true when you send a full text search request to the search service, search service will search that text in every field that you have marked “Searchable” and will send the search results for you.

So you can see how easy it is , If we had to make a search service we will have to write a query which will check match in every column which needs to search. but here what you need to do is just mark the field as “Searchable” and search service will do the rest for you.

There are 3 ways to create a Search service Index.

  1. Azure Portal
  2. .Net
  3. Rest API

I will describe then one by one with samples in next blog posts. Until then

Happy Coding !!

Sunday, August 7, 2016

Covert Image URL in to base64 string

Suppose you have your images hosted in azure blob storage. And you access the images using the URL. Else you have some images from another online location where you have only the URL.

I got a requirement recently on a project to generate a Vcard. For that I need the base64 string of the image, as all the data will be saved in to a text file. So I used the following code to first download the image them convert it to base64 string.

    public String GetImageData(String url)  
     {  
       StringBuilder _sb = new StringBuilder();  
       Byte[] _byte = GetImage(url);  
       //convert byte array in to base 64 string  
       _sb.Append(Convert.ToBase64String(_byte, 0, _byte.Length));  
       return _sb.ToString();  
     }  
     // Download image in to byte array  
     private byte[] GetImage(string url)  
     {  
       Stream stream = null;  
       byte[] buf;  
       try  
       {  
         WebProxy myProxy = new WebProxy();  
         HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);  
         HttpWebResponse response = (HttpWebResponse)req.GetResponse();  
         stream = response.GetResponseStream();  
         using (BinaryReader br = new BinaryReader(stream))  
         {  
           int len = (int)(response.ContentLength);  
           buf = br.ReadBytes(len);  
           br.Close();  
         }  
         stream.Close();  
         response.Close();  
       }  
       catch (Exception exp)  
       {  
         buf = null;  
       }  
       return (buf);  
     }  
     private int? GetCardId(string slug)  
     {  
       string[] slugElements = slug.Split('_');  
       try  
       {  
         return Convert.ToInt32(slugElements.Last());  
       }  
       catch (Exception ex)  
       {  
         return null;  
       }  
     }  

Hope this helps.

Happy Coding !!!

Saturday, July 30, 2016

Azure Push Notification with Web API


Before explaining how to to push notification to hub using Web API, let us see what is azure push notifications hub provides.
Azure Notification Hubs provide an easy-to-use, multiplatform, scaled-out push infrastructure that enables you to send mobile push notifications from any backend (in the cloud or on-premises) to any mobile platform.
With Notification Hubs you can easily send cross-platform, personalized push notifications, abstracting the details of the different platform notification systems (PNS). With a single API call, you can target individual users or entire audience segments containing millions of users, across all their devices.
Step 1 : Create Push Notification Hub
  1. Log on to the Azure Portal, and then click +NEW at the top left of the screen.
  2. Click on New, then Web + Mobile. Scroll down if necessary and click Notification Hub.
  3. Add All the details and create the hub
  4. image
Step 2 : Add Keys
After creating the hub next you need to add keys for each mobile platform you support. Creating keys for each platform are described here
IOS
After you have created the keys, go
Notification Hub –> Settings->Notification Services_> Select the platform you want to add the key then save. Now your hub is ready to send send receive notifications
image
Step 3 : Register with notification Hub
Now we can write the Web API call which allows mobile app to call and register with the hub.
Push notifications are sent to tags. When registering mobile device need to send the device token and tags they want to register.
Ex:- Suppose you push notification related to specific user to inform some action. Then we should have a tag with user name.
Create a class which will be used as the request for the API Call

   public class NotificationRegistration  
   {  
     public string Platform { get; set; }  
     public string DeviceToken { get; set; }  
     public string[] Tags { get; set; }  
   }  


Then Create a class which handles push notifications of your application and add Nuget and  the following using statement
using Microsoft.Azure.NotificationHubs;
 
After that you need to create hub connection string. You can copy it from azure portal.
Go to Hub –> Settings –> Access Policies 
 
  public class PushNotificationService  
   {  
     static string connectionString = ConfigurationManager.AppSettings["HubConnectionString"];  
    static string name = ConfigurationManager.AppSettings["Hubname"];  
     private NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(connectionString, name);  
     public PushNotificationService()  
     {  
     }  
     public async Task<HttpResponseMessage> Regsiter(NotificationRegistration notificationRegistration)  
     {  
       string registrationId =await GetRegistrationId(notificationRegistration.DeviceToken);  
       return await RegiterForTags(registrationId, notificationRegistration);  
     }  
     private async Task<HttpResponseMessage> RegiterForTags(string registrationId, NotificationRegistration notificationRegistration)  
     {  
       RegistrationDescription registration = null;  
       switch (notificationRegistration.Platform)  
       {  
         case "apns":  
           registration = new AppleRegistrationDescription(notificationRegistration.DeviceToken);  
           break;  
         case "gcm":  
           registration = new GcmRegistrationDescription(notificationRegistration.DeviceToken);  
           break;  
       }  
       registration.RegistrationId = registrationId;  
       registration.Tags = new HashSet<string>(notificationRegistration.Tags);  
       try  
       {  
         await hub.CreateOrUpdateRegistrationAsync(registration);  
       }  
       catch (MessagingException e)  
       {  
         ReturnGoneIfHubResponseIsGone(e);  
       }  
       return new HttpResponseMessage(HttpStatusCode.OK);  
     }  
     private static void ReturnGoneIfHubResponseIsGone(MessagingException e)  
     {  
       var webex = e.InnerException as WebException;  
       if (webex.Status == WebExceptionStatus.ProtocolError)  
       {  
         var response = (HttpWebResponse)webex.Response;  
         if (response.StatusCode == HttpStatusCode.Gone)  
           throw new HttpRequestException(HttpStatusCode.Gone.ToString());  
       }  
     }  
     private async Task<string> GetRegistrationId(string userName)  
     {  
       string newRegistrationId = null;  
       if (userName != null)  
       {  
         var registrations = await hub.GetRegistrationsByChannelAsync(userName, 100);  
         foreach (RegistrationDescription registration in registrations)  
         {  
           if (newRegistrationId == null)  
           {  
             newRegistrationId = registration.RegistrationId;  
           }  
           else  
           {  
             await hub.DeleteRegistrationAsync(registration);  
           }  
         }  
       }  
       if (newRegistrationId == null)  
         newRegistrationId = await hub.CreateRegistrationIdAsync();  
       return newRegistrationId;  
     }  
 }  


Then Create a web api call so your mobile application can make a request and register for the push notifications for each device

    [HttpPost]  
     public async Task<HttpResponseMessage> Regsiter(NotificationRegistration notificationRegistration)  
     {  
       return await new PushNotificationService().Regsiter(notificationRegistration);  
     }  


Step 4 : Deregister with notification Hub
Sometimes users turn off receiving push notifications also it is a practice we don’t send push notifications to the user it that user is logged out from our app from the given device. In such scenarios we have deregister from the notifications. As a practice regiter is called when user logs in and deregister is called when log out. These will fully depend on your application requirements.
 
For that create a method in PushNotificationSerice.cs for deregistrations
 
    public async Task<HttpResponseMessage> DeRegister(string deviceToken)  
     {  
       string registrationId = await GetRegistrationId(deviceToken);  
       if (registrationId == null)  
       {  
         return new HttpResponseMessage(HttpStatusCode.NotAcceptable);  
       }  
       await hub.DeleteRegistrationAsync(registrationId);  
       return new HttpResponseMessage(HttpStatusCode.OK);  
     }  
 
Then create a web API call for deregiter
 
  [HttpGet]  
     public async Task<HttpResponseMessage> DeRegister(string deviceToken)  
     {  
       return await new PushNotificationService().DeRegister(deviceToken);  
     }  
Step 5: Send Notification
Now your application is ready to send push notifications using azure push notification hub. You can use following code to send notifications
  public async Task<bool> SendNotification(SendNotificationRequest sendNotificationRequest)  
     {  
       string[] userTag = new string[1];  
       userTag[0] = sendNotificationRequest.Tag;  
       NotificationOutcome outcome = null;  
       //IOS  
       var alert = "{\"aps\":{\"alert\":\"" + sendNotificationRequest.Message + "\",\"content-available\":1,\"sound\":\"default\"}}";  
       outcome = await hub.SendAppleNativeNotificationAsync(alert, userTag);  
       // Android  
       var notif = "{ \"data\" : {\"message\":\"" + sendNotificationRequest.Message + "\"}}";  
       outcome = await hub.SendGcmNativeNotificationAsync(notif, userTag);  
       if (outcome != null)  
       {  
         if (!((outcome.State == NotificationOutcomeState.Abandoned) ||  
           (outcome.State == NotificationOutcomeState.Unknown)))  
         {  
           _notificationRepository.Create(new Domain.Entities.Notification  
           {  
             UserId = sendNotificationRequest.UserId,  
             Description = sendNotificationRequest.Message,  
             IconUrl = sendNotificationRequest.IconUrl  
           });  
           return true;  
         }  
       }  
       return false;  
     }  

Hope this helps

Happy Coding !!

Sunday, June 5, 2016

Azure Search #1

 

I will be writing a series of post on azure search step by step. Each post I will be explaining different areas in azure search.

As this is the first post I will be explaining what azure search is and what are the applications of azure search.

What is Azure Search ?

A search-as-a-service solution allowing developers to incorporate great search experiences into applications without managing infrastructure or needing to become search experts.

If I elaborate the definition bit more,Azure search provides lot of services, which allows developer to add high search experience to their end users, without been a search expert. In other words developer has to call some API calls to azure search all the search algorithms will be executed by azure search service and result will be returned. this makes developer life easier and giving end user a high search experience.

Why we need search?

Search box in an application has been the main entry point of most of the applications. If we unable to provide good search results it tends users to leave our application.

Ex:- If users makes a typo on searching an item in a shopping cart and if no results came, user might think this cart doesn't have the tem he searched for, user might leave and go and try on another shopping cart. To avoid such situations we need to have a search service which detects users type and send the search results with best match.

What are the Search Options?

Before we jump in to azure search first we will see what are the search capabilities we need to provide for our end users. Following are some examples of an shopping cart.

1. Type Ahead

When user comes and type in the search box, we should be provide them some type heads with suggestions so user can click on them and complete search without typing the whole search text.

image

2. Facets

Facets are filters given to users to filter out the search results based on different criteria's.

image

3. Hit Highlighting

On the search results the search text which user has entered should be highlighted in search item title or description so user can see the relevance of the search items.

image

4. Spelling Mistakes

As you can see when searching “mountain” user has made a typo and entered “Mountan” still the user is getting search results which best match

image

5. Geo-Spatial Search

In case user wants to search items near his location, then geo- spatial search is needed to be added to the application

image

6. Paging

image

7. Sorting & Scoring

User should be able to sort the results on different options. Also Best Match sorting should be also available.

Ex:- if the search text is found in product title should come top of the results than the products which contains the search text in the product description. For that search results should contain a score best on the relevance to the search text.

image

Azure Search service provides services to add these capabilities in your search using minimum code and time.

When We should Use it?

Basically Microsoft pointed 3 main areas where this search service could add real value. It does not mean this can be used only in these areas, it could be used in many areas other than this.

1. E-Commerce Application.

2. User Generated Content Applications Ex:- Recipe sites

3. Business Application

Hope you had a basic understanding of what azure search provides as a service and why and when we should use it. In my next article I will be discussing concepts behind azure search then how to enable your data to be searched by azure search.

 

Hope this helps

Thursday, April 7, 2016

Saving Base64 String as image to Azure Blob Storage

 

Recently I started working on a API which supports mobile backend. I got the following requirement

1. When user uploads a image to their profile API will get the base64 string of the image

2. When viewing the User profile to increase the performance of service calls have to send an image URL rather base64 string

 

Solution : Save the base 64 string in the azure storage & save it in DB

  
  public class AzureBlogService
    {
        private static string _connectionString = "DefaultEndpointsProtocol=https;AccountName=****;AccountKey=****";
        public static string UploadImage(string imageData, ImageType imageType, int cardId)
        {
            string filename = GetFileName(imageType, cardId);
            CloudBlobContainer container = GetContainer("userimages");
            byte[] imageBytes = Convert.FromBase64String(imageData);
            CloudBlockBlob blob = container.GetBlockBlobReference(filename);
            blob.Properties.ContentType = "Jpeg";
            blob.UploadFromByteArray(imageBytes, 0, imageBytes.Length);
            return blob.StorageUri.PrimaryUri.AbsoluteUri;
        }

        private static CloudStorageAccount GetConnection()
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_connectionString);
            return storageAccount;
        }

        private static string GetFileName(ImageType imageType, int cardId)
        {
            switch (imageType)
            {
                case ImageType.Cover:
                    return string.Format("Cover-{0}.jpeg", cardId);
                case ImageType.Profile:
                    return string.Format("Profile-{0}.jpeg", cardId);
                default:
                    return null;
            }


        }
        private static CloudBlobContainer GetContainer(string containerName)
        {
            CloudStorageAccount storageAccount = GetConnection();
            // Create the blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve a reference to a container.
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);

            // Create the container if it doesn't already exist.
            container.CreateIfNotExists();

            return container;
        }


    }

Hope this is helpful.

Happy Coding !!!

Wednesday, April 6, 2016

Group By First Letter of word with Linq

 

This is sample code which you can used to group some list of objects based on first letter of the object name or any string property.

In the following example I get list of contacts in an application and after getting those from DB , I group them with the First letter of the Contact name and order them in alphabetical order.

Following is my Contact Class.

  
 public class CardContactModel
    {
        public int CardId { get; set; }
        public string CardName { get; set; }
        public int? ContactId { get; set; }
        public JObject Information { get; set; }
        public string ProfileImage { get; set; }
        public string SharedTo { get; set; }
        public string RecievedFrom { get; set; }

    }

Then I group it and add it to a dictionary with the following line of code.

  
Dictionary> Contacts  = contacts.GroupBy(x => x.CardName.Substring(0, 1).ToUpper(), (Letter, Contacts) => new { Alphabet = Letter, SubList = Contacts.OrderBy(x => x.CardName).ToList() })
                .OrderBy(x => x.Alphabet).ToDictionary(x => x.Alphabet, x => x.SubList);
            return searchContactsResponse;

Hope this is helpful.

 

Happy Coding !!!