Web Applications in the age of Azure

Increasingly, I’ve found myself turning to Microsoft’s Azure platform for new web projects. The convenience of on-demand infrastructure, combined with a usage based payment model is compelling; but what makes Azure shine are the rapidly expanding set of supporting services available.

When you fist start writing Azure WebSites, you quickly run into complexities that are often unfamiliar to developers who only ever targeted on-prem IIS servers. You can’t rely on the local file-system, sites span multiple server instances, you have to ship dependencies along with your application’s code, and so on.

These issues aren’t new for those who develop for web-farm environments, but even the smallest Azure WebSite forces you to consider complexities of scale –issues that plagued only the largest of projects in the past.

Fortunately, Azure provides a complete set of services to address those complexities, and using them is fairly easy. Caching services handle shared session state between instances of your application. Azure storage substitutes for the local file system. Azure WebJobs handle background processing and scheduled tasks.

There are also services analogous to most of the common external dependencies; Azure Search, Azure DocumentDb, Azure SQL, Azure AD, etc. Some of these are so similar to their on-prem equivalents that using them is largely transparent, but most act more like a ultra-modern replacements for their older, on-prem cousins.

If you need a service Azure doesn’t offer directly, you can always spin up an Azure VM. The Azure Gallery has pre-built VMs for tons of common services, or you can roll out a standard Linux or Windows VM and install whatever third party software you need.

It took me a little time to learn my way around the Azure platform. At first, I resented the additional effort, especially in small projects. After the rather modest initial learning curve though, I have found that Azure provides far more than simple replacements for the same old services I’ve always used. They offer a lot of additional value that I’ve never had easy access to before.

Here is an example. The first time one of my Azure applications needed to handle user file uploads, I found it cumbersome to use Azure Storage. I had to provision a storage account, pull down the nuget packages, then configure my application to talk to it. It only took about 20 minutes the first time, but it seemed like a hassle compared to just calling into System.IO.

After getting it all hooked up though, I discovered that Azure storage wasn’t difficult to use, and it eliminated a lot of common problems. I no longer had to worry about mapping server paths, dealing with file and folder permissions, or file contention issues. It just works, and it scales without thought.

Still later, I came across the need to write information to a queue so a background process could act on it later. Normally I’d have to create a table in my database, or drop custom files on the file system to share information with the background process –or worse, deal with Microsoft Message Queues (I still have nightmares). After having setup Azure storage for the file uploads though, I also had access to Azure Storage Queues at my finger tips.

I had similar results when I had to setup a cache service for handling session state. It was a tad inconvenient, but when I needed to cache data I’d fetched from the SQL database, I already had a super-easy, super-fast, cloud-scale caching service right there waiting for me.

Sure, I can setup local servers and services that can do any of these things, but in Azure I don’t have to. These services are already there, all I have to do is turn them on.

It has gotten to the point where I really miss Azure whenever I’m working with on-prem applications. I wish IIS could run WebJobs, and that my local ADFS server supported OpenID Connect. I want a search server on-prem that doesn’t require voodoo-devil-magic to setup and maintain. Working outside of Azure has become an inconvenience.

TicketDesk 2.5 – Progress and Developer Notes

I wanted to give everyone an update on the progress of TicketDesk 2.5, and take a few minutes to explain the general architecture that’s starting to take shape over on the develop branch at CodePlex.

Projects and Architecture:

The Database supports any version of SQL Server 2008 or higher, including Azure SQL (but not compact edition). The design of TicketDesk would also fit a document database very well too, so TD may eventually end up having a RavenDB and/or Azure DocumentDB variant.

The Schema is managed by code-first migrations, with the execution of migrations handled by startup initializers and/or on-screen admin tools. It uses multi-tenant, code-first migrations. The identity and the business domains have separate contexts and models, each of which are tenants within the same DB. Similarly, search and email will be separate tenants too.

TicketDesk.Domain is the core business layer. It has no dependencies on web-specific frameworks, azure frameworks, or specific security providers. It does have a dependency on entity framework, and leverages EF as a full scale business service platform, not just as a data access technology.

I call this a “pervasive EF Domain model”. It’s a lot like most domain models you see described in any .net book or tutorial, but without unnecessary abstractions to hide the entity framework components.

The Entities directly contain their own business logic, while DbSets act as generic repositories. Custom repository functions are provided mostly through extension methods. Some extensions are defined in the domain assembly, while those with web specific dependencies are defined within the web application instead –which is why a DI framework or IoC container has’t been necessary within the domain project.

The DbContext is treated as the root business service, and it provides the unit-of-work pattern. Truly cross-cutting business logic will be handled directly by the DbContext, or through extension methods and helper services.

The application doesn’t need a formal DDD style design, but with search and email breaking out into separate services, the design is headed in that general direction. By the time TD 3 is complete, there will likely be a formal service bus mechanism handling communications between separate root business contexts, and this will drive a DDD style eventual consistency pattern.

The first parts of that design will appear in 2.5 with the queue mechanisms that support email and search. It likely will never adhere to the full DDD battery of principals and patterns, but it will borrow heavily from those designs where they make sense.

TicketDesk.Domain.Legacy exists only for conversion of TD2.1 databases… it’s just an isolated container for EF migrations and migration helpers. It has a completely custom initial migration that upgrades a TD 2.1x database to the starting TD 2.5 schema. After that, the regular TD 2.5 migrations from the main domain assembly will bring the database up to the final schema version.

TicketDesk.Search encapsulates all search related functionality. Currently it has local lucene and azure search providers. This could be decomposed into separate assemblies, but I haven’t seen the need yet to go that far with it yet.

Currently, it also fakes a “queue” based mechanism, but before TD 2.5 ships this will be replaced by a more formal queue management system.

TicketDesk.Identity encapsulates all non-web/owin specific security functionality. This is an odd one architecturally, since much of the overall identity system does need dependencies on owin middleware components. Right now, the core EF and aspnet.identity stuff is isolated here, but the web app layers on additional user and role managers.

Much of this is boilerplate identity code borrowed from stock samples, so as I refactor it for TD’s specific needs, I’m thinking seriously about moving all of the identity stuff to this assembly, and letting it have owin dependencies. I’m waiting until I tackle ADAL and/or OpenID Connect (for AD federated security) before I decide for sure, but I don’t want to go as far as to write a custom abstraction layer for this thing.

Either way, the identity stuff will remain decoupled from the business domain assembly entirely.

TicketDesk.Web.Client is the main web application. Nothing special about this design, except that it is an ultra-modern use of the latest MVC stack. It uses Owin/Katana, Aspnet.Idneity, and all the new toys like that.

It makes light use of the Dependency Resolver, with Simple Injector as the underlying DI service. The UI is written to bootstrap 3, with some light jQuery and custom javascript here and there. It does use the jquery unobtrusive ajax stuff for partial view rendering –a concession that makes it easier to port the old UI without having to completely re-invent the entire design.

Mail / WebJob: I haven’t implemented these yet, but email will be split out like search, and will use a DB queue table when running on-prem, and will use Azure Queue Storage when running on Azure. On Azure, mail delivery will be handled by Azure WebJobs.

What I’m working though now, or in the very near future:

Building out the rest of the core UI:

I’m working my way through porting the UI to MVC 5, Razor, and bootstrap 3 now. TicketCenter is close to done, and I’m currently working on the New Tickets screen. Afterwards I’ll get into the main ticket viewer/editor.

The goal is to reproduce most of the current behavior exactly as it exists in TD 2.1. Later, I’ll revisit the behavior to further streamline it. The Viewer/Editor is an command/action design, rather than a view/edit/submit design, so it lends itself better to an MVC style design pattern anyway. There are a few activities that do need some smoothing out, but most of that will wait until TD3.

Main Text Editor:

TicketDesk has alternately used an HTML WYSIWYG editor, or a Markdown editor in past versions. I’ve always intended to support both at the same time, but for some reason never seem to get around to it.

TD 2.5 will offer both options though. I have the PageDown editor (markdown) working in the new ticket editor already, but I also plan to implement a limited html editor –probably SummerNote. The back-end has always supported both kinds of content, so all I have to do there port the current code over from TD 2.1.

There will be admin settings where the admin can choose which editors are enabled, and which is the default. If multiple are available from the settings, each user will be able to set their own preference.

Ticket Center Lists Editor:

TD 2.1’s ticket center is designed around the idea of user tailored lists (my tickets, history, open tickets, etc.). In TD 1, you could customize these lists, and I intended to make that a feature of TD 2 as well. A customization screen appropriate for non-technical users is a big challenge, and TD 2 also had a significantly more complex way of managing settings for these lists, so I never had time to make that happen the way I wanted.

For TD 2.5, we will at least have tools to let admins change the default list definitions, maybe by just letting them edit the raw JSON if nothing else. A full end-user custom list designer would be nice, but it will probably have to wait on TD3.

Images & Attachments:

TicketDesk has traditionally only supported file attachments, but not embedded images via the text editor. It stores those files in the database directly. This makes it very easy to move the database from one server to another, and also simplifies backups as well. While performance hasn’t been a problem, this isn’t the best approach in cloud or hosted deployments… if nothing else, the cost of renting SQL storage space is very high compared to file or blob storage.

TD 2.5 will need a plugable storage provider that can store attachments on the local file system (or file share ), or in Azure Storage Blobs. The legacy database migration feature will need to move existing file data to the storage provider before it removes the old attachments table.

Eventually I hope to have support for popular file storage solutions like dropbox and friends.

The front-end text editors will ideally be able to handle inline image uploads, though I don’t think a full media gallery is really necessary –image re-use almost never happens with help desk type systems anyway. If an uploaded image is bigger than a certain size, it should be swapped for a thumbnail in the editor text, and the full image included as an attachment instead.

Eliminate MVC Areas:

I don’t like what areas do to MVC’s routes and navigation, especially with the newer attribute routing stuff. It was cool back in the days of MVC 2 and portable areas, but has outlived its usefulness in MVC 5.

Right now, I do have a couple of areas setup in the code, but I plan to remove these very soon, then cleanup the action and url links so they don’t have to specify an area as custom routedata each time.

Admin:

TD 2.5 will have a “first-run” setup experience. There is a sort of stub for this already, but this will be replaced by an expanded wizard to walk the admin through setting up everything. Most important is setting up the database, security, email, and search features.

Part of this experience will include directing the admin on how to make a few changes in web.config that can’t be automated easily, like adding custom machine keys and such.

Localization (pre-support):

I’ve already have this worked out in TD3. The UI text will be supplied from resource files, instead of being hard-coded. I haven’t quite gotten into the string-heavy part of the system yet, but as soon as I do, I’ll start moving all of the text to resource files. TD 2.5 itself will not provide a full internationalization experience out of the box, but I want to go ahead and get the code in shape for the features coming in TD3. This will also make it super easy for developers to localize the system themselves.

Thanks to everyone for their support and patience!

Review: Dell Precision M3800 Workstation

m3800I had to upgrade the old hardware again. In recent years, it has gotten harder and harder to find a laptop powerful enough for full-scale development, tough enough to last more than a week under heavy use, yet also remains small enough to quality as ‘portable’.

This time, I opted for a new Dell Precision M3800.

Dell’s reputation is pretty bad, and they deserve that for the most part. Their consumer and fleet systems have been declining in quality for years, tech support is abysmal, and they cut corners everywhere that can save them a buck or two. But the Precision line has always been the exception. They’re well designed, super powerful, highly reliable, tough as nails, and expensive as hell –worth every penny though.

I had a Precision M4500 for three years, and it was by far the best developer workstation I’ve ever owned –and I’ve been using laptops exclusively for the last 15 years.

The new M3800 is Dell’s first attempt at an ultra-portable precision. It can’t be easy to shave off enough to squeeze it into an ultra portable form-factor, but still maintain the performance and build quality people expect from the Precision brand.

I’m happy to report that Dell has pulled it off spectacularly with the M3800!

For the most part, this thing packs the same high-end hardware its bigger cousins have; Core i7 CPU, 16GB RAM, SSD, workstation class graphics card, and a beautiful QHD+ (3800 x 1800) 15.6″ touch-screen display .

Despite all that, it manages to be razor thin –0.71 inches at it’s thickest point. Though it still weights around 5 pounds with the bigger battery, it doesn’t feel heavy at all. With a 15.6″ screen, the weight is evenly distributed over a very wide area.

To get it this small there were a few cuts. It has an mSATA card slot plus one 2.5″ internal drive-bay, but the drive bay space is taken up by the extended battery when you opt for the 91 watt hour model –and you DO want the 91Wh battery. That leaves you with just the one mSATA slot for storage.

Also missing are a dedicated docking port, ethernet port, finger print scanner, card reader, and an optical media bay. I miss the fingerprint scanner more than I expected I would, but overall the cuts are not too painful. It comes with a USB ethernet adapter, and you can buy any kind of display adapter to plug into the mini-D port.

Good keyboards have become quite rare over the last few years. For some reason, designers seem convinced that people don’t need arrow keys, function keys, or home, end, pgup, and pgdn keys. These designers are assholes. Sure, home users might not care too much, but IT, business, and graphics professionals use these often.

precisionkeyboardWhile the M3800 keyboard is still one of the better options for developers, it is also the source of my main complaint about the system. The keys are a bit mushy, and I’ve found that the left shift, fn and Ctrl keys don’t always register when I’m working quickly.

Dell also moved pgup, pgdn, home, and end to share the arrow keys as fn combinations. It’s less awkward than some keyboards (I’m talking to you Lenovo!), but the fact that the fn key doesn’t always register makes it unreliable and annoying.

Considering how much empty space there is around the keyboard, you’d think we could at least get dedicated keys for this stuff. At least the arrow keys are offset, even though they are half-height.

The only other complaint I have is that the screen has a somewhat glossy coating, meaning you get glare in many lighting conditions. I really prefer the matte displays Precisions have been known for in the past, but I presume the glossy coating is necessary for the touch screen features –still, I’d prefer an option for a matte display even if it meant giving up the touchscreen.

Otherwise though, this machine is making me very happy. The display is truly amazing, just as you’d expect from a Precision. It is also freakishly fast. On paper, the specs for this system aren’t much different from my last machine –an HP Envy TouchSmart 15t with after-market SSD. In reality though, this system murders the HP, and it even outpaces the beastly Lenovo M540 workstations we have at the office.

Battery life is around 5 hours under normal development workloads (with WiFi turned on). Even though the system has a 130watt power supply, Dell was kind enough to reduce the size of the power-brick quite a lot compared to the previous generation boat-anchors.

If you plan to buy one of these, here’s a pro-tip: Dell charges almost $800 for their 512GB mSATA SSD module. I recommend buying the system with the tiny 128GB mSATA card instead, then just pickup an after-market 512GB mSATA. Crucial sells their excellent M550 mSATA modules for under $300, so you’ll save $500, and still get a far better drive than the Dell offering.

Keep in mind though, you will need both a T5 Mini-Torex, and a #1 Phillips screwdriver to open the case. Make sure you get a good driver that has a real handle. These screws are tiny, and fragile, and you do NOT want to strip one of them by accident. I highly recommend the Sears Craftsman mini-Torex kit for this kind of work.

Dev Diary – Scaling search for an Azure WebSite

azuresearchAdding real search capabilities to a custom web application is never easy. Search is a complex and deeply specialized area of development, and the tools available to us regular developers are monstrously complex.

With TicketDesk 2, I used the popular Lucene.net library to provide search. Ported from Apace Lucene (Java), this is the core technology that powers almost every popular search service, appliance, and search library on the market.

Once you’ve tackled the initial learning curve, Lucene.net isn’t all that difficult to leverage in a simple system like TicketDesk. It is freakishly fast, super flexible, and is a powerful search solution –not quite Google good, but close enough for most applications.

The problem with Lucene is that the design revolves around indexes stored on a traditional file system. There are 3rd party extensions that let you store the indexes in a database or in the cloud, but internally these all mimic the behaviors of a file system –that’s just how Lucene works.

You can have many components querying an index at the same time, but only one can write to an index at a time. Normally this single-writer limitation isn’t a huge problem. You code your application so it creates just one writer instance, then share it with any components that want to make an index update. As long as you keep things synchronous, it tends to work fine.

And here lies the problem. TicketDesk 2.5 and 3.0 are designed to run at scale, and will ship ready for deployment to the cloud as an Azure WebSite. In this scenario, there can be several instances of the application running at the same time, each needing to write to a single, shared Lucene index.

I spent a full week trying to find a way around the single-writer problem. WebSites in Azure shouldn’t write to their filesystems. Anything written locally is volatile, and vanishes whenever Azure automatically moves the site to a different host. So, I started with the AzureDirectory library for Lucene, which lets you store the search index in Azure blob storage. This works well, and gives Lucene a stable place to store shared indexes in the cloud.

The second problem was keeping multiple web site instances from writing to the index at the same time. Even though the index is in blob storage, Lucene still demands an exclusive write lock. Each websites can see when the index is locked by another writer, but there isn’t a way to know if the lock is legitimate, or an orphaned lock left behind when some other instance went down unexpectedly.

The only easy solution is to make sure there is a separate application to handle all index writes, and that there is only a single instance of that application running. You can scale the websites or other clients, just don’t scale the index writer application.

WebJobs were designed specifically for handling background on behalf of Azure WebSites, so I started there. Each website would queue index updates to an Azure Storage Queue, then the WebJob could come along and process the queue in the background. But WebJobs scale with the websites, so if you have multiple websites, you also have multiple webjobs. Hopefully, in the future MS will give us the ability to scale webjobs independent of the websites they service.

So the only remaining solution would be an old fashioned worker role. They scale independently –or in this case, can be instructed not to scale. This works well, but I just don’t like the solution. Effectively, the worker role ends up being a half-ass, custom search server. It costs a decent amount of money to run a separate worker role instance, plus it complicates the deployment and management of the entire application.

Failing to find a way to continue in Azure with custom Lucene indexes without a centralized search server, I figured I’d just design TicketDesk to take advantage of the existing Azure native solution –Azure Search Services. It is easy to code against (relatively), and there is a free tier that should be suitable for most smaller shops. For larger shops, the costs of a paid Azure Search tier is still reasonable when compared to the costs of a dedicated worker role.

So, out of the box, TicketDesk 2.5 will include at least two search providers; a Lucene provider for on-premise single instance setups, and native Azure Search for cloud deployments. I will eventually add an alternative for on-premise webfarms, and non-azure cloud VMs. In the meantime though, you could still scale in your own data-center by using Azure Search remotely, or stick with Lucene and manually disable the search writer on all but one instance of the site in the webfarm.

One additional note of interest: Azure Search is still in preview, and it doesn’t have an official client library for .Net yet. There are two 3rd party client libraries though; Reddog.Search and Azure Search Client Library. Both are free as NuGet pacakges, but only Reddog.Search has a public open source repository. Also, Reddog has a management portal you can run locally, or install as an Azure WebSite extension.