Your seat in the clouds awaits you

Ce billet de blog est également disponible en français ici.

Back in November 2011 easyJet announced that starting in the spring of 2012 we would begin a trial of allocated seating and on April 12th we went live on five routes from London Luton and Glasgow. Since then we have gradually extended this trial and we are now offering allocated seating on almost all routes on our network and by the end of November we will be at 100% operational delivery. This is a huge change for easyJet. Free seating, referred to by many of our passengers as “the scrum”, was part of our DNA. It was how we had always operated. It had become part of the definition of easyJet. As our CEO Carolyn McCall said in the article above, the trial could only be deemed successful if it met all three of the following criteria:

1. It had to increase customer satisfaction. We work hard to have happy customers. It’s another thing that’s part of our DNA. Allocated seating had to really make a difference to the passenger experience. Many people said that they wanted it but, once we gave it to them, would it really make the difference they thought?

2. It had to work operationally. easyJet operates one of the quickest turn-around times in the industry. If boarding passengers into allocated seats was seen to have a negative effect on our On Time Performance (OTP) it would not have been considered viable.

3. It had to work commercially. Allocated seating had to prove itself a commercial success as a revenue generating product.

Trial by fire

This highlights the fact that such a move was a calculated risk. We were not sure it would work but it required significant change and investment to find out. One of the major changes was to our reservation system. Our home-grown reservation system did not support allocated seating. The primary advantage of maintaining a bespoke system is that it can be tailored to your exact business needs. No extraneous functionality cluttering up the works. It does, on the other hand, support bookings from around 58 million passengers a year and take over £4 billion in revenue.

Changing the beating heart of our enterprise, our various sales channels like easyJet.com and our operational systems to support allocated seating was no small undertaking, quite apart from the changes to our operational processes. Making those changes to support a trial, an experiment? That called for a quite special approach.

Our first decision was that we definitely did not want to have to conduct open-heart surgery on our reservation system to add this functionality. The I/O load from selling 58 million non-specific seats a year is already a veritable fire-hose. Scaling and refactoring to support the tracking and locking of over 58 million specific seats on a system that can book up to 1500 seats a minute would be a huge project.

“Seat-allocation-as-a-service”

Would it be possible, we wondered, to buy “seat-allocation-as-a-service” (SaaaS?) from a third party? Get someone else to do the heavy lifting of tracking the availability of every single seat we have on sale while we just stored the output, a few bytes that represented the selections made for the seats we have actually sold?

Apparently not. However the idea of a separate “seat-allocation-as-a-service” solution attached via a very light-weight integration was too attractive to let go so we decided to build our own.

What this means, in summary, is that the tens of millions of seats we have available at any given time are tracked via partitioned SQL Azure databases and cached in the Azure AppFabric Cache. All the logic, business rules and data relating to …

  • selecting seats
  • handling contention for seats
  • aircraft types
  • seating layouts and configurations
  • price bands
  • which passengers can sit where
  • seating access for passengers with restricted mobility
  • algorithms for automatically allocating seats to passengers who chose not to make a selection
  • and the million-and-one other things that have to be taken into consideration when seating an aircraft

…all this is done in the cloud. Even the interactive UI that displays the graphical map of the aircraft is served from Azure and injected into the booking pages on easyJet.com.

seating

The ingenious work to achieve this using JSONP, Ajax and Knockout.js (amongst other things) is a tribute to the fantastic development team at easyJet and may be the subject of a subsequent blog post.

The overall approach however has allowed us to implement an incredibly significant change to the way we operate and sell our flights and deliver it at massive scale without needing to implement much more than small refactorings in our core operational and retail systems. The low cost and massive scale of Azure has made the whole notion of experimenting with something so fundamental an achievable reality. This calculated risk has become a bet we can much more easily afford to make.

Most importantly it has massively reduced the cost of failure. We had to conduct a thorough trial. We couldn’t be sure that it would work. Whether it worked or not was primarily a business decision rather than a technical one.

Now that it has been successful we have delivered a solution that works technically, works operationally, works commercially, improves customer experience and transformed our enterprise. However, if it had not worked and we had needed to turn it all off and walk away, we could have done so without having incurred huge risk, technical debt or cost.

Advertisements

Tablet History

Azure Service Bus

Azure Service Bus : Connect All the Things !

GOTCHA : Using Silverlight with the Azure AppFabric Access Control Service (ACS)

Version 2 of the Azure AppFabric Access Control Service now serves up a proper ClientAccessPolicy.xml file to Silverlight clients. Here is what you used to get under version 1 if you went to

https://yournamespace.accesscontrol.windows.net/clientaccesspolicy.xml

<access-policy>
	<cross-domain-access>
		<policy>
			<allow-from http-request-headers="*" http-methods="*">
				<domain uri="https://*"/>
				<domain uri="http://*"/>
			</allow-from>
			<grant-to>
				<resource path="/" include-subpaths="true"/>
			</grant-to>
		</policy>
	</cross-domain-access>
</access-policy>

Here’s what you get now :

<access-policy>
	<cross-domain-access>
		<policy>
			<allow-from http-request-headers="*" http-methods="*">
				<domain uri="https://*"/>
				<domain uri="http://*"/>
			</allow-from>
		<grant-to>
			<resource path="/WRAPv0.9" include-subpaths="true"/>
			<resource path="/v2/OAuth2-13" include-subpaths="true"/>
			<resource path="/v2/wstrust" include-subpaths="true"/>
			<resource path="/v2/wsfederation" include-subpaths="true"/>
			<resource path="/v2/mgmt/service" include-subpaths="true"/>
			<resource path="/FederationMetadata/2007-06/FederationMetadata.xml" include-subpaths="true"/>
			<resource path="/v2/wstrust/mex" include-subpaths="true"/>
			<resource path="/v2/metadata/IdentityProviders.js" include-subpaths="true"/>
		</grant-to>
		</policy>
	</cross-domain-access>
</access-policy>

Here’s the gotcha : this may break previously working code because Silverlight considers those paths to be case sensitive !

If you call the ACS from Silverlight and try to get a simple web token from the WRAP endpoint by calling https://yournamespace.accesscontrol.windows.net/WRAPV0.9 you will get a Silverlight security exception BEFORE Silverlight even attempts to make the call. Basically it will get the client access policy, compare the URL to the permitted resource paths and then throw an exception because /WRAPV0.9 does not match /WRAPv0.9. It will not give you ANY CLUES !

More video…

I just found this video while I was looking for easyJet-related resources on the web. Hadn’t even realised it had been filmed. I gave this talk at BAFTA for a Microsoft event called Migrating Businesses to the Cloud. Pretty nerve-wracking as the other speakers were Bob Muglia and David Chappell; tough acts to follow by anyone’s standards.

UKTechDays 2011 : My Talk on easyJet’s use of Cloud Technology

I gave a talk at UKTechDays last month on how easyJet had evolved from its start-up style, D.I.Y IT, though managed services to cloud. Thanks to everyone who came and for the great feedback. The video is now up on the UKTechDays website : http://uktechdays.cloudapp.net/techdays-live/every-cloud-has-an-orange-lining-how-easyjet-is-making-cloud-work.aspx.

Implementing a REST-ful service using OpenRasta and OAuth WRAP with Windows Azure AppFabric ACS.

I’ve been building prototypes again and I wanted to build a service that exposed a fairly simple, resource-based data API with granular security, i.e. some of my users would be allowed to access one resource but not another or they might be allowed to read a resource but not create or update them.

To do this I’ve used OpenRasta and created an security model based on OAuth/WRAP claims issued by the Windows Azure AppFabric Access Control Service (ACS).

The client can now make a rest call to the ACS passing an identity and secret key. In return they will be issued with a set of claims. A typical claim encompasses a resource in my REST service and the action(s) the user is allowed to perform, so their claim set might show that they were allowed to execute GET against resource foo but not POST or PUT.

In my handler in OpenRasta I add method attributes that indicate what claims are required to invoke that method, for instance in my handler for resources of type foo I might have the following method  :

[RequiresClaims("com.somedomain.api.resourceaction", "GetFoo")]
public OperationResult GetFooByID(int id)
{
	//elided
}

In my solution I have created an OpenRasta interceptor which examines inbound requests, validates the claim set and then compares the claims required by the method attribute to the claims in the claim set. Only if there is a match can the request be processed.

After a few tweets with @serialseb I refactored the above into an IAuthenticationScheme that validates the claims, leaving the original OperationInterceptor to check the claims required by the method to be invoked. I also added an extension method so that the whole thing can be fluently configured like so :

ResourceSpace.Uses.AzureClaimsAuthenticationScheme();

I was going to write a long blog post about how to build this from scratch with diagrams and screen shots and code samples but I found that I couldn’t be arsed. If you’d like more info more on how to do this just drop me a line. In the meantime I’ve dropped the source files as follows :

Amazon recommends…

Hi Bert, this is the Amazon Recommendation Selection Engine or A.R.S.E. Today we would like to recommend :

  1. Things you have already bought from us because you can never be too careful or have too much stuff.
  2. Things that are almost identical to things you have already bought from us because, God knows, once you bought a second one of the thing you already bought a third slightly different one will be hard to resist.
  3. Things you have already bought as gifts for other people and that were obviously gifts because they were completely outside of your known buying patterns.
  4. Things that are almost identical to things you already bought as gifts for other people just in case they need two of everything too.
  5. Things that you looked at accidentally or only because someone sent you a link entitled “LOL! Look at this ridiculous, furry, raccoon-head ski helmet“.
  6. Things that are similar to ridiculous, furry, raccoon-head ski helmets but probably a lot less LOL.
  7. 1 item that is completely inexplicable.

Basically I think that the A.R.S.E is an algorithm modelled on the Junk Lady from the film Labyrinth.

Feeling the pinch

My broadband is getting worse and worse. When I moved into this house 5 years ago I got 4 mbps from an 8 mbps service because I am 1962 metres from my exchange. I’m pretty sure I haven’t got any further from my exchange in the last few  years but I just ran some speed tests and they make depressing reading. Basically, my Vodafone 3G is now faster than my broadband.

5 years ago I was with Bulldog. Bulldog got bought by Pipex who got bought by Tiscali who I think have now been acquired by TalkTalk or something. Either way I’m getting the shitty end of this market consolidation stick. Last time I complained they actually admitted that as part of one of the mergers I was downgraded from ADSL2+ to regular ADSL as part of an “exchange modernisation programme”. Now I’m just waiting for them to deliver my penny-farthing and take my car away as part of a “transport modernisation programme".

Here’s the news :

Network Download (mbps) Upload (mbps)
Broadband 1.45 0.42
O2 PAYG 3G 0.78 0.48
Vodafone Contract 3G 2.02 1.26

Even crappy O2 pay-as-you-go internet beats my broadband for upload speed 😦

Scrummerfall

Scrummerfall. n. The practice of combining Scrum and Waterfall so as to ensure failure at a much faster rate than you had with Waterfall alone. – Brad Wilson.

I like this definition 🙂

%d bloggers like this: