I was recently asked to evaluate some Website monitoring tools for a small client of mine. While there is no shortage of Website monitoring services available, ranging from free to infinitely elaborate and expensive (and sometimes worth it, depending on the company's size and needs), I ultimately decided to just build one from scratch. This way, the client would not be at the mercy of SaaS outages, and would be fully in control with the code on-premise. This solution can be expanded as needed with a UI and possibly a database back-end, but following KISS, I took a simple approach, using a console app with settings in app.config, running it using a scheduled task. Here are the details:
1. Create a new Console Application project.
2. Using the project's Settings file, create a setting called "SitesToMonitor" of type System.Collections.Specialized.StringCollection. This allows you to enter a list of strings, using the ellipsis in the Value column. The list is saved to the app.config file as an xml ArrayOfString, and can be easily accessed, strongly typed, from your C# code. Enter the list of urls you want to monitor. The resulting config item looks like the following:
3. Create a class with a single method accepting a StringCollection, which iterates through them, attempting to retrieve a response from each, along with a method to do whatever your standard logging is when a site returns a negative status code or throws an exception:
4. Add a single line of code to Program.Main to kick off the process:
5. Create a scheduled task to periodically kick it off, and voila!, you have your very own simple, easy-to-configure Website monitor.
Tek Prolixity
Spreading bits of .Net engineering goodness and other tek fun
Wednesday, October 30, 2013
Monday, July 29, 2013
Worst-Smelling Code
I love cleanliness. I can say that, even as the far reaches of my desk have accumulated an unhealthy layer of dust. What I'm really talking about here is code. I have an affinity for clean, concise, logically separated code. Which means, as you can imagine, when I see messy, duplicated, bloated code, I feel like throwing something (or someone).
In the software development world, we call this "Code Smell". I wanted to share what I consider to be some of the smelliest (think bad cheese) code. Keep your code linen fresh, and avoid these:
Duplicated Code. Sure, it may be a lot faster and easier to just copy those 20 awesome lines of code, and use it everywhere else you need the same logic. But, you're just hurting yourself (or whoever has to maintain the code). The disadvantages of copy / paste are obvious: if you need to change the logic due to a business rule change, you'll end up having to change it in all the places you copied it. However, there are other forms of duplication, where code is copied and then tweaked. This is even worse, as now you need to multiply the difficulty of reading the code by the number of times it's copied and tweaked. In this case, for goodness' sake, create a method with parameters!
God Objects. A "god object" is an object that knows or does too much. We've all seen examples of this (and are probably guilty of doing it) in the real world. One of the worst offenders I've seen is a classic ASP app where there was a single .asp page, whose single code path was a huge case statement which, depending on the combination of querystring variables (all integers) would decide where to navigate or what logic to run. It also handled any session variables and caching.
Aside from being a debugging nightmare, god objects go against the time-tested object-oriented tenets of "single responsibility", decoupling and separation of concerns.
My suggestion for breaking up an existing god object is to start from scratch. Document the requirements and properly separate functionality. Think high cohesion, and low coupling.
Methods with too many parameters. This is another easy way to create a debugging debacle and maintenance nightmare. In my opinion, when you get to around 5 parameters, you may want to rethink your approach. A couple of options would be to 1) create a struct or class to pass instead of the parameter list or 2) rethink the method altogether and consider splitting it up into multiple methods.
Contrived Complexity (See KISS). Too often, developers either try to follow a pattern which isn't suited for what they're building, or they attempt to create elaborate "frameworks" to make their code flexible to the Nth degree, when the Bth or Cth degree is all that's really needed. YAGNI is another rule of thumb that directly applies here (You aren't gonna need it). If we try to anticipate what we might need 2 or 3 years from now and bake it into our code, we create unnecessary complexity, which means code with more room for error and more difficult to test and maintain. Please, build what you need when you need it, and allow the software to evolve naturally in an agile manner.
Go get rid of that stench!
In the software development world, we call this "Code Smell". I wanted to share what I consider to be some of the smelliest (think bad cheese) code. Keep your code linen fresh, and avoid these:
Duplicated Code. Sure, it may be a lot faster and easier to just copy those 20 awesome lines of code, and use it everywhere else you need the same logic. But, you're just hurting yourself (or whoever has to maintain the code). The disadvantages of copy / paste are obvious: if you need to change the logic due to a business rule change, you'll end up having to change it in all the places you copied it. However, there are other forms of duplication, where code is copied and then tweaked. This is even worse, as now you need to multiply the difficulty of reading the code by the number of times it's copied and tweaked. In this case, for goodness' sake, create a method with parameters!
God Objects. A "god object" is an object that knows or does too much. We've all seen examples of this (and are probably guilty of doing it) in the real world. One of the worst offenders I've seen is a classic ASP app where there was a single .asp page, whose single code path was a huge case statement which, depending on the combination of querystring variables (all integers) would decide where to navigate or what logic to run. It also handled any session variables and caching.
Aside from being a debugging nightmare, god objects go against the time-tested object-oriented tenets of "single responsibility", decoupling and separation of concerns.
My suggestion for breaking up an existing god object is to start from scratch. Document the requirements and properly separate functionality. Think high cohesion, and low coupling.
Methods with too many parameters. This is another easy way to create a debugging debacle and maintenance nightmare. In my opinion, when you get to around 5 parameters, you may want to rethink your approach. A couple of options would be to 1) create a struct or class to pass instead of the parameter list or 2) rethink the method altogether and consider splitting it up into multiple methods.
Contrived Complexity (See KISS). Too often, developers either try to follow a pattern which isn't suited for what they're building, or they attempt to create elaborate "frameworks" to make their code flexible to the Nth degree, when the Bth or Cth degree is all that's really needed. YAGNI is another rule of thumb that directly applies here (You aren't gonna need it). If we try to anticipate what we might need 2 or 3 years from now and bake it into our code, we create unnecessary complexity, which means code with more room for error and more difficult to test and maintain. Please, build what you need when you need it, and allow the software to evolve naturally in an agile manner.
Go get rid of that stench!
Friday, May 11, 2012
Azure Service Bus Relay: Hybrid OnPrem/Cloud App
There is a lot of buzz around IT departments and development teams about Azure and "the cloud" regarding moving applications, services and data to Azure. If you are planning (or dreaming) about moving to Azure, the nice thing is that you don't have to go all-or-nothing, and if you do, you can migrate to the cloud one application at a time. Having some apps/data in the cloud and some on-premise is usually referred to as "Cloud Hybrid".
One of the easiest ways to achieve this is to host applications in Azure that can consume the WCF services you already know and love that live within your corporate network. This is made possible by Service Bus relay and the netTcpRelayBinding. And by the way, this does not require any custom firewall rules or any other changes to your network infrastructure, which makes it extremely clean and completely configuration-driven. Here are the steps:
1. If you don't already have one, create a namespace in Azure Management Portal. Goto Service Bus and click the {}New button on the top left:
Figure 4
5. Configure your client - the Web app or service in Azure, by adding the following:
Figure 5
It's really as simple as that. You now have an internal service listening on an Azure Service Bus endpoint, secured by server-generated tokens. Once you deploy your app to Azure, you've just created your first hybrid cloud application!
One of the easiest ways to achieve this is to host applications in Azure that can consume the WCF services you already know and love that live within your corporate network. This is made possible by Service Bus relay and the netTcpRelayBinding. And by the way, this does not require any custom firewall rules or any other changes to your network infrastructure, which makes it extremely clean and completely configuration-driven. Here are the steps:
1. If you don't already have one, create a namespace in Azure Management Portal. Goto Service Bus and click the {}New button on the top left:
Figure 1
2. Make note of the default namespace credentials (Default Issuer and Default Key) from the namespace properties, found by selecting your namespace and clicking the "View" button on the bottom-right in the properties pane:
Figure 2
3. In both your client (application in Azure) and service (internal corporate network), ensure you have all the Windows Azure Service Bus references and config values properly set. The easiest way to do this is via NuGet. Right-click, references, search for "WindowsAzure.ServiceBus". Add this package to your internal WCF project and your client (Web/service) project.
Figure 3
4. Expose your internal service by adding an endpoint using the netTcpRelayBinding protocol, as well as the new behavior setting to specify your authentication issuer and secret. The <servicename> can be anything, just make sure the setting matches on your client and service. See Figure 4 below
Figure 4
<system.serviceModel> <services> <endpoint contract="MyCo.Services.IOrderService" binding="netTcpRelayBinding" address="sb://<namespace>.servicebus.windows.net/<servicename>" behaviorConfiguration="sbTokenProvider"/> </services> <behaviors> <endpointBehaviors> <behavior name="sbTokenProvider"> <transportClientEndpointBehavior> <tokenProvider> <sharedSecret issuerName="owner" issuerSecret="**key**" /> </tokenProvider> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
5. Configure your client - the Web app or service in Azure, by adding the following:
Figure 5
<system.serviceModel> <client> <endpoint name="orderservice" contract="MyServiceProxy.IOrderService" binding="netTcpRelayBinding" address="sb://<namespace>.servicebus.windows.net/<servicename>" behaviorConfiguration="sbTokenProvider"/> </client> <behaviors> <endpointBehaviors> <behavior name="sbTokenProvider"> <transportClientEndpointBehavior> <tokenProvider> <sharedSecret issuerName="owner" issuerSecret="**key**" /> </tokenProvider> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
It's really as simple as that. You now have an internal service listening on an Azure Service Bus endpoint, secured by server-generated tokens. Once you deploy your app to Azure, you've just created your first hybrid cloud application!
Tuesday, April 24, 2012
Simulate a Mobile Browser using Chrome
When I first started down the road of mobile Web development, I asked around, Googled, and found some wacky, some nice mobile browser simulators that various enterprising individuals slapped together. Then I discovered that the easiest way to simulate a mobile browser was right in front of my face. If you already use Chrome, you're just a step away. All you need to do is override the "User Agent" to instruct the browser to use an agent specific to a device, either by selecting it from a list, or entering the user agent string directly. Steps:
0. Get Chrome if you don't already have it
2. Goto Tools -> Developer Tools
3. Click the gear icon on the bottom right
4. Find the setting "Override User Agent", check it, and select the browser/device you want to emulate
5. Refresh your page and inspect it. This is how it will look on the device you chose. (You'll have to re-size the browser to a phone-ish size if you've selected a mobile phone device)
Don't see the user agent string you're looking for in the list? Look here (http://www.useragentstring.com/pages/useragentstring.php) for an extensive list of user agent strings you can copy and paste into the free-form textbox.
Friday, April 20, 2012
Instant MVC 3 Mobile App
Have you been pondering getting into mobile development, but have been procrastinating, and making excuses to yourself about how little time you'll have to devote to it, the steep learning curve, etc? Yeah, me too. That is, until I found the simple but awesome "Mobile Ready HTML5" template using Visual Studio Extension manager. Its a fully functioning MVC 3 application template that is "mobile ready" out of the box, and allows you to easily create your own mobile views for a new or existing MVC 3 app.
Figure 1
It's all downhill from there. I made a couple changes and additions to the UserAgent check, but aside from that, this template will have you up and running with an MVC 3 mobile app in no time.
To get it from Visual Studio:
1. Open extension manager from Tools/Extension Manager
2. Goto Online Gallery, and search for "Mobile Ready HTML5"
3. Click Download.
To get it from a browser:
Go here: http://visualstudiogallery.msdn.microsoft.com/9df9c61c-4d90-43e5-9aa1-a58786b7a1e4.
Thanks to Sammy Ageil for putting this together. He's got some more details and instructions on his site: http://www.sammyageil.com.
The elegant key to its functionality is the subclassing of the System.Web.Mvc.RazorViewEngine, overriding the "FindView" method (Figure 1), and deciding on which View to serve up based on the browser type. This prevents having to change any code in your controllers, keeping things clean.
Figure 1
using System.Web.Mvc; namespace Web { class MobileViewEngine : RazorViewEngine { public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { ViewEngineResult result = null; var request = controllerContext.HttpContext.Request; //Determine if this is a mobile browser //IsSupportedMobileDevice is an extension method which queries the UserAgent if (request.IsSupportedMobileDevice() && ApplicationHelper.HasMobileSpecificViews) { //Get mobile view string viewPathAndName = ApplicationHelper.MobileViewsDirectoryName + viewName; result = base.FindView(controllerContext, viewPathAndName, masterName, true); if (result == null || result.View == null) { result = base.FindView(controllerContext, viewPathAndName, masterName, false); } } else { result = base.FindView(controllerContext, viewName, masterName, useCache); } return result; } } }To create your mobile views, you'll simply need to create a folder called "Mobile" (or anything else, as it's configurable) under the existing Views folder, like so:
It's all downhill from there. I made a couple changes and additions to the UserAgent check, but aside from that, this template will have you up and running with an MVC 3 mobile app in no time.
To get it from Visual Studio:
1. Open extension manager from Tools/Extension Manager
2. Goto Online Gallery, and search for "Mobile Ready HTML5"
3. Click Download.
To get it from a browser:
Go here: http://visualstudiogallery.msdn.microsoft.com/9df9c61c-4d90-43e5-9aa1-a58786b7a1e4.
Thanks to Sammy Ageil for putting this together. He's got some more details and instructions on his site: http://www.sammyageil.com.
Labels:
HTML5,
jQuery Mobile,
jQueryMobile,
mobile MVC,
MVC,
MVC 3,
MVC mobile,
MVC3
Thursday, April 19, 2012
Using Moq for Unit Testing
Unit
tests should be run in isolation. Meaning, a test method should not have to
rely on database connections or other external dependencies being available. To accomplish
this, the repository (or other data access) class used by a service must be mocked and injected using
the service constructor. Review this sample code:
[TestMethod] public void GetByID_Test() { var orderCode = "TestOrder"; //Create a mock repository, and specify that the GetByID method always //returns an Order object with a given order code var mock = new Mock<IOrderRepository>(); mock.Setup(m => m.GetByID(It.IsAny<int>())).Returns ( new Company.DataAccess.Order{OrderCode = orderCode} ); //Inject the mock repository into the service using constructor var orderService = new OrderService(mock.Object); //Call the service method var order = orderService.GetById(4); Assert.AreEqual(order.OrderCode, orderCode, string.Format("OrderCode {0} doesn't match the expected value {1}", order.OrderCode, orderCode)); }
All
this code is doing is creating a "fake" repository using the
interface, then setting up the method used by the "GetByID" service method that always returns the same value. If
desired, methods can be faked to return different values based on the parameter
passed in. Ideally, the mock repository setup would be contained in a common
setup method, and each and every repository method would be setup with expected
values, so it could be reused in each test method.
Yes,
this adds time to your development cycle, but it makes your test methods more
precise, isolating only the code it's meant to test, eliminating reliance on
dependencies such as databases and any other "external" dependency.
Unit Testing Guidelines
As quality-conscious software engineers, we all (hopefully) do some level of unit testing. This typically ranges from simply running your code to see if it works, up to full-blown test-driven development in which the component coding cannot commence until all positive and negative unit tests are thoroughly completed. If you fall towards the bottom of the range, your QA team probably hates you, and if you are closer to the top of the range, well, uh, honestly, your QA probably still hates you. Either way, if you create any level of unit tests, there are some basic guidelines that should be followed. These are the guidelines I like to follow. If you don't have a set of "rules of thumb" for your team, here's a good place to start......
General Rules:
- At least one test method should be written for every
public service method and every new or overridden repository method
- Where applicable, positive and negative tests should
be written
- Every Assert should include a relevant, meaningful
error message for when failure occurs
- The Arrange, Act, Assert pattern should always be
followed (see below)
There's
no need to re-hash what others have written better than I can, so, please read
this article on MSDN: Guidelines forTest-Driven Development. If you don't want to delve into that heavy reading, one
important (must-read) highlight from that article is that a good unit test has the following characteristics:
- Runs fast, runs fast, runs fast. If the tests are
slow, they will not be run often.
- Separates or simulates environmental dependencies
such as databases, file systems, networks, queues, and so on. Tests that
exercise these will not run fast, and a failure does not give meaningful
feedback about what the problem actually is.
- Is very limited in scope. If the test fails, it's
obvious where to look for the problem. Use few Assert calls so that the
offending code is obvious. It's important to only test one thing in a
single test.
- Runs and passes in isolation. If the tests require
special environmental setup or fail unexpectedly, then they are not good
unit tests. Change them for simplicity and reliability. Tests should run
and pass on any machine. The "works on my box" excuse doesn't
work.
- Often uses stubs and mock objects. If the code being
tested typically calls out to a database or file system, these
dependencies must be simulated, or mocked. These dependencies will
ordinarily be abstracted away by using interfaces. We are accomplishing
this by using the Moq mocking framework.
- Clearly reveals its intention. Another developer can look at the test and understand what is expected of the production code.
Arrange, Act, Assert:
Follow
the "3-As" pattern for test methods: Arrange, Act, Assert.
Specifically, use separate code paragraphs (groups of lines of code separated
by a blank line) for each of the As.
- Arrange is variable declaration and initialization.
- Act is invoking the code under test.
- Assert is using the Assert.* methods to verify that
expectations were met. Following this pattern consistently makes it easy
to revisit test code.
Example:
[TestMethod] public void should_be_able_to_add_two_numbers_together() { // Arrange int firstNumber = 1; int secondNumber = 2; Calculator calculator = new Calculator(); // Act var result = calculator.Add(firstNumber, secondNumber); //Assert result.ShouldEqual(3); }
This
makes it much easier to see:
- What is being set up and initialized in the arrange
section
- What method is being executed in the act section
- What determines the outcome of the test in the
assert section
This
pattern becomes even more important when using a mocking framework, which we will
be doing, using Moq, which I'll describe in my next post.
Subscribe to:
Posts (Atom)