At Microsoft TechEd 2009 earlier this year, we introduced a startup company that concerns itself with high-tech digital software escrow. The basic idea behind software escrow is simple: When a customer buys software (or anything else that is provided in digital form) from a vendor, there often are concerns about what would happen if the software vendor goes out of business or stops supporting the product for any reason. In such cases, customers often need access to source code, other files, or even expertise that the vendor normally would not be willing to give up. Escrow organizations act as independent third parties that hold such “assets” in a safe place to be released to the customer (a.k.a. “beneficiary”) in case such a scenario arises.
This is a great way for customers to add an extra safety net, while for vendors it often removes serious hurdles in the sales process. The trouble with software escrow in general is that it often is a major hassle and introduces serious expense for everyone involved. Mostly, escrow companies are very generic and handle just about anything imaginable (from software to physical assets), which means there are few things available that are specific to the needs of software companies (such as the ability to upload files digitally, rather than mailing in a DVD). We had to suffer through this on various occasions, which is why we decided to launch Tower48, which is an all-digital offering provided at very low cost. We built Tower48 completely based on Service Oriented Architecture (SOA), which enables nifty features such as easy integration into development environments and eCommerce Web sites. For more information on those features, visit Tower48.com.
From a technical viewpoint, we wrote Tower48’s software completely in .NET 3.5, including some key technologies such as WCF, ASP.NET, and Silverlight. Among the key challenges for Tower48 are flexibility (as we have to very easily adjust to different types of escrow scenarios and legal ramifications of those scenarios), reliability (losing someone’s escrowed assets could have catastrophic implications for the company), and “openness” (allowing all kinds of systems and development environments to integrate with Tower48 directly).
Based on previous experience on a large variety of projects (the implementation of Tower48’s software was entirely done by EPS Software Corp., CODE Magazine’s parent company), we picked WCF as a cornerstone of the overall system architecture, both in terms of internal architecture as well as for a service interface for all kinds of outside callers using all kinds of standards. We chose Silverlight for large parts of the Web front end for two reasons: 1) increased developer productivity over ASP.NET, and 2) the need for sophisticated client-side functionality. For instance, Tower48 features a sophisticated engine that can produce legal contracts, allowing people to set up escrow agreements without the need to get lawyers involved. (Although for unusual scenarios, we do have lawyers available as well.) While we have a version of this engine available on the server, we wanted much of that functionality to run on the client to avoid slow round trips that could potentially include large amounts of data sent back and forth for every little change.
What Went Right
1. Using WCF for a Public Service Interface
From the beginning, we knew that one of the key features of Tower48 was the ability for people to integrate directly with the service. Instead of manually going to the site to add new customers or upload files, we wanted people to be able to integrate escrow directly into the build process of Visual Studio (and other IDEs), or the sales process on their eCommerce site (simply add a checkbox to add escrow services for an order and make some money that way), or enterprise systems (sync your customer base with the list of beneficiaries, and vice-versa), among other scenarios.
A critical requirement was the support of various formats, including SOAP, REST, and binary optimized services (which we use with .NET helper objects and Tower48 API .NET objects). In addition, calls have to be made reliable through various network and firewall scenarios without administrative hassles, as we would immediately risk a loss of business if the services didn’t work without extra maintenance. Furthermore, all calls have to be made securely, as very sensitive information is passed over the wire.
WCF was a great way to satisfy all these requirements. Out of the box, it supports all the required formats and standards. This enabled us to create service interfaces that are callable from any language or environment in a way that is natural to each setup. With some of the existing EPS infrastructure, we were also able to create failover implementations to make sure regardless of network configuration and conditions, service calls always succeed.
2. Using SOA and WCF for Internal Architecture
The entire Tower48 system is internally architected using SOA (Service Oriented Architecture) principles. There are services for file handling, user management, legal contract creation, and many more. Although the overall system is complex, each service is itself relatively simple to create, test, maintain, and extend.
Regardless of the front-end or client calling a service (such as Silverlight, or rich-client WPF implementations), the same services are invoked. However, we call them in different ways. A call from the Silverlight front-end uses very different standards than a call from a WPF client does. In fact, using the Milos framework developed by EPS, we are able to call services in-process with no serialization or out-of-process invocation needs, providing the same performance characteristics for clients on our LAN as a non-WCF-based architecture with simple locally instantiated objects would have.
Just like for the external services, WCF worked very well as a fundamental building block for every internal call. Performance and scalability worked out especially well, in part due to WCF’s intrinsic capabilities, and partially due to the additional infrastructure and framework we had available to us at EPS.
3. Using EPS Software’s Milos Solution Platform for Data Access Architecture
At EPS Software, we have a framework called the “Milos Solution Platform,” which is a .NET soup-to-nuts framework for professional development efforts of any size. (We use Milos mostly for our client projects, but it is also available as a product.) We have used this framework for large parts of the Tower48 implementation on various levels, from the user interface, to service invocation, to business objects/entities, and data access. The one area where Milos worked out particularly well is data access.
From the get-go, we have designed Tower48 to run on cloud environments, in particular (although theoretically not limited to) Windows Azure. However, as I am writing this post-mortem, Azure is still in beta, and although we are an approved early implementer, we did not want to launch Tower48 on a beta platform. Our current Tower48 deployment runs in a conventional data center.
The Milos data access infrastructure allows developers to very easily switch between different database back ends, including SQL Server (which is what Tower48 is currently running on) and a vast variety of other technologies ranging from MySQL and Oracle all the way to SQLCE and even flat XML files used to simulate more sophisticated databases. Milos can handle things such as differences in syntax or whether or not stored procedure support is available on the chosen platform.
Most importantly for our particular scenario, Milos can also seamlessly switch over to various Azure-based data options. This allowed us to create an application architecture and implementation that enables us to seamlessly switch a deployment over to Windows Azure, once we are ready to make that leap for our production deployment.
4. Using Silverlight for the Web Site
The Tower48 Web site has two very distinct areas: 1) The client center, which is where people maintain their actual assets, as well as things that have been put into escrow in their benefit, and 2) general information about escrow, pricing, and similar things. This type of content is almost (but not quite) static information.
The semi-static content we handle in ASP.NET. It is a very simple setup, so we decided to use conventional ASP.NET over ASP.NET MVC. The client center, however, is the heart of the application, with some very heavy duty functionality built in that runs on the client. We thus decided to use Silverlight rather than any version of ASP.NET.
5. File Uploads and File Handling
Digital escrow is all about handling various kinds of files (the “escrow assets”), which includes uploading and downloading files securely as well as managing files that are in escrow and verifying that they are correct in the sense that they aren’t corrupt, but also in the sense that they contain the things people expect them to contain.
The first step for people is always the file upload step. This is a classic problem for Web scenarios, especially when file uploads get large. We solved this by creating a file service that can accept large files in smaller chunks. Using Silverlight, we can easily open a local file, chop it into chunks of a size we desire, and then upload it piece by piece through our service. In fact, we can easily encrypt and compress individual chunks. We can also completely scramble the upload sequence and put things back together into the right order on the server. All this provides for a good upload experience for the user, even for very large files. It also makes for a very secure environment.
Once files have been uploaded to the server, we manage files by putting them into SQL 2008 (which works great for binary content). Here we also have the ability to store files in individual chunks if needed for security. Using Windows Azure, we hope to even geographically separate parts of files for added security.
Another interesting feature is the ability “to look into files.” For instance, using the Silverlight UI, users can see contents of ZIP files without actually having access to the file contents. This allows beneficiaries to verify that all the appropriate files are in escrow, without getting the content unless release conditions are met. (The ability to open ZIP files natively both on the server as well as in Silverlight is a Milos feature.)
All these features are available from the Silverlight client as well as other clients such as services or API objects.
1. File Downloads from Silverlight
While file uploading and handling works great thanks to the magic of Silverlight and WCF, file downloading wasn’t nearly as straightforward. It was our intention to create a standard Web download (using HTTPS for security). While this was fairly straightforward to implement, the devil ended up being in the details. In particular, Internet Explorer caused us some headaches.
Due to Internet Explorer’s security model, attempts to download a file are usually caught by IE and one of those infamous yellow bars shows up at the top of the browser to inform the user of a potential security problem. The user can then accept that warning and proceed to download the file. At that point, Internet Explorer refreshes the current Web page and then allows the download. While this may be workable in for HTML pages, it is a real problem for Silverlight apps, because it means the entire control is being reloaded together with the current page, setting it back to its initial load state. The user then has to re-perform all navigations within the control to get back to the same place, which can be a lengthy and very annoying process. Clearly this was not acceptable.
We were able to create a workaround for this by opening a new browser window and then re-directing into a download URL. (I have a blog post on MarkusEgger.com describing in detail how to do this.) This way, the security message only shows up in the secondary browser window, which can still be annoying, but not nearly as much as the Silverlight-reload scenario.
Note that this is only a problem in Internet Explorer. Other browsers do not have this security restriction. This may leave users more exposed, but it sure makes it easier to create a Silverlight file download scenario. We ended up checking for the browser the user is using, and we only invoke the workaround mentioned above in IE scenarios.
2. Printable Content from Silverlight
It seems that the more advanced development environments and SDKs become, the more printing is neglected. Exact printing never was exactly simple in HTML applications, and it simply is not supported at all in Silverlight. There simply is no printing feature.
The Tower48 application has to deal with considerable amounts of text that make up legal agreements. We can’t simply turn text into HTML and have the user print that, since legal documents can’t change with printer settings and such. An obvious alternative option would have been XPS output, since it is relatively straightforward to turn Silverlight formatted text into XPS. However, XPS is Windows specific and was thus not a viable option, as we want Tower48 to also be accessible from non-Windows environments.
In the end, we were forced to implement “printing” by letting users download PDF versions of contracts, which they can then choose to print. Those PDF documents, we create on the fly using a low level PDF engine we wrote for this purpose (and which we will probably migrate into the Milos Solution Platform). This allows us to create PDF documents both on the server and the Silverlight client.
3. Code Reuse
Large scale code reuse made it possible to build the Tower48 infrastructure in a timely fashion. We were able to reuse framework-level code from Milos as well as business-related code from the Milos Business Framework to do things such as storing names, digital documents, or charge credit cards. We also managed to reuse new code we wrote across various elements of the application. For instance, we are able to reuse file handling code in the Silverlight application as well as the regular .NET back end.
All this sounds good, so why am I putting this in the “challenges” section? Well, while it was great to be able to reuse code like this, it was also somewhat harder than it needed to be to reuse code between “regular” .NET and Silverlight. For one, it is not possible to put code into an external assembly and reference it from .NET and Silverlight projects. This is a somewhat artificial restriction I find to be very annoying. It introduces what seem to be unnecessary file handling and linking hassles that introduce additional sources of errors.
It is also very important to keep an eye on file sizes in Silverlight. At some point during the project, we accidentally grew the Silverlight control to a very large size for no real reason. We then went through manually to remove and refactor things and finally ended up with a more manageable file size. It sure would be nice if there was a more automated process in place to do this. This is also something we have encountered in other Silverlight projects. It seems to be a common problem.
4. Silverlight Versions
When we wrote the Tower48 Silverlight application, we had to do it in Silverlight version 2, while version 3 was already out in beta and would have made many things much easier. However, we decided we simply did not want to wait for Silverlight 3 and thus initially stuck to version 2 and hoped to just upgrade to version 3 as soon as it became available. This ended up being a somewhat annoying hassle, especially since tools such as Blend 3 (which is much improved over Blend 2) are not capable of handling Silverlight 2. On one occasion, we actually ended up accidentally upgrading the app to Silverlight 3 prematurely, which required a lot of manual re-work to fix.
5. Text Formatting
There is no way to sugarcoat this: Silverlight is very poor for text formatting. Blocks of text support very simple formatting such as bold and italic, but even seemingly simple concepts such as paragraphs are not supported. Text can be left or right aligned or centered. Justified text is not available. Alignments are set for entire blocks and not for individual lines or paragraphs. This means it is not natively possible to create a block with a centered heading and the remainder being left aligned or justified.
As you can imagine, all this is a bit of a problem for a system that deals (at least occasionally) with large amounts of legal text. It always seems to me that the Web’s origins are very much in the realms of document definition (after all, that is what HTML was originally created for) and it seems odd that a Web-only technology like Silverlight has practically no features for document or text formatting.
At some point, we even experimented with our own layout and text rendering engine that supports some of the features provided by Flow Documents or XPS in WPF. We also experimented with a PDF viewer written entirely in Silverlight. However, we decided that even a relatively simple initial engine would be too time consuming to build. We may still roll this engine out at some point (probably as part of Milos), but we put this effort on hold in favor of pushing the initial Tower48 version out as quickly as possible.
For the time being, however, we had no choice but to live with the capabilities provided by Silverlight and to limit ourselves to very simple text formatting options such as bold and italic with various fonts and sizes mixed in.
In a lot of ways, the Tower48 infrastructure was an amazing undertaking. We build a relatively complex system in practically no time at all. Silverlight was a great choice for client-side technology. It is reasonable to expect that all serious users of the service will be able to install Silverlight (especially considering the target audience) and all parts of the site that deal with up-front information are kept in plain HTML. WCF was a great communication mechanism.
In hindsight, we would choose all the same technologies and architectural choices again. I believe Tower48 is a great case study for how powerful and productive .NET 3.5 technologies are.