Monthly Archives: January 2013

Cancel CancellationTokenSource after a timeout

Maybe you already discovered it. But in .NET 4.5 the CancellationTokenSource class has a new method CancelAfter. It allows you to signal cancellation after a specified interval aka timeout.

In .NET 4 you’d have to Wait on a Task to complete or not and if not, do the cancellation. This might go little bit off control if you have a bunch of tasks. In .NET 4.5 a handy Task.Delay was added and with await/async it was easier. But still.

Setting a timeout and basically forgetting about it is a nice little help, that will make the code little more clean and easier to comprehend.

Custom encryption of field with Entity Framework

Yesterday there was a good question on Twitter with #efhelp hashtag. The core is about using Entity Framework to store entities, that store the properties encrypted somehow. So it’s custom encryption on client side (not on server). Of course, I could take Entity Framework sources and modify some file, but I wanted to do it with official release. The assumption I’m working with is that the entity itself knows how to encrypt and decrypt data (another valid approach might be that the DbContext does that).

The problem is, that the entity itself doesn’t know when it’s providing data to EF’s code (and hence it should be encrypted) and when to “normal” code (unencrypted). But we can kind of get this info (except looking at stack trace, which might be very slow). I used similar approach as I did few years back with validation, before it was added directly to EF’s API.

Here’s the code:

class MyContext : DbContext
{
	public MyContext()
		: base(@"server=(localdb)\mssql;integrated security=true;database=test;")
	{ }

	public IDbSet<SuperSecured> SuperSecured { get; set; }

	public override int SaveChanges()
	{
		var secured = this.ChangeTracker.Entries()
			.Where(x => x.State == EntityState.Added || x.State == EntityState.Modified)
			.Where(x => x.Entity is ISecured)
			.Select(x => x.Entity as ISecured)
			.ToArray();
		foreach (var item in secured)
		{
			item.Unlock();
		}
		try
		{
			return base.SaveChanges();
		}
		finally
		{
			foreach (var item in secured)
			{
				item.Lock();
			}
		}
	}
}

interface ISecured
{
	void Lock();
	void Unlock();
}

class SuperSecured : ISecured
{
	const string EncryptedStringPrefix = "X";

	bool _locked;

	public SuperSecured()
	{
		_locked = true;
	}

	public int ID { get; set; }
	public string Name { get; set; }
	string _topSecret;
	public string TopSecret
	{
		get
		{
			return _locked
				? Decrypt(_topSecret)
				: _topSecret;
		}
		set
		{
			_topSecret = IsEncrypted(value)
				? value
				: Encrypt(value);
		}
	}

	public static string Encrypt(string s)
	{
		return EncryptedStringPrefix + new string(s.Reverse().ToArray());
	}

	public static string Decrypt(string s)
	{
		return new string(s.Remove(0, 1).Reverse().ToArray());
	}

	public static bool IsEncrypted(string s)
	{
		return s.StartsWith(EncryptedStringPrefix);
	}

	public void Lock()
	{
		_locked = true;
	}

	public void Unlock()
	{
		_locked = false;
	}
}
using (var ctx = new MyContext())
{
	if (ctx.Database.Exists())
		ctx.Database.Delete();
	ctx.Database.Create();
	ctx.SuperSecured.Add(new SuperSecured() { Name = "Testing", TopSecret = "This is not a palindrome ;) " });
	ctx.SaveChanges();
	ctx.SuperSecured.ToList().ForEach(x => Console.WriteLine("{0}|{1}", x.Name, x.TopSecret));
}

First a note. The “encryption” here isn’t smart even a little. It’s just to be there. Do not even think about using it. ;) So how it works?

Let’s start with SaveChanges method. This method looks, before doing any saving, for entities with ISecured interface (It might be good idea not to expose this interface to public, but it’s up to you. ;) ). Then every entity is switched to unlocked state. Unlocked means, that it will provide raw data, encrypted. Then the saving goes and finally the same entities (the collection is materialized before) are switched back to locked state. The locked and unlocked state is simply switching between providing clean decrypted data or raw encrypted data respectively. That’s for the saving.

What about reading. Here we don’t have a directly one place where this happens. So I used another trick that’s often used. Because what’s the problem here? We need to distinguish between user code storing some values (this data should be encrypted) and EF’s infrastructure storing values while materializing entities (this data is already encrypted). So the trick is to us some kind of flag or marker to recognize whether the data is encrypted or not (again my implementation is way too dumb, just proof of concept). If so, store it as is, it’ll decrypted in getter. Else encrypt.

Nothing magical, right? :) Feel free to comment and/or improve.

Gopas DevCon 2013 (Praha, Bratislava)

Velmi jednoduše. Středa 23. ledna 2013 v Praze. A repete v Bratislavě čtvrtek 31. 1. 2013. Více info.

Moje přednáška na téma Entity Framework 5, 6 a dále – využijte nové možnosti naplno.

Entity Framework prošel v posledních měsících, možná i letech rychlým vývojem a přinesl mnoho nových, někdy i nečekaných funkcí. Nejen že se jedná o plnohodnotný OR mapper, ale začíná nabízet i mnoho „jemných“ funkcí a funkcí, které doplňují celý vývojový cyklus spojený s databází. Zkusme se na ně společně podívat. Třeba zjistíte, že některé nástroje vůbec nepotřebujete a můžete využít přímo .NET Framework resp. Entity Framework.

Budu se na vás těšit.

Prezentace

My migration process from Exchange 2010 to Exchange 2013 on SherWeb

I’m a long time customer of SherWeb. I’m with them almost since they started offering hosted Exchange and I like it. Great service (uptime, antispam, performace, …). I migrated from Exchange 2007 to 2010 and now the time brought me to 2013. Currently there’s no automated click-in-admin-panel solution available, hence you have to do a lot of stuff “manually”. And a lot of things can go wrong. If you’re a huge company, with thousands of mailboxes, you’ll probably need more advanced/automated process than me with few of mailboxes.

My preparation took about two hours. And of course I wanted to do everything without any email loss and so on. First I started thinking about it. Not because I’m unhappy on Exchange 2010, but why not to try Exchange 2013, especially if it’s hosted, thus not much work for me (except the migration of course). Then I sketched it in my head and asked sales person to enable the Exchange 2013 in my client section. After that was done, it was all on my shoulders. So here’s the process.

  1. Create same users and mailboxes on 2013 as you had on 2010. You can do it manually or import from file in SherWeb’s admin panel. I did it manually. Partly because I have few users and partly because I wanted to see whether is there something new to learn about.
  2. Log in to new mailboxes. Just to init everything.
  3. Then I disconnected all mobile devices. I simply removed the account. To start clear.
  4. I changed all DNS records, except the one for autodiscover.
  5. Wait. :)
  6. In admin panel you can see number of items in mailbox for selected user. As the DNS records start propagating you’ll emails coming to new mailbox (and you’ll also see your old mailbox being silent). Give it a more time, just to be sure majority has new DNS records (this may be up to few days, based on your TTL and real refresh rate of other DNS servers).
  7. Export current mailbox(es) to PST. Close Outlook.
  8. Activate “data import” in admin panel. This will give you FTP account where to upload the PST(s).
  9. Upload PST(s).
  10. Refresh the page mentioned in 7.
  11. Check the matching of filenames and users, correct if needed and start import. This will probably take a while. You could probably do it with Outlook as well, copying all items to new location, but I thought this could be faster.
  12. Change the DNS record for autodiscover and wait again (or force your local DNS server to refresh, if you have one).
  13. Wait for import to finish.
  14. Delete the current profile for Outlook and add new. You’ll get all the information from already available autodiscover.
  15. Outlook starts fetching emails from mailbox on 2013. And also the new emails are there waiting for you. :)

Enjoy. After some testing (give it a few days) you can terminate your old Exchange 2010 contract.

This process worked for me. I tried to avoid any potential traps, but your mileage may vary. Use your brain. Always have working backups.

Timestamp property on Windows Azure Table entity

Every entity in Azure Table Storage has PartitionKey, RowKey and Timestamp property. PartitionKey gives the “bucket” where the entity will be stored (entities in one partition can be on more machines, though). And the RowKey is simply the key of that row. Queries where you’re matching both keys are fast. Matches inside partition (you know PartitionKey but only part (or none) of RowKey) are slower. Cross partition matches even slower. You get the idea. But what about the Timestamp?

The Timestamp property is maintained by server and it’s the time the entity was last modified. Simple as it is. Because the property is always there, I thought it would be good to actually use it. But it’s not. This property is not being “indexed” (not even slightly :) ) or anything like that. That means any query including condition on it will be as slow as table scan (or any other property condition). And that’s something very very slow, especially if you have dozens of partitions with millions of records and you’re doing range condition (not mentioning the limit on one batch for result).

And I learned that by my experience. :) Because the secondary indices are not here yet, the only option, if you’re doing really a lot of queries based on date&time/last modified to (ab)use RowKey (or build and maintain secondary index yourself).

You might wonder how to create such secondary index. Easy, like in 1980s. You already have table (BTW did you noticed, how easy is to store something into table, but it’s order of magnitude harder (read slower) to get something from it, except if you’re doing PartitionKey&RowKey exact match?), if the inserts/updates/deletes are not super fast and you’re not fighting for throughput you can compute the key for secondary index directly while doing the operation and store it in another table with both keys from original table. But if you need the operation to be super fast, you can just put the data into queue message (if it’s too big for message (64kB in Jan 2013) you can put the data into blog and store just reference to blob) and use worker role(s) to process the data, compute secondary keys and insert/update/delete into table(s). Boring? Yes. Old school? Yes. But Azure Table Storage isn’t exactly smart storage, but it scales. :)

Let’s hope secondary indices (even stale would be good) will be added in the future.

TaskCanceledException on timeout on HttpClient

.NET Framework has a nice new class for all sort of HTTP stuff called HttpClient (interesting the name wasn’t taken before :) ). And because it’s I/O related it has also bunch on XxxAsync methods to nicely fit into C# 5′s async/await.

So you might write code similar to this, based on experience based on previous “network” classes.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200); //adjust based on your network
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
catch (TimeoutException)
{
	// handle somehow
	Console.WriteLine("TimeoutException");
}

If you try to run it, you’ll get unhandled exception, TaskCanceledException to be precise. Yep, the timeout is not propagated as TimeoutException, but as TaskCanceledException. It caught me off guard a little bit. The documentation for Timeout property touches CancellationTokenSource and you can feel the steer to TaskCanceledException. But, still, could be mentioned explicitly, will not be that surprising. Or maybe my thinking was skewed.

This code then works correctly.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200);
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
//catch (TimeoutException)
//{
//	// handle somehow
//	Console.WriteLine("TimeoutException");
//}
catch (TaskCanceledException)
{
	// handle somehow
	Console.WriteLine("TaskCanceledException");
}