| More
Web Development
 


Session State in Windows Azure

By Jim White (Intertech Instructor and Director of Training)

If you are a Web developer, you are probably very familiar with managing user state - that is you are familiar with tracking user activity and actions across several request-response exchanges that occur in Web applications.  Since HTTP is a stateless protocol, developers over the years have developed all sorts of means to manage state.  You'll even find an MSDN page providing alternatives and recommendations for state management here.  Cookies, hidden fields, and query strings are some client-side options to tracking user state.    When it comes to managing that state on the server-side, most Web developers rely on session objects.

Session Objects in Azure

There are sessions in Azure just as you would find them in ASP.NET applications.  For example, the following lines of code would add and retrieve a Customer from the current HttpSessionState object.

Session["currentCustomer"] = new Customer("Joe", "Smith");
Customer customer = (Customer)Session["currentCustomer"];

So, the Web server in Azure provides you the same session object you are accustomed to working with today.  However, the sessions in Azure are not ?sticky.?  In other words, if you have multiple Web role instances, Azure does not guarantee to route a user?s requests to the same Web role instance.  In fact, the load balancer in Azure works to the opposite effect. The load balancer tries to route traffic evenly to all instances regardless of the request's origination.  Since each Web role instance has its own session, there is effectively no shared session data across Web roles.

stickysessionnot

To help understand the implications of this issue, say the user represented by the "client" box above is working with a retail Web site.  If "Request 1" was a request to add an item to the shopping cart, when the user goes to check out per "Request 2", she will be very disappointed to find the item missing from her cart.  That is because the item is in a shopping cart session object associated to the first Web Role and not the shopping cart object associated to the second Web Role.

In-memory Web Server Session Management

Session objects, when managed by the Web server, are often stored in memory on the Web server.  Of course in Windows Azure, each Web role has its own Web server.  You could remove this issue by having only one Web role.  By having just one Web role, you remove load balancing from the picture.  Limiting your application to one Web role also limits your application's scalability - presumably one of the reasons you chose to move your application to Azure in the first place.  If you eventually need to scale your application to involve multiple instances, you now need to rewrite parts of your application. 

Even if scalability is not a chief concern, there are other reasons you should hesitate before using standard Web server sessions to manage user state.  In-memory sessions use a precious commodity: memory.  If your application puts a lot of data in session, your application can experience out of memory errors.  Also, if your Web role fails, Azure establishes your instance on another server.  However, the in-memory session information - still back on the other Web server - is lost.

Session State in Azure Storage

What's the solution to this session dilemma?  Persist your session objects in Azure Storage versus in-memory on the Web server.  Putting session information in table storage has several advantages.  It scales.  It allows all instances of a Web role (or any role) to share session data.  It is always available and stored in triplicate. So, if your role goes down, session data is not lost.

Setup to Use Table Storage for Sessions

To use table storage to persist sessions, you must first modify the Web.config file in your Web role project to indicate you are using a different session provider.  Add the following element to the <system.web> element, replacing ?yourWebAppName? with the name of your Web application.

<sessionState mode="Custom"
       customProvider="TableStorageSessionStateProvider">
    <providers>
      <clear/>
        <add name="TableStorageSessionStateProvider" type=  "Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider"
             applicationName="yourWebAppName"/>
    </providers>
</sessionState>

Note: you may find Visual Studio editors provide false warnings on this entry indicating type and applicationName attributes are not allowed.

Secondly, get a copy of the Windows Azure Platform Training Kit (the June 2010 release is available for download here).  In the kit, look for an AspProviders Visual Studio project (its in the WindowsAzureDeployment lab under Source\Assets).  This project contains a TableStorageSessionStateProvider class that implements the Table Storage Service Provider.

You can either include the AspProviders project into your solution or compile the DLL and reference the DLL.  The AspProviders project uses the DataConnectionString configuration setting to get all the information needed to access table storage for your account.  Make sure you establish your DataConnectionString and point it to use development storage or your storage in the cloud as appropriate.

Using Sessions Persisted in Table Storage

With these adjustments, you use the same API calls as those listed at the top of this blog entry to add and retrieve data to/from session.  However, now user state is not held in memory on the Web server.  It is, instead, persisted to table storage.  The TableStorageServiceProvider actually creates a ?Sessions? table in table storage by default.  So you don't even have to set up or manage the actual table schema in table storage.  After you test and run your application, you can use a tool like Cerebrata?s Cloud Storage Studio to explore the "Sessions" data table.

image

When exploring the Sessions table in table storage, be aware that the data is not stored in a fashion for easy viewing.  In fact, the actual session data is packed away in an associated blob storage record.  Also, don?t forget that objects must be serializable if they are to be stored in session.


Posted by: Jim White
Posted on: 8/15/2010 at 8:32 PM
Tags: , , , ,
Categories: Cloud Computing | .NET | Web Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

1 Hour Understanding jQuery Video

In this one hour video,

  • Understand the purpose and advantages of using jQuery.
  • Learn how to add jQuery to your Web applications.
  • Become familiar with the jQuery object, its primary methods, and the benefit of “implicit iteration.”
  • Use jQuery’s rich selector API for an easy way to match individual and sets of elements.
  • Reduce and organize code by leveraging jQuery’s Ajax utilities.
  • Quickly add and customize sophisticated GUI Widgets through jQuery plug-ins…

 


Posted by: Intertech
Posted on: 8/2/2010 at 1:39 PM
Tags:
Categories: Java | Web Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Windows Azure Local File Storage - How To Guide and Warnings

By Jim White (Intertech Director of Training and Instructor)

In general, Microsoft has tried to make writing Web applications for the Azure platform akin to writing for your local IIS environment.  In fact, Microsoft lists "use your existing development skills to build cloud applications" on the Azure Web site as one of its major selling points.  I think, to a large extent, .NET developers will find building or moving an application to Azure straightforward.  However, to be fair, there are also a number of areas where the application will change to deal with the reality of this new platform and, more generally, cloud computing.  One of those areas is simple file access and/or local storage.

File Access in the "Normal" ASP.NET world

For example sake, say you needed to read/write from a simple text file.  Perhaps you need to read some configuration information from the file, or perhaps some SQL that you need to execute was in the file.  Whatever the reason, accessing this file is pretty straightforward.  In a "normal" ASP.NET application, accessing a file that is stored on a virtual path on the Web server is quite simple and might look like the code below (in C#).

    //----------------------- read config contents --------------------------------
    try
    {
        string s = System.IO.File.ReadAllText(Server.MapPath("myConfigs") + "myFile.txt");
        //... do your work with s
    }
    catch (Exception myException)
    {
       ...    }

    //----------------------- write config contents --------------------------------
    if (!text.Equals(""))
    {
        System.IO.File.WriteAllText(Server.MapPath("myConfigs") + "myFile.txt", text);
    }
    else
    {
        System.IO.File.WriteAllText(Server.MapPath("myConfigs") + "myFile.txt", "no data");
    }

File Access in the Cloud

Now, how would that look in the cloud?  Well, first you must step back and consider that local storage in the cloud is not the same as that under our local IIS environment.  Local storage, is assumed under an ASP.NET application running on a local IIS server.  In the Azure world, you must first configure your role to request local storage as it is deployed.  This can be done with the Role Editor in VS 2008.  The Local Storage tab on the editor allows you to specify the name, size and clean/role policy for the storage as shown below.

image The information from this editor is stored in the service definition file of the role and used to configure the Azure environment when the application is published to the cloud.

Local Storage Location

So now you have local storage, but where is it?  When you deploy your application (consisting of either a web or worker role) to Azure, a storage area is assigned to your application.  The exact location is at the Azure servers discretion.  The physical path of the folder for your assigned storage can be located through the Azure API.  In this case, request the location of your local storage through, Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.  The RoleEnvironment class represents the Azure environment that your instance of your role (web or worker) is running in.  So, reading and writing to that file might look something like the following code in an Azure world.

    //----------------------- read config contents in Azure -----------------------
    try
    {

            LocalResource myConfigsStorage = RoleEnvironment.GetLocalResource("myConfigs");

        string s = System.IO.File.ReadAllText(myConfigStorage.RootPath + "myFile.txt");
        //... do your work with s
    }
    catch (Exception myException)
    {
        ...    }

    //----------------------- write config contents in Azure------------------------
    if (!text.Equals(""))
    {

           LocalResource myConfigsStorage = RoleEnvironment.GetLocalResource("myConfigs");

        System.IO.File.WriteAllText(myConfigStorage.RootPath + "myFile.txt", text);
    }
    else
    {
        System.IO.File.WriteAllText(myConfigStorage.RootPath + "myFile.txt", "no data");
    }

Easy enough you say.  Yes, the API is straightforward enough so as to appease most .NET developers.  However, a bigger issue with regard to this local storage must be considered.

Local Storage is Temporary and Instance Relative in the Cloud

Local storage, like that just used in the example to read/write text to myFile.text is temporary in Azure!  So, if the virtual machine supporting your role dies and cannot recover, your local storage is lost!  Therefore, Azure developers will tell you, only volatile data should ever be stored in local storage of Azure.  Furthermore, I eluded earlier to the fact that the storage was per instance of a role.  Importantly, local storage is not shared across multiple role instances.  Usually, people move applications to the cloud to take advantage of the scalability and redundancy multiple instances provide.  But these instances each have their own local storage and cannot access each others.  If the data in the local storage is changing and must be shared, you need to rethink the application design.

Local Storage Alternatives

If you need to read/write data in the cloud in a non-volatile and shared way , take advantage of Azure's storage options:  blobs, table storage, queues and SQL Azure databases.  My co-worker Tim Star (Microsoft MVP) has described them in his blog post here.  This may require some application re-architecting, but in the end, your application will run better, stronger, faster in the Azure cloud.


Posted by: Jim White
Posted on: 4/25/2010 at 8:24 PM
Tags: , , , ,
Categories: Cloud Computing | .NET | Web Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Spring MVC Command Beans - As Complex As You Need

By Jim White (Intertech Instructor and Director of Training)

It was Spring Framework training again this past week.  How fitting as it was also the first official week of spring and as pro-baseball's Spring Training was wrapping up.

This week, I had two students in my class that are getting ready to develop a new web application for their company.  This web application is going to be built with Spring and Spring MVC.  They have been given a prior web application as a project "template."  So this week's class gave them a great opportunity to learn Spring, and to figure out how to design and build their application around some of the features they have seen in the existing template project.  I love having students in class that have a very concrete purpose for learning the material.  I found these students are eager to learn, and they like challenging me with interesting problems that they want to apply in their applications.  It provides me the opportunity to do what I call "micro-consulting."  In the span of a class, I can't create an entire application, but I can sometimes help solve particular challenges students have.

One of the complex Spring MVC user interfaces my students, Mark and Senthil, know they will have to address deals with showing multiple records in an HTML table and allowing users to randomly edit the data in the table.  A checked checkbox at the front of each row is an indication, on the part of the user, that they have modified something in that row and want the new data provided in that row stored in the database.  A checkbox left unchecked means that the data in that row, regardless of any changes, to be left unsaved.  For demonstration purposes, I have shown a mock up of this kind of UI below for "customer contact" data.  As the contact data is brought up in the edit page, you can change all the data in each row and each field, but unless you also check the checkbox to the left (arrow identifying below), then no update of that row is made in the database.

image

Now, you can argue the merits of this user interface (I like to call it "table-o-data") all you would like.  However, as a practical matter, we all know that the companies we work with design and evolve user interfaces that the business has become comfortable with or find to be productive.  The question put forth to me was can a Spring MVC controller/command bean design be set up to accommodate such a UI?  The answer is absolutely yes!

Spring's MVC components are quite flexible to address all sorts of imaginable UIs.  The Command bean itself is really just the name we give to the set of objects that harvest and provide data from/to the view (which is usually in the form of HTML).

A More Complex Command Bean

          Note:  Code for this example is provided at the link at the bottom of this blog post.

So let's explore how a more complex command bean can be devised to deal with Mark and Senthil's "table-o-data" UI.  In this case, each row represents a single customer contact.  So, at first we build a simple Contact POJO.

public class Contact {
    private Long id = 0L;
    private String firstName;
    private String lastName;
    private Date dateOfBirth = new Date();
    private boolean married = false;
    private int children;
    private boolean updating = false;
    //getters, setters, constructors left off for brevity
}

The updating boolean property will hold the true/false checkbox indication that the Contact data should be updated/saved in the database.

Most Spring MVC references and books use a simple POJO like this one as the command bean behind a view that allows a user to edit a single instance of a contact.  However, in this case, a collection of these Contact beans must be in place to allow multiple rows to be edited.  To accomplish this task, we need another, more complex, "command bean."  Below is the code for a ContactList that servers as our command bean.  Notice that the ContactList wraps a list of Contact objects from above.

public class ContactList {
    private List<Contact> contacts;
    //getters and setters removed for brevity
}

Command beans do not have to be simple objects with no relationship to other objects.  Command beans can have relationships with other object, can be collections of objects, or even a map of data values (see http://forum.springsource.org/showthread.php?t=18687 for an example of a HashMap of data values captured from a UI).

The JSP - Using Spring Form Tags, JSTL with the Command Bean

The trick of using a more complex command bean is finding out how to access and reference it's properties, associated objects, etc. through the form tags in your JSP.  Spring MVC form tags allow you to use dot notation to access properties containing other objects.  You can also use square brackets [ ] to navigate around collections like our list above.  Here is the form portion of the editcontacts.jsp that displays the many customer contacts in the "table-o-data" example shown above.

<form:form action="editcontacts.request" method="post" commandName="contactList">
    <table border="1">
        <tr>
            <th>&nbsp;</th>
            <th>First name</th>
            <th>Last name</th>
            <th>Date of birth</th>
            <th>Married</th>
            <th>Children</th>
        </tr>
        <c:forEach items="${contactList.contacts}" var="contact" varStatus="x">
            <tr>
                <td><form:checkbox path="contacts[${x.index}].updating" value="true"/></td>
                <td><form:input path="contacts[${x.index}].firstName"/></td>
                <td><form:input path="contacts[${x.index}].lastName"/></td>
                <td><form:input path="contacts[${x.index}].dateOfBirth"/></td>
                <td><form:checkbox path="contacts[${x.index}].married" value="true"/></td>
                <td><form:input path="contacts[${x.index}].children"/></td>
            </tr>
        </c:forEach>
    </table>
    <input type="submit" value="Save" />
    <form:errors path="*"/>
</form:form>

Notice how I use JSTL to iterate through the many Contacts in the ContactList (the command bean) which is stored under the name "contactList."   In the form field tags, I use dot notation in the path attribute to access each contact and the properties within the contact (firstName property is accessed out of a contact bean below).  Using a little expression language and square bracket notation, I can access each Contact in the ContactList list.

path="contacts[${x.index}].firstName"

The Controller

What's left is to show you is the important parts of the controller.  In this example, I use a SimpleFormController and configure the controller's command bean as an instance of ContactList.  The XML Spring configuration of the controller is shown below.

</bean>
    <bean id="editContactController" class="com.intertech.controllers.EditContactController">
    <property name="contactService" ref="contactService" />
    <property name="commandClass" value="com.intertech.domain.ContactList" />
    <property name="commandName" value="contactList" />
    <property name="formView" value="editcontacts" />
    <property name="successView" value="confirm" />
</bean>

In the formBackingObject method of the EditContactController, I retrieve the existing Contacts and create the ContactList to populate the edit contacts JSP.

protected Object formBackingObject(HttpServletRequest request)
        throws Exception {
    List<Contact> contacts = contactService.getContacts();
    ContactList list = new ContactList();
    list.setContacts(contacts);
    return list;
}

Then in the doSubmitAction, when the form holding the "table-o-data" is submitted with a POST operation, simply iterate through each contact in the ContactList command bean and determine if the "updating" check box has been checked.  If so, update the contact in the database.

protected void doSubmitAction(Object command) throws Exception {
    ContactList myList = (ContactList) command;
    for (Contact c : myList.getContacts()) {
        if (c.isUpdating()){
            contactService.updateContact(c);
        }
    }
}

Spring MVC Controller Stereotypes

This example uses the Spring MVC 2.5.6 controller hierarchy.  With Spring 3.0, the controller hierarchy is being retired in favor of stereotype components and @Controller annotations.  However, use of command beans is still used in the new MVC architecture.  So the structure of the command bean and JSP does not change.  The controller becomes just a plain Java class with @Controller and @RequestMapping annotations.

Wrap Up

Command beans can be as complex or as simple as they need to be to capture (and possibly redisplay) data in your UI screens.  Don't limit your imagination to simple classes with primitive properties and Strings.  Understand your UI needs and develop a command bean that addresses the UI and not the reverse.

I'd like to thank my students Mark and Senthil for attending my class this week and for providing the idea for this week's blog entry.  The code for the example you see here (complete with DDL and batch files for HSQLDB) is available in a WAR file (optimized for Apache Tomcat 6) stored in a ZIP file (for transport over the Web) located here.  If you would like to learn more about Spring and be the next student that experiences micro-consulting, join me for a class at Intertech by signing up for Complete Spring Core or Complete Spring Web at Intertech.


Posted by: Jim White
Posted on: 3/29/2010 at 12:34 PM
Tags: ,
Categories: Java | Web Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed