Sharing this wonderful article created by Steve Marx, one of the guys working on Windows Azure Platform.

 

http://blog.smarx.com/posts/what-is-windows-azure-a-hand-drawn-video

Posted by Max Bautista | with no comments

Today, during the Microsoft Worldwide Partner Conference 2009 we announced the business and partner model for the Windows Azure platform including service level agreements and support programs.

Windows Azure, SQL Azure and .NET Services will be commercially available at the Professional Developer Conference 2009 and we hope you will continue building on the Community Technology Preview (CTP) at no cost today.

Upon commercial availability we will offer Windows Azure through a consumption-based pricing model, allowing partners and customers to pay only for the services that they consume.

Windows Azure:

* Compute @  $0.12 / hour                     

* Storage @ $0.15 / GB / month stored

* Storage Transactions @ $0.01 / 10K

 

SQL Azure:

* Web Edition – Up to 1 GB relational database @ $9.99

* Business Edition – Up to 10 GB relational database @ $99.99 

 

.NET Services:

* Messages @ $0.15/100K message operations , including Service Bus messages and Access Control tokens

 

Bandwidth across all three services will be charged at $0.10 in / $0.15 out / GB

Windows Azure compute hours are charged only for when your application is deployed so while developing and testing your application you may want to remove the compute instances that are not being used to minimize compute hour billing. Windows Azure storage is metered in units of average daily amount of data stored (in GB) over a monthly period. Storage is also metered in terms of storage transactions used to add, update, read and delete storage data. These are billed at a rate of $0.01 for 10,000 (10k) transaction requests. Bandwidth is charged based on the total amount of data going in and out of the Windows Azure platform services via the internet in a given 30-day period.

While consumption based pricing provides great flexibility we have also heard it introduces a level of unpredictability and some customers prefer other options. At launch we will share details of subscription offers that provide payment predictability and price discounts that reflect levels of usage commitment.

To support partners’ and customers’ complex business needs we are providing an enterprise-class guarantee backed by a service-level agreement that covers service uptime, connectivity, and data availability. For compute, we guarantee that when you deploy two or more role instances in different fault and upgrade domains your Internet facing roles will have external connectivity at least 99.95% of the time. Additionally, we will monitor all of your individual role instances and detect within two minutes when a role instance’s process is not running and initiate corrective action. For storage, we guarantee that at least 99.9% of the time we will successfully process correctly formatted requests that we receive to add, update, read and delete data. We also guarantee that your storage accounts will have connectivity to our Internet gateway.

As part of the Microsoft Partner Network, partners receive an additional 5 percent promotional discount on Windows Azure compute, SQL Azure and .NET Services. As an added benefit of MSDN Premium we also announced we will provide subscribers with resources to build, test, and manage full scale cloud based applications. We will also provide the Development Accelerator promotional offer for partners and customers who want to quickly develop and deploy applications with dynamic scaling, predictable pricing, and a deep discount.

At launch we will have offers available in local currencies for Australia, Austria, Belgium, Canada, Denmark, Finland, France, Germany, Ireland, India, Italy, Japan, Netherlands, New Zealand, Norway, Portugal, Spain, Sweden, Switzerland, UK, and the United States. In the March 2010 timeframe we expect commercial availability to expand to Brazil, Chile, Colombia, Czech Republic, Greece, Hong Kong, Hungary, Israel, South Korea, Malaysia, Mexico, Poland, Puerto Rico, Romania, Singapore, and Taiwan. Additional countries and currencies will be launched as quickly as possible.

 

Source : Azure Blogs

Posted by Max Bautista | with no comments

Last May, Microsoft launched a developer competition tagged as new CloudApp(), a US based developer challenge.  Its focus is to promote applications running on the Azure Services Platform.  The contest had three categories of winners for applications running on theAzure Services Platform:

  • best .NET application,
  • top PHP application, and,
  • community winner

The winners got to have the following:

  • Be featured on www.azure.com as well as at major Microsoft events
  • Be featured in a video interview on Channel 9 with the application author
  • Winners will be announced at Structure 09
  • Receive cash ($):
    • .NET Applications Category winner: $5,000 Visa gift card
    • PHP Applications Category winner: $5,000 Visa gift card
    • Community winner: $2,500 Visa gift card

This contest could sure be fun to have in the Philippines, if Microsoft plans to have this new emerging platform to get full support and have adapters to get into the technology.. They could have some sort of competition like this in the Philippines.

 

By the way, it should have been announced earlier to us but they are also sponsoring the International competition for new CloudApp() lets just wait for the results who made it to the finals.

Posted by Max Bautista | with no comments

First, Congratulations to the winner of the recently held Best of the Best Developer Showdown sponsored by Microsoft and Smart Communications, the winning team was Triumvirate.  Check the details of the project below, it was created in Flash and asp.net. :D


Projects: P.E.T.S. (Pets Enthusiasts Tourney Smash!)
The project is about having a digital community wherein users can nurture their own digital pets and use them to interact with other users within the network by means of battling, pet interactions, sharing, buying and trading of items. Interactions will be done through mobile phones and an online widget to greatly improve users’ experience.

         1. Ricardo Monteverde
         2. Marc Phennee San Diego

------------------------


It has been a while that I didn't update my blog here due to a lot of things that I need to do at work and add to that, we just joined that showdown... though we didn't win, we got he People's choice award. :D (Thanks for the new phones).  Since this is a blog about Azure, might as well discuss the entry we had.  The system was created gearing towards using the latest Microsoft technologies (Azure and Silverlight, plus Windows Mobile 6 support).  It might help other guys who would be developing on it.


Our system, though it was not well described in this site is a system that would enable users to update all their Social Networking sites account Status or Upload Images using SMS/MMS Technologies (Of course we just did a work around for it since Smart doesn't have open API for their SMS and MMS).  That is basically, send once, upload/update to all. Thus supporting all possible mobile users (Even not smart / talk n text users, hehehehe).

Technical, it could be nice to share the issues/learnings we encountered to the community and share the solutions we did.

Item #1 Uploading Images to Windows Azure storage direct image upload is not possible since it is not giving you the client path. (Courtesy of Ogie Chu)

Solution:  You need to use the Filebytes property of a fileupload control and save the bytes in the Azure storage then when you try to retrieve it, you just need to convert the bytes to bitmap. :)


Item #2 Secured Wifi Router (authenticating using web session) is disrupting the connectivity of a windows mobile emulator to different WCF Services / Web Services.

Solution:  Fix the connection of the WM Emulator to connect to the right segment of IP Addresses. :D You could check some blogs fixing this, might update this soon.


Item #3 Silverlight connectivity to Azure is good. :D

Reason: Silverlight could directly interact with the tables in azure since azure tables doens't have relationships and it is running on client side. For security reasons, this is the best option rather than using flash. :)

Item # 4 No internet connection for 5 hours (SMX Admin shut it down, not well coordinated)

Solution: Go down, Smoke, and create a video of your team.  Listen to the organizers singing. Talk to other people, and make friends.  Lastly, SMILE... *wink* *wink*

It was a fun (in a way) experience for us, though we only got the People's Choice award, it strengthened our team's use of the latest Microsoft Technologies. Since competions like this aims to utilized latest technologies, like harnessing what Microsoft Showcased during the Web Ramp Up Event last March.


Posting an article I saw that sounds interesting for us Azure developers.

At MIX 09, we are announcing that we’ll be launching a set of ‘geo’-related features. We’ll be rolling out the features to all our users very soon. In Microsoft-speak, we are ‘super-excited’ about this since we can finally unveil in public what we’ve been working on for the past several months.  Before I talk about what exactly we are releasing, I wanted to explain *why* we’re doing this.

Why are we doing this?

  • Performance — We heard loud and clear that our users wanted to have more choice on where the data is placed so that they could get it as close to their end users as possible and reduce network latency. We also saw how important it was for us to ensure that code and data are as close together as possible (more on that later).
  • Legal/regulatory reasons — Several users had requirements on where they can place their code and data and where they cannot.
  • Business continuity/backup — Users wanted locations geographically spread. You can now make copies of your data across locations so in case of a natural disaster or if the Cloverfield monster came and stomped on one of our datacenters, your data would be safe

What are we announcing ?

We are announcing a few major things.

  • First, we are now present in two geographic locations rather than one. Previously, we had a presence only in north western United States and we now have a presence in the south. Going forward, we plan on expanding our presence to more locations, especially outside the U.S
  • Users will have the ability to pick where they want to host their sevices and/or their data between these two geo locations (and more in the future). For example, when you create a storage account, you can choose where to host it based on your business needs and the storage systems will do some magic behind the covers to route requests to your data. The same holds true for creating a hosted service account and running code. Both geo-locations support all features of Windows Azure. If you don’t have specific requirements on where you want your code/data, you can choose ‘US- Any’ and we’ll pick a location for you.
  • User can create ‘affinity groups’ to put their storage account and/or hosted services in. This goes to what I said about putting code and data as close to each other as possible. Accounts inside an affinity group will be dealt with as one unit and placed together for connectivity. For example, if you create an affinity group placed in North Western United States and place multiple storage accounts and hosted services in there, we’ll allocate these together in that geographical region, so that all of the accounts will be close together from a network perspective

We plan on expanding our presence to more than just two geo-locations. We’d love to hear your feedback on what we’re shipping and what you would like to see. You can leave a comment or contact us through the link on the side. We are pretty excited about what we are shipping. Please do try our features out once we’ve finished rolling them out and tell us what you think!

Sriram Krishnan
Program Manager

 

[This document supports a preliminary release of a software product that may be changed substantially prior to final commercial release. This document is provided for informational purposes only.]

SQL Data Services (SDS) is the relational database offering for the Azure Services Platform. SDS exposes these relational capabilities through the existing network protocol, Tabular Data Stream (TDS). TDS is the underlying protocol used by all SQL Server client libraries such as ADO.NET, ODBC and all other third party and open source access libraries.

The use of the existing protocol enables the service to extend the SQL data platform to the cloud while maintaining symmetry with the existing SQL Server applications models.

SDS offers friction-free provisioning allowing customers to create databases without having to worry about hardware and software procurement, setup or maintenance. SDS also ensures high availability and fault tolerance. The pay as you grow model provides unlimited scale at low cost.

TDS access to the database services allows customer applications to communicate with the service using existing client libraries (such as ADO.NET, ODBC or JDBC).

Customers can optionally host their applications in Azure Compute as shown in the following illustration.

Dd557595.10d9383b-952f-4436-94ac-185f89463eaa(en-us,MSDN.10).gif

The exposure of the TDS protocol provides a programming model in the cloud that is similar to the on-premise database programming experience. Customers can easily migrate their applications from on-premises databases into the cloud as the SQL surface area is largely unchanged.

The database service exposes the strength of SQL Server, the power of Transact-SQL and related richness of the existing SQL tools to customers. Application developers can leverage their existing knowledge when working with the service.

The Azure hosting services complement SDS allowing applications to be hosted close to the database where the application data is stored thereby reducing the overall cost of communicating with the service while at the same time providing lower operational expenses.

Dd557595.c1b8733b-6545-438a-9065-e4a43763691c(en-us,MSDN.10).gif

As shown in the high level architecture diagram, TDS access to the database services allows customer applications to communicate with the service using existing client libraries (such as ADO.NET, ODBC or JDBC). SQL Data Services provides:

  • Provisioning service for on boarding new customers within the Azure platform.
  • Billing, metering and rollup functionality for users to discover service usage information. This metrics information is also used for customer billing.
  • Concepts of Server and User Database which provides context for the management of the databases in the cloud. SDS maps these logical concepts to the underlying platform.

The relational model described in this topic replaces the SDS ACE (Authority, Container and Entity) model. The current SDS CTP participants have the following options:

  • Migrate existing applications to use the SDS relational service. Customers can optionally host their applications in Azure Compute.
  • Use Windows Azure Storage for applications that don’t need relational capabilities

The SDS ACE model, with SOAP and REST interfaces, is being phased out.

Posted by Max Bautista | with no comments

I would like to share just a blog I saw regarding the changes Microsoft is implementing on SQL Data Services...

The no spin details on the new SDS features

Today we announced the details of our plans to accelerate the delivery of core relational database features as part of SDS.  There has been quite a bit of buzz about SDS over the past couple weeks and it is great to be able to share the details more broadly.

If we flash back about a year ago to Mix 08, Nigel Ellis got up on stage to introduce the community to SDS which, at the time, was a flexible entity based cloud database that you accessed using standard internet protocols. We made this announcement with the promise that more relational capabilities would be coming - and they did. But the universal feedback we received from our TAP partners and other early adopters was the need for a relational database delivered as a service. This was extremely valuable feedback and drove us to more aggressively investigate ways in which we could deliver these features. As a result of that work and based on the progress we’ve since made in the product team, we are announcing that SDS will deliver full relational database capabilities as a service.

While we knew we needed to accelerate our plans we also knew we needed to hold true to some on the founding principles we had when we started our journey. Things like High Availability, Fault Tolerance, Friction Free Provisioning, Pay As You Grow Scaling, Immediate Consistency. We are still delivering on these promises and have added to the mix true relational capabilities, T-SQL and compatibility with the existing developer and management tools ecosystem.

What does this mean for developers? Developers will be able to very easily provision themselves a logical server and database and begin developing against it immediately using the existing tools and technologies that they are accustomed to. We are providing an experience where a developer can take an existing application and just change the connection string to point it to the cloud and have it just work.

How will we do it? Three letters TDS. TDS stands for Tabular Data Stream and it's the published protocol that clients use to communicate with SQL Server. From its inception, SDS has always been built on the SQL Server technology foundation and it just made sense to allow our users to access their data via TDS. Most importantly for developers, this means symmetric SQL Server functionality and behavior combined with compatibility with the existing tools you are familiar with.

                Tables?...Check

                Stored Procedures?...Check

                Triggers?...Check

                Views?...Check

                Indexes?...Check

                Visual Studio Compatibility?...Check

                ADO.Net Compatibility?...Check

                ODBC Compatibility?...Check

To be clear, the above is not a complete list of supported features.  However, given the feature set we are planning to support in SDS v1, a majority of database applications will “just work”, allowing developers to target on and off-premises deployments with essentially the same code base.  The initial scenarios we are targeting are things like web and departmental applications. We will be posting some content to our MSDN Dev Center in the coming weeks with specifics and getting started guidance but I encourage everyone to download SQL Express and the Windows Azure SDK to get started.

The core foundational components of SDS have not changed. This is still the same architecture that we have been telling you about for the past year and that underlies the current CTP bits. It is the same architecture that is powering some of Microsoft's key service properties and in the next few months will be used to store 100’s of terabytes of data in production deployments. Our early adopters (both internal and external) have shaken it down pretty well and we feel very confident about these bits.  The only difference is we are now providing a rich SQL model while maintaining the high availability, fault tolerant and scale aspects of the system.

What about the ACE (Authority, Container, Entity) data model and developer experience? Since Windows Azure storage has a similar data model (property bag) and developer experience, we will stop supporting the current ACE Model sometime in the future. Does this mean you can't access your relational data via internet friendly protocols like REST?  Not at all. You can still access your relational data (located on premises or in the cloud) via HTTP/REST using the ADO.Net Data Services framework. The compatibility with existing tools and technologies is a really important point to drive home and a super important value add that Microsoft provides.

Breadth and OSS developer support will continue to be a high priority for us and we will continue to support and provide breadth development libraries for all mainstream development technologies including PHP, Ruby and Java.  If it works with SQL Server, it will largely work with SQL Data Services.

What about Security? All communications with our service is SSL encrypted and our initial authentication will be using SQL Authentication.

Of course, SQL Data Services remains one of the key developer services of the Azure Services Platform - that hasn't changed. Consuming SDS from within an Azure application has never been easier and we will continue to ensure this is a feature rich, friction-free experience.

I have said a lot, so go ahead and digest all of this. What else do you want to know? As I am sure you all have more questions, feel free to email me at david.robinson@microsoft.com and I'll post the questions and answers for all to see.


Kudos to SQL Data Services Team for the information on the blog.  Refer to this link.

Posted by Max Bautista | with no comments

Console Application

The “Console Application 1” is the simple console program created to simulate the calls for each services. It has 5 .cs files.  Additional project references: DataHelper, Model, TesterREST, TesterWCF and TesterWS.

Program.cs: this file is the main class for this program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace ConsoleApplication1
{
    public class Program
    {
        static List<long> addUserWSTime;
        static List<long> addUserWCFTime;
        static List<long> addUserRestTime;

        static List<long> getAllUsersWSTime;
        static List<long> getAllUsersWCFTime;
        static List<long> getAllUsersRestTime;

        static List<long> updateUserWSTime;
        static List<long> updateUserWCFTime;
        static List<long> updateUserRestTime;

        static List<long> deleteUserWSTime;
        static List<long> deleteUserWCFTime;
        static List<long> deleteUserRestTime;


        static int tryID;
        static int runNumber;

        [STAThread]
        static void Main(string[] args)
        {
            Stopwatch timerTotal = new Stopwatch();
            Console.WriteLine("WS , REST and WCF Service Test will now start...");
            Console.Write("Enter Try ID: ");
            tryID = Convert.ToInt32(Console.ReadKey(false).KeyChar.ToString());
            Console.WriteLine();
            Console.Write("Enter Number of Run: ");
            runNumber = Convert.ToInt32(Console.ReadLine().Trim());
            Console.WriteLine();
            Console.WriteLine("Press any key to start...");
            Console.ReadKey(true);

            timerTotal.Start();

            addUserRestTime = new List<long>();
            addUserWCFTime = new List<long>();
            addUserWSTime = new List<long>();

            getAllUsersRestTime = new List<long>();
            getAllUsersWCFTime = new List<long>();
            getAllUsersWSTime = new List<long>();

            updateUserRestTime = new List<long>();
            updateUserWCFTime = new List<long>();
            updateUserWSTime = new List<long>();

            deleteUserRestTime = new List<long>();
            deleteUserWCFTime = new List<long>();
            deleteUserWSTime = new List<long>();

            UserProfileBL _objProfileBL;

            int maxRunNumber = runNumber;
            string constFName="Auto Test FN ";
            string constLName="Auto Test LN ";

            for (int ctr = 1; ctr <= maxRunNumber; ctr++)
            {
                _objProfileBL = new UserProfileBL();
                string fName = string.Format("{0}{1}",constFName, ctr.ToString("000000"));
                string lName = string.Format("{0}{1}",constLName, ctr.ToString("000000"));
               
                TestAddUser(new Guid(), fName, lName);               
                TestGetAllUsers();
                TestUpdateUser(_objProfileBL.GetGuids(fName), fName, lName);
                _objProfileBL = null;               
            }

            for (int ctr = 1; ctr <= maxRunNumber; ctr++)
            {
                _objProfileBL = new UserProfileBL();
                string fName = string.Format("{0}{1}", constFName, ctr.ToString("000000"));
                string lName = string.Format("{0}{1}", constLName, ctr.ToString("000000"));

                Console.WriteLine(string.Format("Deleting : {0}", fName.ToString()));
                TestDeleteUser(_objProfileBL.GetGuids(fName));

                _objProfileBL = null;
            }

            timerTotal.Stop();
            Console.WriteLine(string.Format("Total Execution Time for Tests: {0} m {1} s {2} ms", timerTotal.Elapsed.Minutes, timerTotal.Elapsed.Seconds, timerTotal.Elapsed.Milliseconds));

            timerTotal = new Stopwatch();
            timerTotal.Start();
            GenerateReports();
            timerTotal.Stop();
            Console.WriteLine(string.Format("Total Report Creation Time:  {0} m {1} s {2} ms", timerTotal.Elapsed.Minutes, timerTotal.Elapsed.Seconds, timerTotal.Elapsed.Milliseconds));

            Console.WriteLine("Tests Finished...");
            Console.WriteLine(string.Format("Report Saved at {0}", "TestReports Table!"));
            Console.ReadKey();
        }

        static void GenerateReports()
        {
            ReportBL objBLReport = new ReportBL();

            //WS
            int runCtr=1;

            foreach (long l in addUserWSTime)
            {
                objBLReport.AddReport(runCtr, "WS", "AddUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in getAllUsersWSTime)
            {
                objBLReport.AddReport(runCtr, "WS", "GetAllUsers", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in updateUserWSTime)
            {
                objBLReport.AddReport(runCtr, "WS", "UpdateUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in deleteUserWSTime)
            {
                objBLReport.AddReport(runCtr, "WS", "DeleteUser", l, tryID);
                runCtr++;
            }

            //WCF
            runCtr = 1;

            foreach (long l in addUserWCFTime)
            {
                objBLReport.AddReport(runCtr, "WCF", "AddUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in getAllUsersWCFTime)
            {
                objBLReport.AddReport(runCtr, "WCF", "GetAllUsers", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in updateUserWCFTime)
            {
                objBLReport.AddReport(runCtr, "WCF", "UpdateUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in deleteUserWCFTime)
            {
                objBLReport.AddReport(runCtr, "WCF", "DeleteUser", l, tryID);
                runCtr++;
            }

            //REST
            runCtr = 1;

            foreach (long l in addUserRestTime)
            {
                objBLReport.AddReport(runCtr, "REST", "AddUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in getAllUsersRestTime)
            {
                objBLReport.AddReport(runCtr, "REST", "GetAllUsers", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in updateUserRestTime)
            {
                objBLReport.AddReport(runCtr, "REST", "UpdateUser", l, tryID);
                runCtr++;
            }

            runCtr = 1;

            foreach (long l in deleteUserRestTime)
            {
                objBLReport.AddReport(runCtr, "REST", "DeleteUser", l, tryID);
                runCtr++;
            }
        }

        static void TestAddUser(Guid _id,string _firstname,string _lastname)
        {
            Guid Id = _id;
            string FirstName = _firstname;
            string LastName = _lastname;

            Stopwatch timer;

            Console.WriteLine("Processing AddUser...");

            //WS

            timer = new Stopwatch();
            timer.Start();

            TesterWS.TesterWS objTesterWS = new TesterWS.TesterWS();

            TesterWS.UserInfo infoWS = new TesterWS.UserInfo();
            infoWS.FirstName = FirstName;
            infoWS.LastName = LastName;
            infoWS.ID = Id;

            objTesterWS.AddNewUser(infoWS);

            timer.Stop();

            addUserWSTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WS Finished...");

            //REST
            timer = new Stopwatch();
            timer.Start();

            TesterREST.TesterRest objTesterRest = new TesterREST.TesterRest();

            Model.UserInfo infoRest = new Model.UserInfo();
            infoRest.FirstName = FirstName;
            infoRest.LastName = LastName;
            infoRest.ID = Id;

            objTesterRest.AddNewUser(infoRest);

            timer.Stop();

            addUserRestTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("REST Finished...");

            //WCF
            timer = new Stopwatch();
            timer.Start();

            TesterWCF.TesterWCF objTesterWCF = new TesterWCF.TesterWCF();

            Modelo.UserInfo infoWCF = new Modelo.UserInfo();
            infoWCF.FirstName = FirstName;
            infoWCF.LastName = LastName;
            infoWCF.ID = Id;

            objTesterWCF.AddUser(infoWCF);

            timer.Stop();

            addUserWCFTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WCF Finished...");
        }

        static void TestGetUser()
        {
        }

        static void TestGetAllUsers()
        {
            Stopwatch timer;

            Console.WriteLine("Processing GetAllUsers...");

            //WS
            timer = new Stopwatch();
            timer.Start();

            TesterWS.TesterWS objTesterWS = new TesterWS.TesterWS();

            objTesterWS.GetAllUsers();

            timer.Stop();

            getAllUsersWSTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WS Finished...");

            //REST
            timer = new Stopwatch();
            timer.Start();

            TesterREST.TesterRest objTesterRest = new TesterREST.TesterRest();

            objTesterRest.GetAllUsers();

            timer.Stop();

            getAllUsersRestTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("REST Finished...");

            //WCF
            timer = new Stopwatch();
            timer.Start();

            TesterWCF.TesterWCF objTesterWCF = new TesterWCF.TesterWCF();

            objTesterWCF.GetAllUsers();

            timer.Stop();

            getAllUsersWCFTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WCF Finished...");
        }

        static void TestUpdateUser(Guid[] _ids,string _firstname,string _lastname)
        {
            Guid[] Ids = _ids;
            string FirstName = _firstname + " Updated";
            string LastName = _lastname + " Updated";

            Stopwatch timer;

            Console.WriteLine("Processing UpdateUser...");

            //WS

            timer = new Stopwatch();
            timer.Start();

            TesterWS.TesterWS objTesterWS = new TesterWS.TesterWS();

            TesterWS.UserInfo infoWS = new TesterWS.UserInfo();
            infoWS.FirstName = FirstName;
            infoWS.LastName = LastName;
            infoWS.ID = Ids[0];

            objTesterWS.UpdateUser(infoWS);

            timer.Stop();

            updateUserWSTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WS Finished...");

            //REST
            timer = new Stopwatch();
            timer.Start();

            TesterREST.TesterRest objTesterRest = new TesterREST.TesterRest();

            Model.UserInfo infoRest = new Model.UserInfo();
            infoRest.FirstName = FirstName;
            infoRest.LastName = LastName;
            infoRest.ID = Ids[1];

            objTesterRest.UpdateUser(infoRest);

            timer.Stop();

            updateUserRestTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("REST Finished...");

            //WCF
            timer = new Stopwatch();
            timer.Start();

            TesterWCF.TesterWCF objTesterWCF = new TesterWCF.TesterWCF();

            Modelo.UserInfo infoWCF = new Modelo.UserInfo();
            infoWCF.FirstName = FirstName;
            infoWCF.LastName = LastName;
            infoWCF.ID = Ids[2];

            objTesterWCF.UpdateUser(infoWCF);

            timer.Stop();

            updateUserWCFTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WCF Finished...");
        }

        static void TestDeleteUser(Guid[] _ids)
        {
            Guid[] Ids = _ids;
            Stopwatch timer;
            Console.WriteLine("Processing DeleteUser...");

            //WS
            timer = new Stopwatch();
            timer.Start();

            TesterWS.TesterWS objTesterWS = new TesterWS.TesterWS();

            objTesterWS.DeleteUser(Ids[0]);

            timer.Stop();

            deleteUserWSTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("WS Finished...");


            //REST
            timer = new Stopwatch();
            timer.Start();

            TesterREST.TesterRest objTesterRest = new TesterREST.TesterRest();

            objTesterRest.DeleteUser(Ids[1]);

            timer.Stop();

            deleteUserRestTime.Add(timer.ElapsedMilliseconds);

            Console.WriteLine("REST Finished...");

            //WCF
            timer = new Stopwatch();
            timer.Start();

            TesterWCF.TesterWCF objTesterWCF = new TesterWCF.TesterWCF();

            objTesterWCF.DeleteUser(Ids[2]);
            timer.Stop();
            deleteUserWCFTime.Add(timer.ElapsedMilliseconds);
            Console.WriteLine("WCF Finished...");

        }
    }
}

ReportBL.cs: this is the BusinessLayer that will call the DataLayer of the reporting in order to perform the operation in the Database.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class ReportBL
    {
        ReportDataAccess _data = new ReportDataAccess();
        public ReportBL()
        {
        }

        public void AddReport(int runId, string serviceType, string methodName,
            long elapsedTime, int tryId)
        {
            _data.AddReport(runId, serviceType, methodName, elapsedTime, tryId);
        }
    }
}


ReportDataAccess.cs: this is the DataLayer of the Reporting.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using DataHelper;

namespace ConsoleApplication1
{
    public class ReportDataAccess:DataAccessBase
    {
        public ReportDataAccess()
        {
        }

        public void AddReport(int runId, string serviceType, string methodName,
            long elapsedTime, int tryId)
        {
            DbParameterCollection parameters = new DbParameterCollection();

            SqlParameter pRunId = new SqlParameter("@RunId", SqlDbType.Int);
            pRunId.Value = runId;
            parameters.Add(pRunId);

            SqlParameter pServiceType = new SqlParameter("@ServiceType", SqlDbType.VarChar, 5);
            pServiceType.Value = serviceType;
            parameters.Add(pServiceType);

            SqlParameter pMethodName = new SqlParameter("@MethodName", SqlDbType.VarChar, 20);
            pMethodName.Value = methodName;
            parameters.Add(pMethodName);

            SqlParameter pElapsedTime = new SqlParameter("@ElapsedTime", SqlDbType.Int);
            pElapsedTime.Value = elapsedTime;
            parameters.Add(pElapsedTime);

            SqlParameter pTryId = new SqlParameter("@TryId", SqlDbType.Int);
            pTryId.Value = tryId;
            parameters.Add(pTryId);

            this.ExecuteNonQuery(
                "INSERT INTO TestReports (RunId,ServiceType,MethodName,ElapsedTime,TryId) " +
            "VALUES (@RunId,@ServiceType,@MethodName,@ElapsedTime,@TryId)", parameters);
           
        }
    }
}

UserProfileBL.cs: this is the BusinessLayer that will call the DataLayer of the UserProfile in order to fetch the IDs.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class UserProfileBL
    {
        public UserProfileBL()
        {
        }

        public Guid[] GetGuids(string filterName)
        {
            UserProfileData _data = new UserProfileData();

            return _data.GetAll(filterName);
        }
    }
}

UserProfileDataAccess.cs: this is the DataLayer of the UserProfile that will fetch the IDs.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using DataHelper;

namespace ConsoleApplication1
{
    public class UserProfileData : DataAccessBase
    {
        public UserProfileData()
        {
        }

        public Guid[] GetAll(string filtername)
        {
            List<Guid> _guids = new List<Guid>();

            DataTable dt = this.ExecuteDataTable("SELECT ID FROM UserProfile WHERE FirstName LIKE '%" + filtername + "%'");

            foreach (DataRow row in dt.Rows)
            {
                _guids.Add(new Guid(row["ID"].ToString()));
            }

            return _guids.ToArray();
        }
    }
}

 

RESPONSE TIME AND BANDWIDTH USAGE OF THE SERVICE

The simple Console Application was created in order to simulate the calls for each service and record the Response Time for each method and call. The result was stored in the Database with the following information: “Method Name” (The name of the method used e.g AddUser, DeleteUser), “Service Type” (The type of service e.g WS, REST, WCF), “Elapsed Time” (Response Time of the call), “RunID” (The Id of the thread), “TryID” (The Id of the trial made).

In order to avoid (or lessen) the SQL data cache, the method were executed (or called) as: AddUser first, followed by UpdateUser that was added, then GetAllUsers and finally, DeleteUser. The table was pre-populated with 13 records in which it won’t be modified / removed.

The Fiddler2 was used to capture the number of calls, bytes sent and received though out the processing of the method in the service.

The services were called as: WS, followed by REST and finally WCF.

During our attempts and trials during the test we did, it seems that among the differenct services, the WCF Rest and the Web Service SOAP utilizes the most efficient approach since it is only consuming very minimal bandwidth.  The WCF-WCF communication to our surprise seems to be less efficient since it is consuming to much bandwidth due to the multiple requests it sends to the server. During our quality testing, the WCF Rest and the Web Service SOAP takes the lead on our study.

Upon executing the Console Application made to simulate the call of each service, and from a lot of trials made to the calls (Figure 1), it turns out that REST has the lowest Response Time, followed by the WS. Whereas, the WCF has the highest Response Time among the different services.

From the information retrieved in the Fiddler2, and tallying the results, it was a shocking result produced. The REST and WS are both have only 1 call needed to complete the process (single method e.g. AddUser, DeleteUser), whereas the WCF needed 5 calls just to complete the process. By summing up the bytes and number of calls made (Figure 2), the REST has the lowest number of bytes sent and received, followed by WS which is more than 50% higher bytes sent and received compared to REST, and lastly WCF which is almost 300% higher bytes sent and received compared to REST.

Figure 1: Response Time

 

Figure 2: Bandwidth Usage

 

Considering the idea that we might utilize the services on a cloud computing environment, we must take into consideration the total amount of bytes sent and received on our services since cloud computing costs is based on the bytes used rather than the amount of requests sent and received. But since limiting the number of requests would also take a weight on the response and the bandwidth consumption it is better that we limit it.

Assuming we will use Amazon Cloud Computing (Since Windows Azure as of the moment does not release and actual cost of the service), based on the results above on the bandwidth usage, here are the financial forecasted results.

Figure 3. Forecast

 

WCF REST

 WS SOAP

WCF - WCF

Session Length (in minutes)

30

30

30

No. Of Sessions (No. Of Users)

1000

1000

1000

No. Of Transactions / session

4

4

4

Cost per hour (Instance Cost)

 $ 0.30

 $ 0.30

 $  0.30

Transactions Cost / GB (Sent)

 $  0.17

 $ 0.17

 $  0.17

Transactions Cost / GB (Received)

 $  0.10

 $ 0.10

 $  0.10

Total Bytes Sent in Bytes (Per Session)

857

3123

80068

Total Bytes Received in Bytes (Per Session)

7766

9023

87387

Subtotal for the Session

 $ 0.30

 $ 0.30

 $ 0.30

Subtotal for Trans Cost (Sent) / hr

 $ 0.000145690000

 $ 0.000530910000

 $ 0.013611560000

Subtotal for Trans Cost (Receive) /hr

 $ 0.000003106400

 $  0.000003609200

 $ 0.000034954800

Total / Hr

 $  0.3001487964

 $ 0.3005345192

 $ 0.3136465148

Total / Day

 $ 7.2035711136

 $  7.2128284608

 $  7.5275163552

Total / Month

 $  216.1071334080

 $  216.3848538240

 $ 225.8254906560

Total / Year

 $  2,593.2856008960

 $  2,596.6182458880

 $  2,709.9058878720

 

As what you can see on figure 3, WCF Rest basically is the cost effective solution in terms of the amount of bytes sent and received by the system.  The Web Services SOAP is also a viable solution for us however; this is based on the computation on available pricing as of the moment.  If Microsoft releases its official offering, we might have to reconsider the technology based on pricing.  On this part, WCF Rest again takes the lead over the 3 services.

CONCLUSION

After the study made on the services, it turns out that our expectation is wrong. The study clearly showed us that REST has the faster processing time shown in the Response Time and consuming the lowest bandwidth thru the use of bytes sent and received. WCF has the slowest Response Time and highest bandwidth usage. And lastly, WS which is in the middle of the two that has a medium Response Time and medium bandwidth usage.

 

Continuing on the article, here are the codes used for the different Communication methods.

Services

WCF-WCF

The WCF-WCF Service has 2 Files, the “UserAddress.cs” inheriting from “IUserAddress.cs” (an interface). Additional Project References are:  BL and Model.

UserAddress.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Xml.Linq;

namespace SampleWCFLibrary
{  
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,
        ConcurrencyMode=ConcurrencyMode.Multiple
        ,MaxItemsInObjectGraph=1000000)]
    public class UserAddress : IUserAddress
    {
        public void AddUser(Model.UserInfo user)
        {
            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Add(user);
        }

        public Model.UserInfo GetUser(Guid id)
        {
            BL.UserBL _objBL = new BL.UserBL();
            return _objBL.Get(id);
        }

        public List<Model.UserInfo> GetAllUsers()
        {
            BL.UserBL _objBL = new BL.UserBL();
            return _objBL.GetAll();
        }

        public void DeleteUser(Guid id)
        {
            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Delete(id);
        }


        public void UpdateUser(Model.UserInfo user)
        {
            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Update(user);
        }
    }
}


IUserAddress.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;


[assembly: ContractNamespace("", ClrNamespace = "SampleWCFLibrary")]
namespace SampleWCFLibrary
{
    [ServiceContract]
    public interface IUserAddress
    {
       
        [OperationContract]
       void AddUser(Model.UserInfo user);

        
        [OperationContract]
        Model.UserInfo GetUser(Guid id);

        
        [OperationContract]
        List<Model.UserInfo> GetAllUsers();



        [OperationContract]
        void DeleteUser(Guid id);

        [OperationContract]
        void UpdateUser(Model.UserInfo user);
    }    
}

 

REST

The REST service has 1 item called “WCF Service”. Additional project references: BL and Model.    The markup of the service (right-click the .svc file and choose view markup) should contain this code:

 

<%@ ServiceHost Language="C#" Debug="true" Service="MyRestTest.Service" CodeBehind="MyService.svc.cs" Factory="MyRestTest.AppServiceHostFactory" %>

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using Microsoft.ServiceModel.Web;

namespace MyRestTest
{
  class AppServiceHostFactory : ServiceHostFactory
  {
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        return new WebServiceHost2(serviceType, true, baseAddresses);
    }
  }
}


 
The .svc.cs file should contain the following code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.ServiceModel.Activation;
using Microsoft.ServiceModel.Web;


[assembly: ContractNamespace("", ClrNamespace = "MyRestTest")]
namespace MyRestTest
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceContract]
    public class Service
    {
 
        [WebGet(UriTemplate = "/adduser?user={user}")]
        [OperationContract]
        public void AddUser(string user)
        {
            XElement elem = XElement.Parse(user);
            Model.UserInfo userInfo = new Model.UserInfo();

            foreach (XElement e in elem.Elements())
            {
                switch (e.Name.LocalName)
                {
                    case "FirstName": userInfo.FirstName = e.Value; break;
                    case "LastName": userInfo.LastName = e.Value; break;
                    case "ID": userInfo.ID = new Guid(e.Value); break;
                }
            }

            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Add(userInfo);
        }

       
        [WebInvoke(UriTemplate = "/getuser?id={id}",
            Method="GET")]
        [OperationContract]
        public Model.UserInfo GetUser(string id)
        {
            BL.UserBL _objBL = new BL.UserBL();
            return _objBL.Get(new Guid(id));
        }

       
        [WebGet(UriTemplate = "/getall")]
        [OperationContract]
        public List<Model.UserInfo> GetAllUsers()
        {
            BL.UserBL _objBL = new BL.UserBL();
            return _objBL.GetAll();
        }



         [WebGet(UriTemplate = "/deleteuser?id={id}")]
        [OperationContract]
        public void DeleteUser(string id)
        {
            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Delete(new Guid(id));
        }


        [WebGet(UriTemplate = "/updateuser?user={user}")]
        [OperationContract]
        public void UpdateUser(string user)
        {
            XElement elem = XElement.Parse(user);
            Model.UserInfo userInfo = new Model.UserInfo();

            foreach (XElement e in elem.Elements())
            {
                switch (e.Name.LocalName)
                {
                    case "FirstName": userInfo.FirstName = e.Value; break;
                    case "LastName": userInfo.LastName = e.Value; break;
                    case "ID": userInfo.ID = new Guid(e.Value); break;
                }
            }

            BL.UserBL _objBL = new BL.UserBL();
            _objBL.Update(userInfo);
        }
    }
}

WS

The Webservice is an item called “Web Service”. It has files “.asmx” and “.cs”. Additional project references: BL and Model.

The “.cs” file should contain the following code:

using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Collections.Generic;

/// <summary>
/// Summary description for OgieWS
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class OgieWS : System.Web.Services.WebService
{

    public OgieWS()
    {

        //Uncomment the following line if using designed components
        //InitializeComponent();
    }

    [WebMethod]
    public void AddUser(Model.UserInfo user)
    {
        BL.UserBL _objBL = new BL.UserBL();
        _objBL.Add(user);
    }

    [WebMethod]
    public Model.UserInfo GetUser(Guid id)
    {
        BL.UserBL _objBL = new BL.UserBL();
        return _objBL.Get(id);
    }



    [WebMethod]
    public List<Model.UserInfo> GetAllUsers()
    {
        BL.UserBL _objBL = new BL.UserBL();
        return _objBL.GetAll();
    }

    [WebMethod]
    public void DeleteUser(Guid id)
    {
        BL.UserBL _objBL = new BL.UserBL();
        _objBL.Delete(id);
    }

    [WebMethod]
    public void UpdateUser(Model.UserInfo user)
    {
        BL.UserBL _objBL = new BL.UserBL();
        _objBL.Update(user);
    }
}

 

Tester Projects


TesterRest

TesterRest project is a specific project calling the methods of REST project. It has an application configuration key called “ServiceURL” which contains the URL of the REST project. Additional references: Model.

TesterRest.cs contains:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Net;
using System.IO;

namespace TesterREST
{
    public class TesterRest
    {
        public TesterRest()
        {
        }

        public void AddNewUser(Model.UserInfo info)
        {
            string xmlUser = "";

            XElement userInfo = new XElement("UserInfo",
                new XElement("FirstName", info.FirstName),
                new XElement("LastName", info.LastName),
                new XElement("ID", new Guid())
                );

            xmlUser = userInfo.ToString();

            Uri address = new Uri(string.Format("{0}adduser?user={1}", Settings1.Default.ServiceURL, xmlUser));

            HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
          
            try
            {
                WebResponse response = request.GetResponse();

            }
            catch (WebException wex)
            {
                StreamReader reader = new StreamReader(wex.Response.GetResponseStream());
                throw wex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<Model.UserInfo> GetAllUsers()
        {
            List<Model.UserInfo> userCollections = new List<Model.UserInfo>();

            XElement rootXml = XElement.Load(string.Format("{0}getall", Settings1.Default.ServiceURL));
            foreach (XElement u in rootXml.Elements())
            {
                Model.UserInfo user = new Model.UserInfo();

                foreach (XElement i in u.Elements())
                {
                    switch (i.Name.LocalName)
                    {
                        case "FirstName": user.FirstName = i.Value; break;
                        case "LastName": user.LastName = i.Value; break;
                        case "ID": user.ID = new Guid(i.Value); break;
                    }

                }
                userCollections.Add(user);
            }
            return userCollections;
        }

        public Model.UserInfo GetUser(Guid id)
        {
            XElement rootXml = XElement.Load(string.Format("{0}getuser?id={1}", Settings1.Default.ServiceURL, id.ToString()));

            Model.UserInfo user = new Model.UserInfo();

            foreach (XElement i in rootXml.Elements())
            {
                switch (i.Name.LocalName)
                {
                    case "FirstName": user.FirstName = i.Value; break;
                    case "LastName": user.LastName = i.Value; break;
                    case "ID": user.ID = new Guid(i.Value); break;
                }
            }
            return user;
        }

        public void UpdateUser(Model.UserInfo info)
        {
            string xmlUser = "";

            XElement userInfo = new XElement("UserInfo",
                new XElement("FirstName", info.FirstName),
                new XElement("LastName", info.LastName),
                new XElement("ID", info.ID)
                );

            xmlUser = userInfo.ToString();

            Uri address = new Uri(string.Format("{0}updateuser?user={1}", Settings1.Default.ServiceURL, xmlUser));

            HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
                       
            try
            {
                WebResponse response = request.GetResponse();

            }
            catch (WebException wex)
            {
                throw wex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeleteUser(Guid id)
        {
            Uri address = new Uri(string.Format("{0}deleteuser?id={1}", Settings1.Default.ServiceURL, id.ToString()));

            HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;


            try
            {
                WebResponse response = request.GetResponse();

            }
            catch (WebException wex)
            {
                throw wex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

 

TesterWCF

TesterWCF project is a specific project calling the methods of WCF project. It has an application configuration key called “URLService” which contains the URL of the WCF project. It has 2 .cs files, TesterWCF.cs and SampleWCF.cs. The SampleWCF.cs is a proxy class generated by a tool by executing “svcutil.exe http://localhost:6969/SampleWCFLibrary/UserAddress.svc?wsdl”.

TesterWCF.cs contains:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Modelo;

namespace TesterWCF
{
    public class TesterWCF
    {
        UserAddressClient client;

        public TesterWCF()
        {
        }



        public void AddUser(UserInfo user)
        {
            client = new UserAddressClient();

            client.AddUser(user);
            client.Close();
        }

        public UserInfo GetUser(Guid id)
        {
            UserInfo user = null;
            client = new UserAddressClient();

            user = client.GetUser(id);
            client.Close();

            return user;
        }

        public List<UserInfo> GetAllUsers()
        {
            client = new UserAddressClient();
            List<UserInfo> userCollections = client.GetAllUsers().ToList<UserInfo>();
            client.Close();
            return userCollections;
        }

        public void UpdateUser(UserInfo user)
        {
            client = new UserAddressClient();
            client.UpdateUser(user);
            client.Close();
        }

        public void DeleteUser(Guid id)
        {
            client = new UserAddressClient();
            client.DeleteUser(id);
            client.Close();
        }
    }
}


TesterWS

TesterWS project is a specific project calling the methods of WS project. It has an application configuration key called “ServiceURL” which contains the URL of the WS project. It has 2 .cs files, TesterWS.cs and WSProxy.cs. The WSProxy.cs is a proxy class generated by a tool by executing “wsdl.exe  http://localhost:6969/MyTestWS/MyWS.asmx?wsdl”.


TesterWS.cs contains:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TesterWS
{
    public class TesterWS
    {
        WSProxy channel;

        public TesterWS()
        {
        }
        public void AddNewUser(UserInfo info)
        {
            channel = new WSProxy();

            channel.AddUser(info);
        }

        public List<UserInfo> GetAllUsers()
        {
            channel = new WSProxy();

            List<UserInfo> userCollections = new List<UserInfo>();

            userCollections = channel.GetAllUsers().ToList<UserInfo>();

            return userCollections;
        }

        public UserInfo GetUser(Guid id)
        {
            channel = new WSProxy();

            UserInfo info = channel.GetUser(id);

            return info;
        }

        public void UpdateUser(UserInfo info)
        {
            channel = new WSProxy();

            channel.UpdateUser(info);
        }

        public void DeleteUser(Guid id)
        {
            channel = new WSProxy();

            channel.DeleteUser(id);
        }
    }
}

 

To be continued..

As promised I will be providing a series of articles that could be beneficial for those individuals thinking to move on Windows Azure, I would like to share this study me and my Team made for finding the best communication options.  Kudos for Rogelyn Chu (For the help on the study) and Michael Dorchain (For giving me the opportunity to work on this study).

Software architecture indeed needs a lot of careful study and analysis on the technology to use.  This study is a vital component for us to identify whether this could be one of the core technologies we will implement on delivering the solution needed by our business.  As times change and communication between systems has been the key factor of the success of implementing applications, this study could lead to solve this complexity and identify which would be the best solution for our design.

THE CHALLENGE: ONE PLATFORM FOR DIFFERENT KINDS OF COMMUNICATION

There’s no way around it: Different .NET Framework applications need different kinds of communication. Sometimes an application built using WCF needs to interact with code running on some other platform, such as a Java application server. The best choice here is frequently interoperable communication using SOAP, perhaps with one or more of the WS-* specifications. When a WCF application interacts with another WCF application, however, paying the performance price exacted by SOAP’s standard XML encoding isn’t necessary. A speedier binary encoding, one designed expressly for WCF-to-WCF communication, is a better choice. In other cases, the interaction style known as Representational State Transfer (REST) might be the right choice. More and more Internet applications provide a RESTful interface, for example, and so WCF applications must be able to communicate using this approach.

There are plenty of other possibilities, too. An application might need to send XML-defined data directly over HTTP, an approach that’s commonly known as Plain Old XML (POX). Perhaps that XML should be structured using common formats such as RSS and ATOM. Communication with a line-of-business application such as SAP might require an application-specific adapter. Queued messaging can be the best choice when reliable communication is required between occasionally connected systems. Similarly, the built-in peer-to-peer networking functions of Windows are the right solution for a certain class of problems, while some form of inter process communication, such as Windows named pipes, is required for interactions between software on the same machine.

Until relatively recently, each of these communication styles was supported with its own idiosyncratic platform. Developers were forced to learn a different programming model for each approach. WCF was created to change this, and as described next, it has.

But considering the fact that most of the .NET developers are still adjusted with the Web Services SOAP approach, we should not leave this out and take it into consideration.  With that, we will also dig into the earlier approach of communicating via SOA since, web services are still one of the easiest applications to interact with other platforms.

Expectations on this Study

At the end of this study, it is expected that we will identify the best solution in terms of its effectiveness and efficiency using various factors like response time; bytes sent and received, and as well as cost economics.  This study would also enable readers of this document to have an initial understanding of the technologies being evaluated.

Approach to the Study

The approach of this study would be a experimental approach to have a real basis of the conclusion of this paper.  Since there are three subjects to be tested, we will be creating the three services in order for us to test and compare their performance and determine their strengths and weaknesses.  The services would be a WCF Rest Service, a Web Service SOAP, and a WCF-WCF Binary communication.  All services would be using the same Business Layer, Data Layer and Model; with this approach, we will be able to really identify which would be the best technology to use between them.

This study would basically focus only on Microsoft WCF REST, Microsoft Web Services SOAP and Microsoft WCF-WCF Communication tapping particularly the effectiveness and efficiency of the services. This would also include a forecast of how much cost we will incur if the services would be deployed on a cloud network.
 
In particular, this study would not be covering other services implementation offered by non-Microsoft Companies, deployment of services in a cloud network, windows azure and the likes, and full details of deployment guidelines and possible deployment plan.

Main Study

Lets say that on this study we will create a basic application that would utilize CRUD (Creat-Read-Update-Delete) functionalities on a single table Source named “UserProfile” which has 3 columns: “ID” (uniqueidentifier), “LastName” (varchar 200), and “FirstName” (varchar 200).

The methods are: “AddUser” (no return value), “UpdateUser” (no return value), “DeleteUser” (no return value), and GetAllUsers “List of UserProfile”.
We will be getting the following variables during the study: “Bytes Sent” (number of bytes sent in the request to the service), “Bytes Received” (number of bytes received in the response of the service), “Number of Calls” (the number of times in which a method needs to do to perform its function), and “Response Time” (the amount of time in milliseconds the request and response took place in a method of the service).

For checking the bytes send and received on this application, Fiddler2, Visual Studio 2008 and SQL Express 2005 was used in this study.  You could get a copy of the tool at www.fiddler.com.

Here are the codes you need to recreate in order to come up with the test:

Data Layer

    The Data Layer is also known as DataAccess project in this scenario. It will be called by Business Layer.  It’s inheriting the “DataAccessBase” from DataHelper project.  Additional project references:  DataHelper and Model.

Business Layer

    The Business Layer will call the Data Layer. Additional project references: DataAccess, Model and DataHelper.

 

On the next part of the article I will show you the Communication codes used for WCF REST, WS and WCF-WCF Communication.

 

 

I am so pleased to announce that Azure would start now to move to the Coordinated Universal Time staring March 8, 2009 at 10:00 AM GMT. This was based on the email I got from the Azure Services Platform Team. Good news for a lot of developers then.

 

For those who have read my previous post, this is just a follow up blog for it. :)

Posted by Max Bautista | with no comments

I was reading an article on Windows Azure and was surprised to know that currently Azure is running on Pacific Standard Time.  It's a good thing to know that soon, they will be migrating to Coordinated Universal Time (UTC).  A good thing then for applications relying on local time.

 

When will Microsoft make the change?

As far as Microsoft is concerned, they will make this change soon.  Most probably on the next few weeks.  As of the moment, series of testings are being conducted within the community and these feedback would enable Microsoft to identify as to when the move would take place.

 

Why are they doing this?

Why not? Since Windows Azure is a global service platform, it is but right to have all applications inside the platform to behave the same way regardless of geographic conditions. It is but right to have windows Azure be consistent to all users worldwide.  And if we are speaking of consistency, the standard choice now for timezone would be utilizing UTC.

 

What’s the potential impact to us?

Basically based on the blog I read regarding this, the following would be the impact of the migration to UTC.

 

  • Occurence of gaps in the event logs if local timestamps would be used.
  • Different results may occur if the UI of the application depend on the local timestamp.
  • Some local timestamps stored already by the application may be interpreted differently on the move.

But design wise, a lot of applications now are utilizing UTC.  But for those not yet utilizing this standard, you should take a look on the effects that might occur.  For the others, your applications are safe.

 

Architecting services for Windows Azure basically undertakes the following considerations:

  • Cloud Services have specific design considerations : always on, distributed state, large scale, failure handling (you should expect failures and you should handle them)
  • Windows Azure is an OS for the Cloud : scale out, dynamic, and on-demand. Each machine runs its own layer, but together this makes an OS
  • Windows Azure manages services not just servers : tell it what you want, it will help automate the details
  • Windows Azure frees developers from many platform issues : you concentrate on application logic instead of platform issues

How to architect Windows Azure Services ?

Cloud Computing is based on Scale-Out not scale-up. You can add / remove capacity on demand. Pay for what you use as you go. Automation is key to reducing costs.

Design considerations

  • Failure of any given node (or role) should be expected : view each node (or role) as a cache, state has to be replicated (don't assume your state is safe)
  • No one-time install step : applications need to reinitialize on restarts. Do not assume previous local state is available (If a node fails, we will try to restart you)
  • Configuration changes due to load or failures : handle dynamic configuration changes
  • Services are always running (there is no maintenance window) : your code has to handle upgrades or downgrades + your code must handle data schema changes
  • Services are built using multiple nodes / roles : document service architecture, document communication paths of elements
  • Services can grow very large : state management will become difficult

ð  Those issues are not new : you have tried to be as stateless as possible.

If you have good design, Windows Azure will manage your services, nodes and network. Windows Azure automates life cycle management (Model Driven Automation).

Further readings can be found on this link.

 

 

First of all, I would like to thank Risman for helping me out open this blog.  I would love to help this community get involved more on this technology and bring Cloud Computing potentials to the Philippines.

So before we define What's Windows Azure, let us first get a good understanding of what is Cloud Computing.

So let's say, we have an application and we wanted this application to be available anywhere in the world regardless of platform then we definitely need have a way to host this. Quoting on an article I saw in Wikipedia:

 

"Cloud computing is Internet ("cloud") based development and use of computer technology ("computing").It is a style of computing in which dynamically scalable and often virtualised resources are provided as a service over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure "in the cloud" that supports them.

The concept incorporates infrastructure as a service (IaaS), platform as a service (PaaS) and software as a service (SaaS) as well as Web 2.0 and other recent (ca. 2008-2009) technology trends which have the common theme of reliance on the Internet for satisfying the computing needs of the users. Examples include Salesforce.com and Google Apps which provide common business applications online that are accessed from a web browser, while the software and data are stored on the servers."

So Microsoft's move towards cloud computing pave the way to the birth of the Azure Services Platform. So what is this platform?

 

The AzureTM Services Platform (Azure) is an internet-scale cloud services platform hosted in Microsoft data centers, which provides an operating system and a set of developer services that can be used individually or together. Azure's flexible and interoperable platform can be used to build new applications to run from the cloud or enhance existing applications with cloud-based capabilities. Its open architecture gives developers the choice to build web applications, applications running on connected devices, PCs, servers, or hybrid solutions offering the best of online and on-premises.

Azure reduces the need for up-front technology purchases, and it enables developers to quickly and easily create applications running in the cloud by using their existing skills with the Microsoft Visual Studio development environment and the Microsoft .NET Framework. In addition to managed code languages supported by .NET, Azure will support more programming languages and development environments in the near future. Azure simplifies maintaining and operating applications by providing on-demand compute and storage to host, scale, and manage web and connected applications. Infrastructure management is automated with a platform that is designed for high availability and dynamic scaling to match usage needs with the option of a pay-as-you-go pricing model. Azure provides an open, standards-based and interoperable environment with support for multiple internet protocols, including HTTP, REST, SOAP, and XML.

Microsoft also offers cloud applications ready for consumption by customers such as Windows LiveTM, Microsoft DynamicsTM, and other Microsoft Online Services for business such as Microsoft Exchange Online and SharePoint® Online. The Azure Services Platform lets developers provide their own unique customer offerings by offering the foundational components of compute, storage, and building block services to author and compose applications in the cloud.

Ok, now I know most of you would say, we know that already and we have seen it at the Web Ramp up event, how do I really start using it? The answer, it's just creating the conventional way of web applications, difference is you just have another way of creating packages for deployment in azure.  And there are a lot of exciting features in Azure that would be very beneficial to business and for us developers.

For starters, I will repost the list of links I have sum up on one of the links in the forums.

Visual Studio development

Quick lap around VS2008 azure tools (very nice)
http://msdn.microsoft.com/en-us/library/dd203059.aspx


Development fabric & storage integration
http://msdn.microsoft.com/en-us/library/dd203061.aspx


Deployment
http://msdn.microsoft.com/en-us/library/dd203057.aspx


Azure training kit
http://www.microsoft.com/downloadS/details.aspx?FamilyID=413e88f8-5966-4a83-b309-53b7b77edf78&displaylang=en


Windows Azure Tools Development Fabric and Storage Integration
http://msdn.microsoft.com/en-us/library/dd203061.aspx


Integrating LiveID/AD into Azure projects
http://dev.live.com/blogs/devlive/archive/2008/11/12/432.aspx

 

Azure SDK's
http://www.microsoft.com/azure/sdk.mspx

 

Azure

Azure management tools
http://code.msdn.microsoft.com/AzureManagementTools


Live services poster
http://dev.live.com/liveframework/livefxposter.pdf



Whitepapers

Azure services platform
http://download.microsoft.com/download/e/4/3/e43bb484-3b52-4fa8-a9f9-ec60a32954bc/Azure_Services_Platform.docx


Azure blobs
http://go.microsoft.com/fwlink/?LinkId=131258


Azure Tables
http://go.microsoft.com/fwlink/?LinkId=131257

 

Azure Services Platform Videos

Windows Azure "How Do I" Videos

How Do I: Get Started Developing with Windows Azure?
http://msdn.microsoft.com/en-us/azure/dd327648.aspx

How Do I: Deploy a Windows Azure Application?

http://msdn.microsoft.com/en-us/azure/dd327644.aspx

How Do I: Store Blobs in Windows Azure Storage?
http://msdn.microsoft.com/en-us/azure/dd327650.aspx

How Do I: Leverage Queues in Windows Azure?
http://msdn.microsoft.com/en-us/azure/dd464806.aspx

Debugging Tips for Windows Azure Applications
http://msdn.microsoft.com/en-us/azure/dd464807.aspx

How Do I: Store Data in Windows Azure Tables?
http://msdn.microsoft.com/en-us/azure/dd483299.aspx

.NET Services "How Do I" Videos

How Do I: Get Started with .NET Services?
http://msdn.microsoft.com/en-us/azure/dd441704.aspx

How Do I: Harness the Microsoft .NET Service Bus?
http://msdn.microsoft.com/en-us/azure/dd441706.aspx

Live Services "How Do I" Videos

How Do I: Get Started with the Live Framework?
http://msdn.microsoft.com/en-us/azure/dd425068.aspx

How Do I: Use the Microsoft Live Framework Resource Browser?
http://msdn.microsoft.com/en-us/azure/dd441707.aspx

So with these references to start with, are we ready now? I hope you are.  Since I have prepared myself now to take the leap on the next level of cloud computing starting with the Azure Services Platform.