I decided to follow up on my previous post and write a series of more practical articles to illustrate various decisions that are specific to mobile enterprise applications. Being is Microsoft platform developer, I am going to stick to Windows Phone 7 in this series. This first blog post discusses general architectural issues.
Choosing Client Technology
WinPhone 7 supports two development paradigms: Silverlight and XNA. The latter targets game developers, providing them with game loop, sprites, and stuff like that. Silverlight, on the other hand, is a subset of the traditional desktop UI platform (WPF). It has a rich set of controls plus the ability to do cool visual effects. Silverlight is a natural choice for a mobile enterprise application.
Relative Merits of MVVM
Model-View-ViewModel design pattern has a widespread adoption in the XAML world, including Silverlight. The question isn't whether or not MVVM can be used in WinPhone 7 applications (it can) but whether or not it should be used. On the negative side, MVVM makes your app larger and slower, which is no small thing on the mobile device. On the positive side, it provides the separation between user interface and logic which is extremely beneficial in two scenarios: unit testing and sharing projects with a designer.
Unit Testing
Generally, I am a big proponent of unit testing - I believe they are essential to building high-quality maintainable programs. However, WinPhone 7 unit testing is a little wobbly at the moment. Test framework built into Visual Studio doesn't support phone applications, so we are supposed to download Silverlight Unit Test framework, which is included into Silverlight Toolkit. Only problem is that latest version of the toolkit supports Silverlight 4, but not WinPhone 7... I'm sure eventually Microsoft will sort everything out, but for the time being it's probably best not to concentrate on unit tests.
Sharing Projects With Designer
If your project team has a dedicated designer who actually works with the same project as developers, MVVM provides a nice clean separation of concerns. If, on the other hand, you do not have a designer, or the one you have prefers exchanging images and screenshots with you over email, MVVM doesn't really give you much of an edge.
Choosing Server Technology
We should try to shift as much logic as possible to the server. This makes sense from several points of view. First of all, mobile client doesn't offer a lot of processing power while server side can be very scalable. Second, if you support more than one client platform, it helps to have as little code to port as possible. Third, your business logic is your intellectual property, and it is definitely more secure on the server.
SOAP or REST?
When it comes to building web services, WCF allows the choice between SOAP and REST. On the high level, SOAP is really a remote procedure call mechanism which can support sophisticated logic and advanced security requirements. REST, on the other hand, operates with a simple set of HTTP verbs and is therefore better suited for simpler CRUD-type logic.
Secure Communication
Mobile clients communicate with web services over 3G or WiFi networks, which makes them vulnerable to security attacks (open public WiFi are especially fertile ground for packet sniffing - read more here). It is therefore essential to encrypt all messages, not just those related to authentication. Using SSL protocol for communication is a good start.
(to be continued)
Showing posts with label Architecture. Show all posts
Showing posts with label Architecture. Show all posts
Wednesday, November 10, 2010
Monday, March 29, 2010
Passing Parameters To ClickOnce Applications
I was doing some research with ClickOnce deployment architecture and found an unexpected challenge: passing command line parameters. This post summarizes a couple of different approaches; hopefully, it will save someone a few hours of trial and error and frantic googling.
Use Query String
ClickOnce applications can be installed from a website, and they can also be invoked from a webpage. All that's needed is a hyperlink that references the .application file, e.g.: http://www.mywebsite.com/foobar/foobar.application. When user clicks the link, Foobar will launch (actually, the same link will install Foobar on user machine). In this scenario, parameters can be passed to the application by adding query string to the URL: http://www.mysite.com/foobar/foobar.application?param1=value1¶m2=value2&... . Here's how to do it:
Step 1: Enable URL parameters in ClickOnce application
Open project properties in Visual Studio and click "Publish" tab. Then click "Options" button, which brings up a dialog window. Select "Manifests" from the list, and make sure the checkbox that reads "Allow URL parameters to be passed to application" is checked.
Step 2: Add code to process parameters
In regular Windows applications written in C#, it is enough to declare static void Main(string[] args) in order to get the list of command line parameters in the args array. Unfortunately, this doesn't work with ClickOnce applications - the args array will be empty whether or not URL had any parameters. In order to access them, we need to analyze AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData property.
[STAThread]
static void Main()
{Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);var args = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
var frm = new MainForm();if (args != null
&& args.ActivationData != null&& args.ActivationData.Length > 0)
{ var url = new Uri(args.ActivationData[0], UriKind.Absolute);var parameters = HttpUtility.ParseQueryString(url.Query);
// Process parameters here}
Application.Run(frm);
}
Add File Type Association
Another interesting approach is to associate the application with a specific file extension. When a file with this extension is downloaded from a web page or opened in Windows Explorer, application will be launched automatically and file name will be passed to it. Prior SP1 release of .NET 3.5, file type association had to be created programmatically (by creating subkeys for the desired extension and a shell\open\command using Microsoft.Win32.Registry API). Visual Studio 2008 SP1 allows to define association declaratively. In the same Options dialog mentioned above, click "File Associations" and fill in required information in the data grid.
Processing logic is very similar to the first scenario - we still need to analyzeAppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationDataproperty. The only difference is that instead of calling HttpUtility.ParseQueryString, we need to extract file name from it.
Saturday, September 26, 2009
Two Strategies For Asynchronous Message Processing
Asynchronous Message Processing
Asynchronous message processing is a common pattern in designing highly available web applications. Essentially, it means that certain tasks are not processed immediately within the scope of a HTTP request. Instead, they are handled asynchronously, by a different application unit, which in Microsoft realm is often (but not always) implemented as a Windows service. This helps streamline the web application and make it appear faster to the end user.There is a special class of tasks that are suitable for asynchronous message processing, and it is different from typical scheduled jobs (also executed by a separate application service). Usually, they are closely related to user interactions with the main web application, but are too process-expensive or slow to be incorporated into the page processing workflow. Dynamic rendering of a multi-page PDF report is a good example since it falls under both categories. Sometimes, the tasks are not necessarily slow, but they do not produce any information for the user, for example keeping an audit trail of user activity within the system.
Regardless of the specific task being "outsourced", web application exchanges information with the processing service using discrete messages. In a typical design, messages flow only one way: from web application to the service (although there are scenarios where two-way dialog is preferable). There are two main strategies for implementing this design, MSMQ and SQL Server Service Broker.
Technologies
Although I remember the days when you had to buy 3rd party applications (like IBM MQSeries) if you wanted message queuing functionality, Microsoft has incorporated MSMQ 1.0 into Windows NT back in 1994. Fifteen years later, we are now at version 4, and MSMQ is considered to be a proven messaging platform. Even the advent of Windows Communication Foundation did not make it obsolete, since WCF includes special MSMQ binding. Service Broker is a much more recent addition to Microsoft tools lineup; it debuted with SQL Server 2005 and was updated in SQL Server 2008.
Message Size And Content Validation
MSMQ uses special memory-mapped files to store messages, while Service Broker relies on SQL Server database engine for storage. Message size limit is 4Mb and 2048Mb, respectively (Service Broker uses varbinary(max) data type to store messages). When it comes to describing the content of the message, MSMQ offers 18 "Body Type" values, such as integer, double, date, ANSI or Unicode strings, etc. but this information is optional: MSMQ doesn't validate message contents. Service Broker, on another hand, has just 3: empty, XML, and XML with schema, but it does validate the contents and rejects messages that don't conform.
Queue-Server Affinity
When developing high-performance MSMQ applications, one important best practice is "send remotely, receive locally" (here is a link to the article that explains it). What this means is that the process reading from the queue has to exist on the same machine where the queue is located. This impacts overall system scalability, because it makes adding additional processing servers more difficult.
Service Broker doesn't have such limitations, although it does require an instance of SQL Server database engine. In enterprise applications, it is generally a good idea to use a dedicated instance and host all message queues there. Applications that send and receive messages will use this instance as a global hub; they can be physically located on different servers.
Programmability
There are a number of ways to develop MSMQ applications: you can use native API, COM, or .NET. Programmers can use literally any language, from VB to C# to C++. Service Broker is less accessible: its main language is Transact-SQL and in order to use it in, say, a .NET application, you will need to write an ADO.NET wrapper. SQL Server programming samples include one such wrapper, Microsoft.SqlServer.Broker.dll, which exposes classes like SsbService and SsbMessage that shield developers from Transact-SQL.
Tuesday, July 14, 2009
Exposing EntLib to COM Clients
All of us (well, most of us) know and appreciate the benefits of Enterprise Library (EntLib) Application Blocks: they solve common problems, encapsulate best practices, implement design patterns. They are easy to use and not hard to extend. What's even better, they ensure consistency across different applications and development teams.
Sadly, but all this goodness is only available to .NET code.
I do not have exact statistics, but anecdotal evidence suggests that even software companies firmly committed to .NET platform still have 25-50% of their codebase in C++, VB 6, or some form of VBScript. The ratio will continue to shift but legacy code is unlikely to disappear anytime soon (after all, mainframes and COBOL are still with us). And of course, all that code needs to be maintained.
Programmers are rarely enthusiastic about legacy code maintenance. Part of the reason is that such code is often a reverse of EntLib: it doesn't encapsulate best practices, doesn't use design patterns, is difficult to use. Yet, we cannot afford to rewrite the whole thing and have to be content just patching holes. Therefore, I think many will welcome the possibility to somehow plug in Application Blocks into their legacy code. Parts of EntLib aren't useful in the non-.NET world, of course, but things like logging, caching, and cryptography are perfect integration points.
In the remaining part of this post, I will describe how this can be done and will use Logging Application Block as an example.
COM Facade
There are many different ways to expose EntLib functionality to older applications, but COM Interop is probably the most efficient. The idea is to use a "facade" design pattern: create a .NET class that will be exposed to COM clients via Interop and pass through calls to EntLib.
I decided to derive this new facade from System.EnterpriseServices.ServicedComponent and host it in a COM+ server application. This way we can take advantage of a couple of very useful services provided by COM+ infrastructure.
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class EntLibAdapter : ServicedComponent, IEntLibAdapter
Interface IEntLibAdapter contains a single method:
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IEntLibAdapter
{
void WriteLog(ref ILogData log, string category, int priority);
}
Here, ILogData is a name of another interface that defines multiple properties collected for logging. Our COM clients will invoke WriteLog method of the facade class and Logging Application Block will determine whether to log or not (based on category and priority), and which logging trace listener to use. This, however, requires that Application Block be properly initialized.
Initialization
EntLib application blocks rely on XML configuration which is usually stored in the web.config or exe.config file. In our scenario, entry point is not a .NET application, so we cannot rely on default behavior. Fortunately, EntLib supports multiple configuration sources: for example, it can consume a stand-alone file and read XML configuration from it. Here is how this is achieved for Logging Application block:
FileConfigurationSource configSrc = new FileConfigurationSource(fileName);
LogWriterFactory factory = new LogWriterFactory(configSrc);
this.LogWriter = factory.Create();
Because the facade class is a ServicedComponent, we can take advantage of the COM+ Activation service. When object is created, COM+ will invoke Construct method and pass a string that in our case will contain full path to the configuration file:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ConstructionEnabled(true, Default = @"C:\EntLibAdapter.config")]
public class EntLibAdapter : ServicedComponent, IEntLibAdapter
{
protected override void Construct(string s)
{
if (File.Exists(s))
{
FileConfigurationSource configSrc = new FileConfigurationSource(s);
LogWriterFactory factory = new LogWriterFactory(configSrc);
this.LogWriter = factory.Create();
}
}
}
Object Pooling
In a typical usage scenario, EntLibAdapter object will be constructed, WriteLog method invoked, and then the object will be destroyed. Notice that the initialization step is fairly expensive - it involves reading a file from disk, parsing XML, building up objects. We can improve performance and increase overall system scalability by maintaining a pool of objects. That way EntLibAdater instances do not get destroyed after client releases the reference - they simply go back to the pool. Object pooling is another built-in service in COM+, so all we need to do is mark our class to participate:
[
ComVisible(true),
ClassInterface(ClassInterfaceType.None),
ConstructionEnabled(true, Default = @"C:\Nexsure\Installation\Dlls\EntLibAdapter.config"),
EventTrackingEnabled(true),
ObjectPooling(true, MinPoolSize = 5)
]
public class EntLibAdapter : ServicedComponent, IEntLibAdapter
Object pooling may not be the best approach if you plan to use flat file logging. In the example above, there will always be 5 instances in the pool, and each will create its own log file (4 of them will have a GUID-based file name). This should not be a problem if your primary target is database or Windows Event Log.
Deployment
Since EntLibAdapter is a ServicedComponent, it has to be strongly named and registered using RegSvcs.exe. In addition, EntLib assemblies that it depends on, such as Microsoft.Practices.EnterpriseLibrary.Logging.dll, need to be placed in the GAC.
Sunday, January 25, 2009
Cloud Storage or SDS?
Ever since Ray Ozzie has announced Windows Azure on last year's PDC (watch the keynote) there's been a lot of buzz about new platform. Every recent Microsoft event, it seems, included a session or two on Azure. SoCal Code Camp that took place this past weekend at CalState Fullerton had an entire track of cloud-related presentations.

One general observation: details of the new platform are still, well, cloudy. Windows Azure is presently in a CTP stage; nobody expects an RTM until the end of 2009. There are a lot of technology-, process-, and cost-related questions that no one yet knows the answers to. What's worse, marketing geniuses at Microsoft decided to slap Azure label on a set of technologies that originated in different parts of the company (and even Microsoft evangelists admit that there is very little coordination).
Take a look at the obligatory Azure platform stack slide:

My initial assumption about SQL Server Data Services (SDS) was that it is somehow built on top of Azure. Apparently, SDS is a completely separate service. In fact, you don't even need to have an Azure application in order to use it.
Let's take a closer look at the data support for cloud applications. This is, in my opinion, the biggest paradigm shift for developers and architects. After all, it's easy to understand the concept of deploying your application code to a whole bunch of virtual servers, but how are we going to survive without our beloved connection strings, stored procedures, triggers?
There are two options available to us, cloud storage and SDS. Both are going to be reliable, scalable, highly available, and support terabytes of data. On the back end, both will utilize a vast network of SQL Server nodes that use some advanced algorithms to support distributed data storage and replication. Below is a side-by-side comparison.
Signup. When you sign up for Azure, you receive a separate storage account. To use SDS you will need to get yet another account.
Hierarchy
Cloud Storage: Provides account/container/entity model for your data.
SDS: The model is similar - authority/container/entity
Data Abstractions
Cloud Storage: Supports blobs (basically, named files with metadata) up to 50Gb, tables (which are essentially lists of entities, not database tables), and queues with message size up to 8Kb.
SDS: Only works with entities, which are similar to the tables above.
Data Access
Cloud Storage: Blobs and queues can be accessed via REST, but tables are also exposed via ADO.NET Data Services. This allows for a more convenient API (for example, you can query a table using LINQ). Large blobs can be uploaded by small 4Mb-sized chunks.
SDS: Entities can be queried using REST. Although there is no ADO.NET Data Services support, you can pass a LINQ-style query in the HTTP request (query may even join entities).
*** UPDATE (March 17, 2009)
Someone at Microsoft have finally noticed the striking similarities between Cloud Storage and SDS. Data Platform Insider blog is announcing the change to SDS architecture: REST-based interface will be decommissioned and replaced by a service protocol based on Tabular Data Stream (which has been a SQL Server network protocol since SQL 2000). Public CTP of the new architecture will be available in the middle of this year.
Tuesday, May 01, 2007
Integrating Services on User's Desktop
.NET architects, including myself, enjoy talking about services, service-orientation, and enterprise service bus. Our emphasis is clearly on the server side. Although that is indeed very important and extremely interesting, we tend to forget that people (whom we contemptuously call "users") are mostly interested in client-side systems. These systems are predominantly intranet-based, and their sole purpose - contrary to that of their client-server predecessors - is to invoke services. Services implement core business logic for applications that range from human resources to inventory management and from accounting to business operations control. So, when we implement SOA in our enterprises, what options do we give to users?
At the very high level, there are two principal choices for user interface: web application and windows forms (winforms) applications - thin and thick clients, respectively. Until recently, web applications were the clear winners when it came to integrating services on a desktop. Obvious advantages such as small footprint and ease of deployment gave them an edge over winforms.
Then in December 2005 Microsoft Patterns & Practices group has released a Composite User Interface application block followed by Smart Client Software Factory in June 2006. Composite UI application block is a framework for building complex, event-driven, and modular winforms applications efficiently. Smart Client software factory builds on top of it, adding proven design patterns, Visual Studio automation and extensive reference implementation. These releases, combined with ClickOnce deployment subsystem in .NET 2.0, have dramatically changed the landscape for desktop services integration. I am going to compare Smart Client architecture with web applications from that angle.
Modularity.
One of the key benefits of Smart Client applications is their inherent modularity. Classic winforms programs consist of numerous forms and ASP.NET consists of numerous web pages. In Smart Client, there is a single shell form and multiple modules. UI elements are part of the module; they are created using Model-View-Presenter design pattern. From the service integration perspective, it is beneficial to use plug-in modules for different service groups.
Data Exchange.
Lack of attention to client systems usually results in proliferation of single-use applications. Users need to constantly switch from one web application to another, or from web to winform and back. Not only this is confusing, but it may also be counterproductive, because there is typically no automated way to exchange data between systems and users have to resort to copy-paste technique. Smart Client applications have built-in capability to exchange data and events between objects.
UI Consistency.
Multitude of client applications (no matter web or winform) which are produced by different development teams makes it very difficult to maintain UI consistency. On the other hand, modular approach of Smart Client allows engineering teams to work independently on a single solution, thus reusing code and applying consistent UI.
UI Quality.
Having spent many years developing web applications, I am convinced that the quality of their user interface will never measure up to that of windows applications. Sure, ASP.NET 2.0 has many improvements, but it is the underlying platform that has problems. HTML was not designed for UI rendering, although this has been somewhat improved with CSS. Add a requirement to support different web browsers (with their different user settings), and we end up with a lowest common denominator. Naturally, there are third party UI libraries for ASP.NET but they are a) expensive and b) usually available for winforms as well.
Web Server Considerations.
SOA must be designed and deployed with optimal balance between scalability and performance. When we develop client-side system as a web application, we are essentially adding another service to our environment. Yet, its design is rarely as rigorous as the design of main services. As a result, users of the application may experience problems caused by poor server-side design. Smart Client, by contrast, doesn't rely on any other services except main SOA.
Security.
Web applications built using ASP.NET 2.0 have at their disposal such security features as membership and role providers, security controls. These are typically linked to a custom database schema. Smart Client applications have built-in authorization mechanisms: for example, it is possible to limit access to a module, command, or view by user role. No dedicated database is needed since we can get membership information for the current security principal from the organization's Active Directory. By combining multiple modules into a unified application, we are in effect providing a single-sign-on functionality.
Deployment.
Anyone who had deployed .MSI packages or setup CDs to even a small number of users will tell you that ease of deployment is the biggest benefit of web applications. Indeed, once you post updated code to the web server, there is nothing more to do: next time user accesses the web site, he or she will execute the latest version of the application. ClickOnce technology, which has debuted in 2.0 version of .NET framework, brings similar experience to the world of winforms systems. ClickOnce has several deployment patterns: for example, it allows applications to be published to a file share or URL. If we choose the online-only mode, users will have to launch the program from that location (this is very similar to web applications). However, we may allow application to be available offline. This way, the binaries will be downloaded to user's computer and program title will appear in Start menu and Control Panel. Every time the application is launched, it will check for updates and prompt user to download latest code if available.
Hopefully, I managed to convince you that Smart Client applications are a viable alternative to web when it comes to integrating services on user's desktop. The only way to find out if the technology is a match for your specific requirements, is to give it a try.
Good luck!
At the very high level, there are two principal choices for user interface: web application and windows forms (winforms) applications - thin and thick clients, respectively. Until recently, web applications were the clear winners when it came to integrating services on a desktop. Obvious advantages such as small footprint and ease of deployment gave them an edge over winforms.
Then in December 2005 Microsoft Patterns & Practices group has released a Composite User Interface application block followed by Smart Client Software Factory in June 2006. Composite UI application block is a framework for building complex, event-driven, and modular winforms applications efficiently. Smart Client software factory builds on top of it, adding proven design patterns, Visual Studio automation and extensive reference implementation. These releases, combined with ClickOnce deployment subsystem in .NET 2.0, have dramatically changed the landscape for desktop services integration. I am going to compare Smart Client architecture with web applications from that angle.
Modularity.
One of the key benefits of Smart Client applications is their inherent modularity. Classic winforms programs consist of numerous forms and ASP.NET consists of numerous web pages. In Smart Client, there is a single shell form and multiple modules. UI elements are part of the module; they are created using Model-View-Presenter design pattern. From the service integration perspective, it is beneficial to use plug-in modules for different service groups.
Data Exchange.
Lack of attention to client systems usually results in proliferation of single-use applications. Users need to constantly switch from one web application to another, or from web to winform and back. Not only this is confusing, but it may also be counterproductive, because there is typically no automated way to exchange data between systems and users have to resort to copy-paste technique. Smart Client applications have built-in capability to exchange data and events between objects.
UI Consistency.
Multitude of client applications (no matter web or winform) which are produced by different development teams makes it very difficult to maintain UI consistency. On the other hand, modular approach of Smart Client allows engineering teams to work independently on a single solution, thus reusing code and applying consistent UI.
UI Quality.
Having spent many years developing web applications, I am convinced that the quality of their user interface will never measure up to that of windows applications. Sure, ASP.NET 2.0 has many improvements, but it is the underlying platform that has problems. HTML was not designed for UI rendering, although this has been somewhat improved with CSS. Add a requirement to support different web browsers (with their different user settings), and we end up with a lowest common denominator. Naturally, there are third party UI libraries for ASP.NET but they are a) expensive and b) usually available for winforms as well.
Web Server Considerations.
SOA must be designed and deployed with optimal balance between scalability and performance. When we develop client-side system as a web application, we are essentially adding another service to our environment. Yet, its design is rarely as rigorous as the design of main services. As a result, users of the application may experience problems caused by poor server-side design. Smart Client, by contrast, doesn't rely on any other services except main SOA.
Security.
Web applications built using ASP.NET 2.0 have at their disposal such security features as membership and role providers, security controls. These are typically linked to a custom database schema. Smart Client applications have built-in authorization mechanisms: for example, it is possible to limit access to a module, command, or view by user role. No dedicated database is needed since we can get membership information for the current security principal from the organization's Active Directory. By combining multiple modules into a unified application, we are in effect providing a single-sign-on functionality.
Deployment.
Anyone who had deployed .MSI packages or setup CDs to even a small number of users will tell you that ease of deployment is the biggest benefit of web applications. Indeed, once you post updated code to the web server, there is nothing more to do: next time user accesses the web site, he or she will execute the latest version of the application. ClickOnce technology, which has debuted in 2.0 version of .NET framework, brings similar experience to the world of winforms systems. ClickOnce has several deployment patterns: for example, it allows applications to be published to a file share or URL. If we choose the online-only mode, users will have to launch the program from that location (this is very similar to web applications). However, we may allow application to be available offline. This way, the binaries will be downloaded to user's computer and program title will appear in Start menu and Control Panel. Every time the application is launched, it will check for updates and prompt user to download latest code if available.
Hopefully, I managed to convince you that Smart Client applications are a viable alternative to web when it comes to integrating services on user's desktop. The only way to find out if the technology is a match for your specific requirements, is to give it a try.
Good luck!
Monday, February 19, 2007
Design For Operations (Part II)
Last time I made a mistake by including words "Part I" in the title of my post. The plan was to write part II right away, and of course, it took me two months to get to it. I bet if I didn't call it "Part I", I would have posted this essay before Christmas ;-)
So, my goal is to make the application more accessible to the people who actually have to maintain production servers. WMI is great for this particular purpose, because it is a standard mechanism for accessing many system components at run-time: disk drives, Windows services, message queues, etc.
1. Publishing to WMI
If I design my application as a WMI provider, it will be able to publish information to WMI infrastructure built into Windows system. Application status information is represented by instances and events. Windows WMI infrastructure will ensure that any client that has proper permissions can query this data, subscribe to events, etc. All I need to do is define classes that will be published and decorate them with InstrumentationClassAttribute.
Publishing data is extremely simple:
2. Registering WMI Namespace
Now let's take a step back. In order to make above code functional, I need to register WMI namespace for my application. This is done using ManagementInstaller class, but first, I have to decorate the assembly with a special attribute:
ManagementInstaller is trivial: it just needs to be added to the Installers collection of my application's Installer class:
Now, after I build the application, I can register WMI namespace simply by running "installutil" command against assembly name.
3. Developing WMI Client
Chances are, operations team will ask me to write a WMI client for my provider. No problem, .NET framework has all the tools to get to my application's published data. One approach is to write a query using a SQL-like syntax and execute it using WqlObjectQuery class. Another relies on the ManagementClass object:
In both cases, I will get back a collection of ManagementObject instances. Although I can extract all the data I want from ManagementObject using field names (e.g., obj["ProcessName"]), I would rather have a strongly typed class to work with. Turns out, there is a .NET tool called "mgmtclassgen" that does exactly that - generates a strongly typed class wrapper for any WMI instance type.
WMI is a complex subject, and I realize that I barely scratched the surface in this post. Still, there is enough information to get you started. Good luck!
So, my goal is to make the application more accessible to the people who actually have to maintain production servers. WMI is great for this particular purpose, because it is a standard mechanism for accessing many system components at run-time: disk drives, Windows services, message queues, etc.
1. Publishing to WMI
If I design my application as a WMI provider, it will be able to publish information to WMI infrastructure built into Windows system. Application status information is represented by instances and events. Windows WMI infrastructure will ensure that any client that has proper permissions can query this data, subscribe to events, etc. All I need to do is define classes that will be published and decorate them with InstrumentationClassAttribute.
[InstrumentationClass(InstrumentationType.Instance)]
public class MyInstance
{
public MyInstance() {}
public string ProcessName;
public string Description;
public string ProcessType;
public string Status;
}
[InstrumentationClass(InstrumentationType.Event)]
public class MyTerminationEvent
{
public MyTerminationEvent() {}
public string ProcessName;
public string TerminationReason;
}
Publishing data is extremely simple:
using System.Management.Instrumentation;
...
MyInstance myInstance = new MyInstance();
MyTerminationEvent myEvent = new MyTerminationEvent();
// Set field values...
Instrumentation.Publish(myInstance);
Instrumentation.Fire(myEvent);
2. Registering WMI Namespace
Now let's take a step back. In order to make above code functional, I need to register WMI namespace for my application. This is done using ManagementInstaller class, but first, I have to decorate the assembly with a special attribute:
[assembly: Instrumented(@"root\MyCompanyName\MyNamespace")]
ManagementInstaller is trivial: it just needs to be added to the Installers collection of my application's Installer class:
[RunInstaller(true)]
public partial class MyAppInstaller : Installer
{
private ManagementInstaller managementInstaller;
public MyAppInstaller()
{
InitializeComponent();
managementInstaller = new ManagementInstaller();
Installers.Add(managementInstaller);
}
}
Now, after I build the application, I can register WMI namespace simply by running "installutil" command against assembly name.
3. Developing WMI Client
Chances are, operations team will ask me to write a WMI client for my provider. No problem, .NET framework has all the tools to get to my application's published data. One approach is to write a query using a SQL-like syntax and execute it using WqlObjectQuery class. Another relies on the ManagementClass object:
ObjectGetOptions options = new ObjectGetOptions(null, new TimeSpan(0, 0, 30), true);
ManagementClass wmiClass = new ManagementClass(WmiScope, "MyInstance", options);
ManagementObjectCollection wmiInstances = wmiClass.GetInstances();
In both cases, I will get back a collection of ManagementObject instances. Although I can extract all the data I want from ManagementObject using field names (e.g., obj["ProcessName"]), I would rather have a strongly typed class to work with. Turns out, there is a .NET tool called "mgmtclassgen" that does exactly that - generates a strongly typed class wrapper for any WMI instance type.
***
WMI is a complex subject, and I realize that I barely scratched the surface in this post. Still, there is enough information to get you started. Good luck!
Monday, December 11, 2006
Design For Operations (Part I)
When I design an enterprise application, I need to realize one simple truth: the system is going to spend just 15% (or less) of its life in development environment. After that it moves to the gated community known as production, and the only people who are supposed to have access to production are system operations engineers, a.k.a. “IT guys”. And of course, I cannot assume that IT guys will become familiar with the intricacies of the application’s design. If I do, I would be making a grave mistake which results in those dreaded 4:50 PM or 2:30 AM phone calls from the NOC.
So, I really need to design the system with operations in mind. It should be able to report its status and notify about any issues. I should allow operations to monitor my system with their usual tools, such as event viewer, performance monitor, management console, or MOM, instead of running SQL queries and reviewing XML configuration files. This means instrumenting my application with event logs, performance counters, and WMI objects and events.
Event Logging. Although simple file log is very convenient to put all sorts of debugging and profiling information, I can’t really expect IT to dig through megabytes of text looking for error information. Instead, they should be able to get it from Windows Event Viewer. So, I will create an instance of EventLogInstaller in the application’s installer class and specify the Source and Log properties. I will make sure to log all unhandled exceptions (see my previous post) using EventLog.WriteEntry method.
Performance counters are invaluable tools for monitoring and profiling the system in production. They may also give early indication of system issues. Windows and .NET framework already contain dozens of performance counters, but custom counters can provide an insight into my application’s processing logic. So, exactly kind of information should I expose via performance counters and what kind of counters (instantaneous or average) I should use? There is no standard answer; it really depends on the nature of the system. There is a good introduction to the concept on MSDN. In order to register custom performance counters I usually create a custom installer:
In the next post I will discuss using WMI to publish application status information.
So, I really need to design the system with operations in mind. It should be able to report its status and notify about any issues. I should allow operations to monitor my system with their usual tools, such as event viewer, performance monitor, management console, or MOM, instead of running SQL queries and reviewing XML configuration files. This means instrumenting my application with event logs, performance counters, and WMI objects and events.
Event Logging. Although simple file log is very convenient to put all sorts of debugging and profiling information, I can’t really expect IT to dig through megabytes of text looking for error information. Instead, they should be able to get it from Windows Event Viewer. So, I will create an instance of EventLogInstaller in the application’s installer class and specify the Source and Log properties. I will make sure to log all unhandled exceptions (see my previous post) using EventLog.WriteEntry method.
Performance counters are invaluable tools for monitoring and profiling the system in production. They may also give early indication of system issues. Windows and .NET framework already contain dozens of performance counters, but custom counters can provide an insight into my application’s processing logic. So, exactly kind of information should I expose via performance counters and what kind of counters (instantaneous or average) I should use? There is no standard answer; it really depends on the nature of the system. There is a good introduction to the concept on MSDN. In order to register custom performance counters I usually create a custom installer:
public class PerformanceCountersInstaller : Installer
{
public const String CategoryName = "...";
public const String CategoryHelp = "...";
public const String CounterName = "...";
public const String CounterHelp = "...";
public override void Install(IDictionary state)
{
base.Install(state);
Context.LogMessage("Installing performance counters...");
SetupPerformanceCounters();
}
public override void Uninstall(IDictionary state)
{
Context.LogMessage("Uninstalling performance counters...");
if (PerformanceCounterCategory.Exists(CategoryName))
PerformanceCounterCategory.Delete(CategoryName);
Context.LogMessage("Successfully uninstalled performance counters");
base.Uninstall(state);
}
private void SetupPerformanceCounters()
{
try
{
if (PerformanceCounterCategory.Exists(CategoryName))
PerformanceCounterCategory.Delete(CategoryName);
CounterCreationDataCollection CCDC = new CounterCreationDataCollection();
// Create and add the counters
CounterCreationData ccd;
ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.CounterDelta32;
ccd.CounterName = CounterName;
ccd.CounterHelp = CounterHelp;
CCDC.Add(ccd);
// Create the category.
PerformanceCounterCategory.Create(CategoryName,
CategoryHelp,
PerformanceCounterCategoryType.SingleInstance,
CCDC);
Context.LogMessage("Successfully installed performance counters");
}
catch (Exception ex)
{
Context.LogMessage(String.Concat("Could not install performance counters", ex.Message));
}
}
}
In the next post I will discuss using WMI to publish application status information.
Friday, September 15, 2006
Business Objects and Value Objects
Encapsulation of data and behavior is one of the cornerstones of object-oriented programming. This basically means that a business object contains both the data and methods that manipulate the data. In the example below, a CreditCard object contains public method Authorize and public property AuthorizationCode. It's important for the object to establish a proper public interface. Authorization code value is returned by the payment processor; we wouldn't want clients to accidentally modify it. Therefore, I exposed a read-only property rather than a field.
public CreditCard
{
...
private string _AuthorizationCode;
public string AuthorizationCode
{
get { return _Authorizationcode; }
}
public bool Authorize(double amount) {...}
...
}
Object-oriented approach is great - within a single application tier. When designing a distributed application, we need to take other factors into consideration. Suppose, my application needs to display customer credit card data on a web page. Should I pass the CreditCard object to the web tier? Sure, it is possible, but the web tier only needs credit card data, not the behavior. Frankly, I wouldn't want web tier code to accidentally call Authorize() method. So, for the sake of security, we should somehow limit the objects. Performance is another concern, especially when passing objects between physical tiers. Regardless of which remote technology we use - web services, .NET Remoting, or COM+ - large objects with lots of methods and properties may not be ideal for this.
A simple and elegant solution is to combine essential business object data into a "value object". Individual data elements of the value object are exposed to business object's clients via public properties. Revised CreditCard class below demonstrates this approach. Note how overload of the constructor allows us to easily create a business object from a value object. We can extract value object just as easily and send it to another application tier.
public CreditCard
{
...
private CreditCardInfo _CCInfo;
public CreditCardInfo CCInfo
{
get { return _CCInfo; }
}
public CreditCard(CreditCardInfo info)
{
_CCInfo = info;
}
public string AuthorizationCode
{
get { return _CCInfo.Authorizationcode; }
}
public bool Authorize(double amount) {...}
...
}
public CreditCardInfo
{
...
public string CardNumber;
public DateTime ExpDate;
public string Authorizationcode;
public DateTime? LastTransactionDate;
...
}
public CreditCard
{
...
private string _AuthorizationCode;
public string AuthorizationCode
{
get { return _Authorizationcode; }
}
public bool Authorize(double amount) {...}
...
}
Object-oriented approach is great - within a single application tier. When designing a distributed application, we need to take other factors into consideration. Suppose, my application needs to display customer credit card data on a web page. Should I pass the CreditCard object to the web tier? Sure, it is possible, but the web tier only needs credit card data, not the behavior. Frankly, I wouldn't want web tier code to accidentally call Authorize() method. So, for the sake of security, we should somehow limit the objects. Performance is another concern, especially when passing objects between physical tiers. Regardless of which remote technology we use - web services, .NET Remoting, or COM+ - large objects with lots of methods and properties may not be ideal for this.
A simple and elegant solution is to combine essential business object data into a "value object". Individual data elements of the value object are exposed to business object's clients via public properties. Revised CreditCard class below demonstrates this approach. Note how overload of the constructor allows us to easily create a business object from a value object. We can extract value object just as easily and send it to another application tier.
public CreditCard
{
...
private CreditCardInfo _CCInfo;
public CreditCardInfo CCInfo
{
get { return _CCInfo; }
}
public CreditCard(CreditCardInfo info)
{
_CCInfo = info;
}
public string AuthorizationCode
{
get { return _CCInfo.Authorizationcode; }
}
public bool Authorize(double amount) {...}
...
}
public CreditCardInfo
{
...
public string CardNumber;
public DateTime ExpDate;
public string Authorizationcode;
public DateTime? LastTransactionDate;
...
}
Saturday, September 02, 2006
How Many Layers Is Enough?
A colleague recently asked my advise about the design of a web application he was working on. He showed me the draft: an elaborate architecture involving web application calling web service, which in turn invoked application server over .NET Remoting. The problem? This was an intranet application, with maximum number of concurrent users below 50. Had he implemented this original design, he would end up with an extremely scalable system which will never get a chance to realize its potential. On the other hand, the flip side of scalability - poor performance - will be obvious to any user.
So, how many layers is enough for an enterprise application? I am talking about physical layers, of course. With logical layers, approach is well-known: you would typically have data abstraction tier, business objects tier, and workflow tier. In addition, web application itself should be designed using Model-View-Presenter pattern .
With physical layers, it's far less straightforward. When we have all logical tiers running inside single application domain, we achieve best possible performance, because all calls are in-process. Once we place business and data tiers in a dedicated application server, we lose performance to out-of-process calls even if the application server is running on the same physical server. It really doesn't matter what specific remote calling mechanism we use: Web services, .NET Remoting, or Enterprise Services (COM+) - performance will suffer. When we move application server to a separate hardware, performance gets even worse because of network latency.
So why not run everything in-process? Well, many web application do just that - every web server in a farm has all logical tiers of the application. The downside is that web servers have to process both web application logic and business logic. This limits the number of HTTP requests each server could process and thus dramatically reduces system scalability. There are other drawbacks, too. Servers have to be really beefed up to handle the load, so hardware cost is high. Also, this deployment layout is inherently insecure: web servers are usually placed in a DMZ outside company firewall. Think of all the connection strings, encryption keys and other sensitive data that hacker could obtain by breaking into a web server.
By placing business and data tiers on separate physical layer (application server farm) we are trading performance to scalability. Web servers no longer have to process business logic, so they can handle much more page requests (and don't require high-end CPUs and tons of memory). Application servers can utilize connection pooling, object pooling and data caching in order to effectively support the web layer. Better yet, if we move from a homogenous app servers to more specialized "application services", we can improve performance even more by fine-tuning server configuration.
Coming back to the question I used as a title, there really isn't a universal rule. Number of physical layers can be different depending on scalability, performance, security, and other requirements of a particular application.
So, how many layers is enough for an enterprise application? I am talking about physical layers, of course. With logical layers, approach is well-known: you would typically have data abstraction tier, business objects tier, and workflow tier. In addition, web application itself should be designed using Model-View-Presenter pattern .
With physical layers, it's far less straightforward. When we have all logical tiers running inside single application domain, we achieve best possible performance, because all calls are in-process. Once we place business and data tiers in a dedicated application server, we lose performance to out-of-process calls even if the application server is running on the same physical server. It really doesn't matter what specific remote calling mechanism we use: Web services, .NET Remoting, or Enterprise Services (COM+) - performance will suffer. When we move application server to a separate hardware, performance gets even worse because of network latency.
So why not run everything in-process? Well, many web application do just that - every web server in a farm has all logical tiers of the application. The downside is that web servers have to process both web application logic and business logic. This limits the number of HTTP requests each server could process and thus dramatically reduces system scalability. There are other drawbacks, too. Servers have to be really beefed up to handle the load, so hardware cost is high. Also, this deployment layout is inherently insecure: web servers are usually placed in a DMZ outside company firewall. Think of all the connection strings, encryption keys and other sensitive data that hacker could obtain by breaking into a web server.
By placing business and data tiers on separate physical layer (application server farm) we are trading performance to scalability. Web servers no longer have to process business logic, so they can handle much more page requests (and don't require high-end CPUs and tons of memory). Application servers can utilize connection pooling, object pooling and data caching in order to effectively support the web layer. Better yet, if we move from a homogenous app servers to more specialized "application services", we can improve performance even more by fine-tuning server configuration.
Coming back to the question I used as a title, there really isn't a universal rule. Number of physical layers can be different depending on scalability, performance, security, and other requirements of a particular application.
Thursday, August 24, 2006
Caching in Distributed Applications
This is an overview of different approaches to caching in a distributed application environment. Distributed N-Tier applications generally have at least two server farms: web servers and application servers.
Web servers, of course, can cache entire HTTP responses, using, for example, ASP.NET OutputCache page directive. This is a blunt tool, though. It can result in high memory load and impact page processing logic. Sometimes it's not applicable at all. In these cases, application data - in form of objects - should be cached instead. Naturally, this is the only caching option for application servers.
Application data that we need to cache can be either static or dynamic. I'm not suggesting that static data doesn't change at all (otherwise we could just build it into the application), only that it changes very infrequently. Static data can be loaded into cache on every server (let's call it isolated cache). We get the benefit of fast reading, because data is always stored locally. On the other hand, it is heavily duplicated - every single server has to have a copy, which may be a waste of memory. Here's another drawback of isolated cache: imagine several servers joining the farm at the same time. How stressful it will be for the database server while they are filling up their respective isolated caches?
Caching dynamic data is much more complicated, because any server may need to modify it at any time. First thing that comes to mind is to use a common caching data store, such as a database or dedicated server (let's call it centralized cache). For example, ASP.NET allows you to have centralized data store for session state. Unfortunately, centralized mechanism always creates a single point of failure, so it may not be a good solution depending on your availability requirements. Another drawbacks of centralized cache are generally reduced performance and scalability.
A good alternative to centralized cache is distributed cache, which assumes some kind of communication and coordination among the servers. Distributed cache comes in two essential flavors: fully replicated and partitioned. In the fully replicated architecture once application puts an object into local cache on one server, it is immediately copied to all other servers in the cluster. The end result may look very similar to the isolated cache, but remember that isolated cache only works with static data. Still, as the server farm grows, it will take more and more time and memory to maintain fully replicated cache.
Enter partitioned cache. While "get" operation in the previous scenario was always local, getting data from partitioned cache could mean querying all servers in the cluster until one is found that holds the required object. "Put", on the other hand, is local. Partitioned architecture represents a trade-off: we utilize memory more efficiently and don't waste time replicating the data, but it may take longer to retrieve it.
Last but not least: tools. Enterprise Library from Microsoft is free and has Caching application block which unfortunately doesn't support distributed cache. Enterprise version of NCache from Alachisoft does support distributed cache but is far from being free.
Web servers, of course, can cache entire HTTP responses, using, for example, ASP.NET OutputCache page directive. This is a blunt tool, though. It can result in high memory load and impact page processing logic. Sometimes it's not applicable at all. In these cases, application data - in form of objects - should be cached instead. Naturally, this is the only caching option for application servers.
Application data that we need to cache can be either static or dynamic. I'm not suggesting that static data doesn't change at all (otherwise we could just build it into the application), only that it changes very infrequently. Static data can be loaded into cache on every server (let's call it isolated cache). We get the benefit of fast reading, because data is always stored locally. On the other hand, it is heavily duplicated - every single server has to have a copy, which may be a waste of memory. Here's another drawback of isolated cache: imagine several servers joining the farm at the same time. How stressful it will be for the database server while they are filling up their respective isolated caches?
Caching dynamic data is much more complicated, because any server may need to modify it at any time. First thing that comes to mind is to use a common caching data store, such as a database or dedicated server (let's call it centralized cache). For example, ASP.NET allows you to have centralized data store for session state. Unfortunately, centralized mechanism always creates a single point of failure, so it may not be a good solution depending on your availability requirements. Another drawbacks of centralized cache are generally reduced performance and scalability.
A good alternative to centralized cache is distributed cache, which assumes some kind of communication and coordination among the servers. Distributed cache comes in two essential flavors: fully replicated and partitioned. In the fully replicated architecture once application puts an object into local cache on one server, it is immediately copied to all other servers in the cluster. The end result may look very similar to the isolated cache, but remember that isolated cache only works with static data. Still, as the server farm grows, it will take more and more time and memory to maintain fully replicated cache.
Enter partitioned cache. While "get" operation in the previous scenario was always local, getting data from partitioned cache could mean querying all servers in the cluster until one is found that holds the required object. "Put", on the other hand, is local. Partitioned architecture represents a trade-off: we utilize memory more efficiently and don't waste time replicating the data, but it may take longer to retrieve it.
Last but not least: tools. Enterprise Library from Microsoft is free and has Caching application block which unfortunately doesn't support distributed cache. Enterprise version of NCache from Alachisoft does support distributed cache but is far from being free.
Subscribe to:
Posts (Atom)

