Yesterday Windows Azure experienced a worldwide disruption in many services due to an expired PKI certificate for Windows Azure storage. Mary Jo Foley’s article Windows Azure storage issue: Expired HTTPS certificate possibly at fault provides the best coverage of the event as it unfolded. You can also take a look at a few threads on the Windows Azure forum and Stack Overflow that provide a lot of commentary on the event. The effects of this disruption rippled through most of the other Windows Azure services. Even if you modified your application to use HTTP instead of HTTPS it’s likely you still had issues given that the rest of the platform was crippled by the expired certificate.

It’s disappointing this happened but highlights a pretty common situation. This has nothing to do with the merits of the Windows Azure storage service or any other parts of the platform – this is an operations management issue, plain and simple. The irony is that, as a number of folks including Lars Wilhelmsen have pointed out, there are tools like Microsoft SCOM that provide a Certificate Management Pack that can notify operations of expiring certificates. I can’t imagine the operations team at Windows Azure doesn’t use some kind of tool to manage expiring certificates.

As a developer, I found myself curious to see just how hard it is to determine the expiration of a certificate by checking the URI. Turns out, it’s pretty simple by using System.Net.ServicePoint which provides connection management for HTTP/S connections.

private string GetSSLExpiryDate()
{
    string url = "https://www.aditicloud.com/";
    var request = WebRequest.Create(url) as HttpWebRequest;
    var response = request.GetResponse();

    if (request.ServicePoint.Certificate != null)
    {
        return request.ServicePoint.Certificate.GetExpirationDateString();
    }
    else
    {
        return string.Empty;
    }
}

Pretty simple. What’s hard is the practice of managing and tracking these sorts of things.

I would expect that Microsoft will ensure that this kind of problem never happens again. It’s embarrassing yet solvable. Yet it exposes an issue that most of us will also have to account for – expiring certificates. If it can happen to Microsoft, it can happen to us too.

I’m working on a Windows Phone project that requires me to surface up multiple RSS feeds as a single source. I needed a way to do this quickly and easily, and with a little help from friends on Twitter (particularly a suggestion from @bertcraven) I found a nice way to accomplish this using the SyndicationFeed in System.ServiceModel.Syndication.

I’ve detailed the steps below, but if you want to get to the heart of it then here’s the code to get this working:

SyndicationFeed mainFeed = new SyndicationFeed();
List<string> feeds = new List<string>();

feeds.Add("http://feeds2.feedburner.com/WadeWegner");
feeds.Add("http://www.nickharris.net/feed/");
feeds.Add("http://feeds.feedburner.com/ntotten");
feeds.Add("http://michaelwasham.com/feed/");
feeds.Add("http://blogs.msdn.com/b/hpctrekker/rss.aspx");

foreach (var feed in GetRssFeeds())
{
    Uri feedUri = new Uri(feed);
    SyndicationFeed syndicationFeed;
    using (XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri))
    {
        syndicationFeed = SyndicationFeed.Load(reader);
    }

    syndicationFeed.Id = feed;

    SyndicationFeed tempFeed = new SyndicationFeed(
        mainFeed.Items.Union(syndicationFeed.Items).OrderByDescending(u => u.PublishDate));
    mainFeed = tempFeed;
}

It’s really quite simple – once you know how to do it!

As you iterate through the list of feeds we use LINQ to union the feeds together – in the end this produces a main feed that has all the contents. Along the way we sort the elements in a descending order based on the PublishDate – otherwise you’ll just get blocks from each of the feeds and nothing is sorted according to the date publish. Once this is done you end up with a main feed that you can use.

For me I wanted to create a service that published the aggregated feed – I chose to use ASP.NET MVC 3 for this new feed. Here are steps you can follow in order to get this working in ASP.NET MVC 3.

  1. Create a new ASP.NET MVC 3 Web Application. I’ve called mine RssFeed
    NewProject
  2. Choose an Internet Application using the Razor view engine and HTML5 semantic markup.
  3. Add System.ServiceModel as a reference in the application. We’ll use this with SyndicationFeed.
  4. Create an empty controller. I’ve called mine the RssController
    RssFeed
  5. We’re going to define our own ActionResult implementation that can emit RSS by deriving from ActionResult. Inspiration and original source comes from this post on Developer Zen.
    public class RssActionResult : ActionResult
    {
        public SyndicationFeed Feed { get; set; }
    
        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.ContentType = "application/rss+xml";
    
            Rss20FeedFormatter rssFormatter = new Rss20FeedFormatter(Feed);
            using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
            {
                rssFormatter.WriteTo(writer);
            }
        }
    }
  6. We can now update the Index method to use the RssActionResult instead of the default ActionResult implementation.
    public RssActionResult Index()
    {
        return new RssActionResult();
    }
  7. Define a method that returns all the feeds with which you want to aggregate. You can pull from many different places – I recommend SQL Azure – but for the purposes of this demo you can just use a generic list of strings.
    private static List<string> GetRssFeeds()
    {
        List<string> feeds = new List<string>();
    
        feeds.Add("http://feeds2.feedburner.com/WadeWegner");
        feeds.Add("http://www.nickharris.net/feed/");
        feeds.Add("http://feeds.feedburner.com/ntotten");
        
        return feeds;
    }
  8. Now we can update our Index method to iterate through the feeds and aggregate them into a single SyndicationFeed that is sorted (descending) by the publish date.
    public RssActionResult Index()
    {
        SyndicationFeed mainFeed = new SyndicationFeed();
    
        foreach (var feed in GetRssFeeds())
        {
            Uri feedUri = new Uri(feed);
            SyndicationFeed syndicationFeed;
            using (XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri))
            {
                syndicationFeed = SyndicationFeed.Load(reader);
            }
    
            syndicationFeed.Id = feed;
    
            SyndicationFeed tempFeed = new SyndicationFeed(
                mainFeed.Items.Union(syndicationFeed.Items).OrderByDescending(u => u.PublishDate));
            mainFeed = tempFeed;
        }
    
        return new RssActionResult() { Feed = mainFeed };
    }
  9. Now, hit F5 and run. Browse to http://localhost:<port>/rss to see the aggregated RSS feed. 
    RssFeed

And that’s it!

There’s certainly more you can do with this – in fact, given the cost it takes to aggregate a large number of feeds, I’ve started to take the aggregated feed and store it in Windows Azure blob storage attached to the Content Delivery Network (CDN). The code to do this is similar to the following:

StringBuilder builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder))
{
    mainFeed.SaveAsRss20(writer);
    string rssFeed = builder.ToString();

}
// write to Windows Azure blob storage
You might consider doing something similar.
I hope this helps!

I spent a good deal of time this weekend importing hours and hours family videos off our Mini DV cassettes.  Lots of fun, and LOTS of video!  Based on the size of these files, I was quite close to running out of room on my Windows Media Center.  So, I decided to encode the files as WMVs.  Huge size reduction with very little quality loss.

I decided to use Microsoft Expression Encoder 3 – a great tool.  The best part is that there’s an SDK and set of assemblies that you can use in your own applications.

Note: if you are using a 64-bit machine, be sure to set the platform target of your application to x86, or else you will get compilation errors from the Encoder assemblies.

Below you’ll find the application I wrote.  Let me explain my goals:

  • Multi-thread the application to encode more than one video at a time.
  • Leverage the multitude of cores in my machine.
  • Limit the number of threads (I chose the core count as a baseline).
  • Use source video and audio source to reduce quality lose.

In order to do this, I had to do two things: 1) find a way to pass in the file name into thread, and 2) keep track of the number of threads and limit them to the number of cores in the machine.

I spent a bit of time looking for a good approach.  In the end, I chose to use the delegate ParameterizedThreadStart, which takes a parameter of type object.  This way, I can create a thread using an instance of this delegate instead of just ThreadStart, and the overload to Thread.Start allows me to specify a value that is passed to this new thread.  (Be careful, though, as it only accepts a single parameter (although it can be a collection) and isn’t type-safe.)  Additionally, with this approach I was able to leverage a counter, and sleep whenever the counter is going to exceed the number of cores in my machine.

Here’s all the code.  For this to function, I imported the following assemblies (yes, you need Expression Encoder 3):

  • Microsoft.Expression.Encoder
  • Microsoft.Expression.Encoder.Types
  • Microsoft.Expression.Encoder.Utilities
  • WindowsBase
// This method is used to look-up the core the thread is using
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentProcessorNumber();
 
static string inputFolder = @"C:tempVideos";
static string outputFolder = @"C:tempOutputVideo";
static int count;
static int maxNum;
 
static void Main(string[] args)
{
    // Start the counter at zero
    count = 0;
    // Grab the processor count
    maxNum = Environment.ProcessorCount;
    // Iterate through the AVI files
    foreach (var fileName in System.IO.Directory.GetFiles(inputFolder, "*.avi"))
    {
        // Sleep/wait for a core to free up
        while (count > (maxNum - 1))
        {
            Thread.Sleep(500);
        }
        // Increment the counter
        count++;
        // Create the thread with the delegate
        Thread t = new Thread(new ParameterizedThreadStart(EncodeFile));
        // Start the thread, passing in the file name
        t.Start(fileName);
    }
}
 
public static void EncodeFile(object ofileName)
{
    string fileName = (string)ofileName;
    MediaItem mediaItem = new MediaItem(fileName);
    mediaItem.OutputFormat = new WindowsMediaOutputFormat();
    // Use source video profile if available
    if (mediaItem.SourceVideoProfile != null)
    {
        mediaItem.OutputFormat.VideoProfile = mediaItem.SourceVideoProfile;
    }
    else
    {
        mediaItem.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile()
        {
            Size = mediaItem.MainMediaFile.VideoStreams[0].VideoSize,
            Bitrate = new ConstantBitrate(1000)
        };
    }
    // Use source audio profile if available
    if (mediaItem.SourceAudioProfile != null)
    {
        mediaItem.OutputFormat.AudioProfile = mediaItem.SourceAudioProfile;
    }
    else
    {
        mediaItem.OutputFormat.AudioProfile = new WmaAudioProfile();
    }
    // Create a job and the media item for the video we wish to encode.
    Job job = new Job();
    job.MediaItems.Add(mediaItem);
    // Set up the progress callback function
    job.EncodeProgress
        += new EventHandler<EncodeProgressEventArgs>(OnProgress);
    // Set up the completed callback function
    job.EncodeCompleted
        += new EventHandler<EncodeCompletedEventArgs>(job_EncodeCompleted);
    // Set the output directory and encode
    job.OutputDirectory = outputFolder;
    // Do not create a job subfolder
    job.CreateSubfolder = false;
    // Encode
    job.Encode();
}
 
static void job_EncodeCompleted(object sender, EncodeCompletedEventArgs e)
{
    // Decrement the counter
    count--;
}
 
static void OnProgress(object sender, EncodeProgressEventArgs e)
{
    // Write out information
    Console.WriteLine(
        count.ToString() + " : " +
        GetCurrentProcessorNumber().ToString() + " : " +
        System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " : " +
        e.Progress + " : " +
        e.CurrentItem.ActualOutputFileName);
}

 

Good stuff.

I’m running it from the console, so you will have to make some modifications if you want it to run in a more sophisticated application.  Works for me, though – I just start it up at the end of the day.  Here you can see the information that’s written out to the console (note the variety of cores leveraged):

Console Output

It’s fun to see my machine working this hard.  Every core is pegged.

Pegged Cores

Hope someone finds this useful.  Anyone see a better way to approach this?

Starflight I love gaming.  Long before the death match 95 tournament with Windows 95 that featured Bill Gates in a trench coat, I was playing computer games.  Two of the first games I remember playing were The Ancient Art of War and Montezuma’s Revenge – simple but fun.  I soon became a Sierra devotee, and devoured games such as Kings Quest, Heroes Quest (renamed Quest for Glory), Space Quest, Police Quest, and Leisure Suit Larry (just don’t tell my dad).  However, my favorite all time game was Starflight from Binary Systems – this game had everything: space battles, exploration, great story line, and it required strategy and a lot of invested time.

As an aside, I have seen the Starflight and Starflight 2 executables, along with some of the other games I’ve mentioned, floating around the Internet for awhile.  It is possible to use DOSBox – an x86 emulator with DOS – to play these games.

The common theme to all of this, of course, is that my gaming platform was the PC – while I had a Nintendo, I never really considered it a decent gaming platform.  All of the console platforms of the day – Sega, Atari, Nintendo – paled in comparison to the PC as a gaming platform.  Even today, I prefer the PC to a console.  Despite this prejudice, I have come to love my Xbox 360 – not only is it a great gaming platform, but it’s the media hub of our entire house.

XNAFor a long time I’ve wanted to try my hand at making a game, but I’m a developer not a designer.  Additionally, I know nothing about DirectX, OpenGL, and other multimedia/gaming APIs.  While I’ve known about the XNA since it released in 2006, I never made the time to try it out. For those of you that aren’t familiar with XNA, it’s a framework with a set of tools that facilitates the development and management of computer games.  The best part is it uses C#!

Now, there’s a lot that goes into making a game.  I’m a complete noob, and I’ll try to share the things I learn on this blog as I go.  As I see it, the first step is actually getting your tools and environment setup.  It is this process that I intend to outline in this article.  The process is a bit confusing, but what I’ve been able to piece together are the following three steps:

  • Setting up your XNA account
  • Configuring your Xbox
  • Deploying your first “game”

I should also mention that my goal here is to build and deploy a “game” to the Xbox 360.  This may seem contradictory given my stated preference for the PC above, but there’s more to the Xbox 360 than just games, and eventually I’d like to build applications for the Xbox (not just games).

Setting Up Your XNA Account

The first thing to do is get your XNA account all setup.  This allows you to deploy games to your Xbox 360.  It will also cost a little $$.

1. Download XNA Game Studio 3.1.  I grabbed it via my MSDN membership, but I believe you can find it elsewhere too.  You can get it for Visual C# Express here.

2. Go to the XNA Creators Club Online and setup an account.  Note: It’s very important that you use the same account that’s associated to XBOX Live.  Review the different membership options – you will start off as Registered (after creating an account) and you want Premium.

XNA Membership Options

4. Sign up for Premium Membership.  There area  few ways to do this – if you’re lucky enough to have a Redeem Code, then use it here.

XNA Membership Types

5. After you have setup your membership, verify by selecting Creators and choose My Profile.

My Profile

6. Your membership should now be premium.

My Profile - Premium

While straightforward, I never found this process nicely spelled out and defined.

Configuring Your Xbox

The next thing to do is setup your Xbox such that you can deploy your games to it.  This one took me a bit longer to figure out because of all the various steps.

1. Go to your Xbox 360 and turn it on.

2. Log into your Xbox Live account on your Xbox 360.  Remember how you used the same Live ID in step #2 above?  This is why you did so.

3. The next step is to setup the XNA Game Studio Connect software on your Xbox .  Follow these steps:

  • Select Game Marketplace
  • Select Explore Game Content
  • Select Browse
  • Select title X
  • Select title XNA Creators Club
  • Select All Downloads
  • Select XNA Game Studio Connec
    t
  • Select Confirm Download
  • Select Play Now

4. The application will provide you a connection key that you’ll use to register your Xbox with your development environment.  Write down the key.

5. Return to your development machine.

6. Open up the XNA Game Studio Device Center.

7. Click Add Device.

Add Device

8. Select the XBOX 360 icon.

XBOX 360

9. Choose an Xbox 360 Name.

Name

10. Enter the connection key you wrote down.

Connection Key

11. When you’re complete, click Finish.  You should now see your Xbox as a listed device.

XNA Game Studio Device Center

Okay, everything’s setup.  Now to build and deploy a game.

Deploying Your First “Game”

1. Take a look at this great “Hello World!” in XNA post by Nezeeh.  Follow the steps – they are very simple.

2. Ensure that the XNA Game Studio Connect application is still running on your XBOX.

XNA Game Studio Connect

3. Deploy your application from Visual Studio.  It will push the package to the XBOX 360 and should look something like this:

Hello World!

And there you have it!  Your “game” is running.  I apologize for the poor quality pictures – I used my phone as it was easy and available.

All in all, this process shouldn’t take you more than an hour.  I spent about three hours trying to figure it all out, but I guess I’m just slow.  I hope you find this valuable.

Happy gaming!