Our software runs as Windows Services and we have multiple services on each server. If our software is interfacing with a specific piece of hardware using a serial connection, that is one service. If we are listening for a call on a Dialogic Telephony card, that is a different service. Before this project was implemented, it was becoming very difficult to keep each location running the correct version of the software.
This project consists of three major components. First, it has a Website component for administrators to view and edit information. Second, it has a console program that checks for and actually performs the updates. Finally, it has web services that expose functionality that both the Website and Console program need.
The original version was deployed on Microsoft Azure using Sql Azure as the database. It is currently being moved to Amazon servers using a SQL Server deployed on Amazon Web Services. The actual files were saved to Azure using a CloudStorageAccount, but are now being saved to Amazon S3 storage.
A WatchDog service at each location runs the Hup.exe console program hourly. Hup compares the current running version of each service to the required version for that location. When it finds a difference, it downloads the new version into a new folder. After it successfully downloads the files, it stops and unregisters the old version of the windows service. It then fires up the new version.
Website (Asp.Net MVC3, ASPX Views)
I am not a designer (seems like I say that in every post). I always liked the clean simple look of Google, and Gmail was no exception. Since this was an intranet site, I figured Google would not mind (or find out) that I “borrowed” their look.
This project started as an MVC2 project, so the Razor view engine was not a possibility. When I upgraded it to MVC3, it didn’t make sense to refactor the views. I have used Razor on subsequent projects, and I definitely prefer it to the ASPX view engine.
Here is an example List screen. It includes paging information with the total record count and the current “page” being viewed. Clicking the “Show Filter” link brings up the next screen.
The user can filter the results based on predetermined values. This specific screen only allows the user to filter based on the Application. They can also select the number of records they want to view per page. Finally, they can select from a predefined list of Sort fields to order the results.
Here is an example Edit screen. The preferred action is to click the Save button, but if they want to cancel their changes, they can click the “Back to List” link to cancel their changes.
Set Current Version
This is one of the more critical screens in the application. Here, the user can chose what applications run for each specific location. Our server may be talking to one piece of hardware at one location, and completely different type of hardware at another location. In addition to the application, the user an also select what version needs to be ran at that location. Usually, we want to run the latest version, but not always. This screen gives us that flexibility.
Some services run multiple copies of the same service. For a Dialogic Telephony card listening on four lines, four separate services will run. The Service Count column allows the user to specify how many should run. In this example, the column is grayed out for the currently selected services, since each of them are only allowed to run one instance.
This was a very helpful report/screen that allows the user to know what version is running at each location. This should be one of the first screens a tech should use when running down a problem at a location. It has been especially helpful when a location is have a problem that we “thought we already fixed”, only to find that a specific location is still running an older version of the code.
I am sure I stole this idea from somebody, but it has been so helpful to always include a few common methods in all web services I write. It makes it nice to verify that the basics are working before I try to run down why some method that requires a complex object is not working.
- Version – This is helpful for making sure the latest code actually got deployed.
- ServerTime – Useful to make sure I am not fighting a cache issue and the result is changing each time I call the service.
- Ping – Returns an Http 200 response status code, but no text. When using a Load Balancer, I have it call this method to make sure the server is ready for requests.
- Service-Oriented Architecture
- Windows Communication Foundation (WCF)
- Deployed on Microsoft Azure
- Sql Azure Database
- Asp.Net MVC3 (not Razor)
- Windows Service, Console Program
Yes, an actual console program. This needed to be a simple .EXE that could be placed on a remote server. It only requires the .Net Framework and doesn’t depend on any custom .DLLs. When it is ran without any parameters, it shows the following help screen.
It started with just a few simple switches, but grew to include other functions.