<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>.Net Jonesie</title>
  <link rel="alternate" type="text/html" href="http://jonesie.net.nz/" />
  <link rel="self" href="http://jonesie.net.nz/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2010-07-20T04:29:33.21225-05:00</updated>
  <author>
    <name>Peter G Jones</name>
  </author>
  <subtitle>A simple programmers blog</subtitle>
  <id>http://jonesie.net.nz/</id>
  <generator uri="http://dasblog.info/" version="2.3.9074.18820">DasBlog</generator>
  <entry>
    <title>Thanks again Apple :(</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/07/20/ThanksAgainApple.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,94a2b090-fd26-464d-b14c-32f877002235.aspx</id>
    <published>2010-07-20T04:29:33.21225-05:00</published>
    <updated>2010-07-20T04:29:33.21225-05:00</updated>
    <category term="I Hate Apple" label="I Hate Apple" scheme="http://jonesie.net.nz/CategoryView,category,IHateApple.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
If your like me and made the mistake of upgrading your iPhone 3G to OS 4 then found
your phone is – to be blunt – fucked, you can actually reverse the update.
</p>
        <p>
See here for the story: 
</p>
        <p>
          <a href="http://www.stuff.co.nz/technology/gadgets/3937179/iPhone-3G-crippled-by-software-update">http://www.stuff.co.nz/technology/gadgets/3937179/iPhone-3G-crippled-by-software-update</a>
        </p>
        <p>
 
</p>
        <p>
See here for the remedy: 
</p>
        <p>
          <a href="http://www.lifehacker.com.au/2010/06/how-to-downgrade-from-ios-4-to-iphone-3-1-3/">http://www.lifehacker.com.au/2010/06/how-to-downgrade-from-ios-4-to-iphone-3-1-3/</a>
        </p>
        <p>
 
</p>
        <p>
Apple Score: Love – 0 , Hate - 5
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=94a2b090-fd26-464d-b14c-32f877002235" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SharePoint 2010 Custom Timer Jobs</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/05/05/SharePoint2010CustomTimerJobs.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,83274683-123b-47e3-b4f1-ee46d47fb318.aspx</id>
    <published>2010-05-05T16:56:27.690875-05:00</published>
    <updated>2010-05-05T16:56:27.690875-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been working on a sample app for SharePoint 2010 that demonstrates the Sync Framework,
Custom Service Applications and a Custom Timer.
</p>
        <p>
There’s a few good articles on <a href="http://msdn.microsoft.com/en-us/library/cc406686.aspx" target="_blank">MSDN</a> and <a href="http://www.andrewconnell.com/blog/articles/CreatingCustomSharePointTimerJobs.aspx" target="_blank">elsewhere</a> that
document the process of creating a custom timer job pretty well.  This hasn’t
changed much in 2010 – if at all – from what I can see.  However, the samples
don’t show you how to create a Service/Server level job definition, so here’s my small
addendum to show how to do this.
</p>
        <p>
          <strong>Creating a Service Job</strong>
        </p>
        <p>
When you construct a new job definition – custom or otherwise – there are two constructors
you use:
</p>
        <blockquote>
          <p>
protected SPJobDefinition(string name, SPWebApplication webApplication, SPServer server,
SPJobLockType lockType);
</p>
          <p>
protected SPJobDefinition(string name, SPService service, SPServer server, SPJobLockType
lockType);
</p>
        </blockquote>
        <p>
You can override the constructors in your custom job.  For a service timer you
should use the 2nd constructor.  In this case, the lockType can only be Job or
None.
</p>
        <p>
          <strong>Persisted Configuration</strong>
        </p>
        <p>
If you take a look at the definition of SPJobDefinition you will notice that it inherits
SPPersistedObject.  The MSDN sample talks about creating a separate persisted
object for the job configuration data.  This is not necessary.  Instead,
you can add your [Persisted] public fields directly to your custom job definition.
</p>
        <p>
          <strong>Errors</strong>
        </p>
        <p>
When you run a timer job that is created for a service, the service must be running
– yes, strangely :)  If it’s not the job will fail silently and you have to look
in the logs to see the error.  There doesn’t seem to be any way to catch this
exception.
</p>
        <p>
          <strong>Weirdness</strong>
        </p>
        <p>
I managed to waste about 3 hours trying to track down why timer execution of my service
method was failing when calling it directly would work.  There is no special
logic in the timer.  The bug I was seeing was something that I had fixed previously
so I was baffled why it was failing for the timer and not for my web page.
</p>
        <p>
Overnight, and after a few IISResets, redeployments and reboots, it came right and
now works correctly.  I also made sure the GAC was cleared out between deployments. 
It seems to me like there was an old version of the service application dll that the
timer was using and the rest of the site wasn’t.  I cant prove this but that’s
certainly how it appeared.
</p>
        <p>
          <strong>Debugging</strong>
        </p>
        <p>
As Andrew Connell points out in his articles, you need to fire an Assert() to get
the debugger to stop in the job Execute() method.  
</p>
        <blockquote>
          <p>
#if DEBUG<br />
            System.Diagnostics.Trace.Assert(false);<br />
#endif
</p>
        </blockquote>
        <p>
Attaching to OWTIMER.exe is not enough.  However, for me, this Assert does not
popup a message – you need to attached to OWTIMER first.  This maybe a SP or
VS 2010 thing.
</p>
        <p>
 
</p>
        <p>
Enjoy :)
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=83274683-123b-47e3-b4f1-ee46d47fb318" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SharePoint 2010 Launch</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/26/SharePoint2010Launch.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,deb63605-160a-46b6-9789-833c833d7339.aspx</id>
    <published>2010-04-25T23:46:39.039375-05:00</published>
    <updated>2010-04-25T23:46:39.039375-05:00</updated>
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The SP User Groups are organising a nation wide launch party for SharePoint 2010 on
May 13.  If your interested then register here: <a href="http://www.dot.net.nz/Lists/SharePoint2010Survey/overview.aspx">http://www.dot.net.nz/Lists/SharePoint2010Survey/overview.aspx</a></p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=deb63605-160a-46b6-9789-833c833d7339" />
      </div>
    </content>
  </entry>
  <entry>
    <title>64 bit… but not quite</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/20/64BitButNotQuite.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,1154957d-2421-420d-baef-c6392166d272.aspx</id>
    <published>2010-04-20T10:05:44.729125-05:00</published>
    <updated>2010-04-20T10:06:08.776-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <category term="Visual Studio" label="Visual Studio" scheme="http://jonesie.net.nz/CategoryView,category,VisualStudio.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been enjoying the stability and extra performance of a 64 bit OS for about 2
years now so I am surprise and somewhat disappointed that the latest round of goodness
from Microsoft – i.e. SharePoint 2010, Office 2010 and Visual Studio 2010 have some
annoying incompatibilities in this mode.
</p>
        <p>
          <br />
        </p>
        <p>
Datasheet View of  a SharePoint list with a 64 bit version of Office does not
work, you just get this annoying dialog:
</p>
        <p>
          <a href="http://jonesie.net.nz/content/binary/WindowsLiveWriter/64bitbutnotquite_2B7F/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jonesie.net.nz/content/binary/WindowsLiveWriter/64bitbutnotquite_2B7F/image_thumb.png" width="240" height="117" />
          </a>
        </p>
        <p>
Apparently this is because the ActiveX control is not available for 64 bit OS’s. 
I have only tested on 2008 R2 server – Windows 7 64 bit may be ok.
</p>
        <p>
Also, Intellitrace in Visual Studio – aka Historical Debugging - does not support
SharePoint (or any 64 bit app?).
</p>
        <p>
I’m sure Microsoft are aware of these limitations and will offer solutions in due
course – but really, 64 bit has been coming for a while and I think we can expect
not to see this sort of incompatibility, especially for Office.  
</p>
        <p>
For me this has tarnished my experience only a tad, but overall, 64 bit everywhere
is better than 32 bit in the same way that cake is better than two week old bagels.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=1154957d-2421-420d-baef-c6392166d272" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Grrrrrr.  Nothing makes me madder than this</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/15/GrrrrrrNothingMakesMeMadderThanThis.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,b7ea2747-0af0-46af-89b8-6d7d9fe5eb5d.aspx</id>
    <published>2010-04-15T15:33:50.4953064-05:00</published>
    <updated>2010-04-15T15:33:50.4953064-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Old news I guess but it takes a while for things to filter down sometimes.
</p>
        <p>
From the latest iPhone SDK license:
</p>
        <blockquote>
          <p>
Applications may only use Documented APIs in the manner prescribed by Apple and must
not use or call any private APIs. Applications must be originally written in Objective-C,
C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and <strong>only
code written in C, C++, and Objective-C may compile and directly link against the
Documented APIs</strong> (e.g., Applications that link to Documented APIs through
an intermediary translation or compatibility layer or tool are prohibited).
</p>
        </blockquote>
        <p>
This appears to kill MonoTouch and many other platforms such as Adobe’s attempt to
get flash on the iPhone.
</p>
        <p>
As a user of the iPhone this probably wont make much difference to me as I don’t use
a lot of the crappy little apps.  As a human being – and more importantly – as
a software developer – this makes me madder than hell.
</p>
        <p>
I believe that Apple have taken the place of the most evil software company on the
planet.  Don’t let anyone tell you otherwise.  They have always been evil
and until Steve Jobs has gone for good, they have no chance of being honest or decent.
</p>
        <p>
As soon as I can get my hands on a Windows Phone 7 Series, the iPhone goes into the
blender! (or to my daughter more likely – she more interested in cool than political
correctness).
</p>
        <p>
 
</p>
        <p>
Rant over.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=b7ea2747-0af0-46af-89b8-6d7d9fe5eb5d" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Creating a SharePoint 2010 Service Application</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/12/CreatingASharePoint2010ServiceApplication.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,57fc986b-eb47-4ffc-925f-1227c97c81ff.aspx</id>
    <published>2010-04-11T21:55:16.72575-05:00</published>
    <updated>2010-04-11T21:55:16.72575-05:00</updated>
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m in the deep end at the moment.  SharePoint 2010 provides an improved mechanism
for service applications that replaces Shared Service Providers.  I’m not ready
to say I understand how these beasts (and they are a beast) work yet, but I can tell
you that at this early stage of the 2010 release cycle (i.e. very nearly RTM) there
is bugger-all documentation available.  The following list may prove useful if
you want to get started learning this.
</p>
        <p>
 
</p>
        <p>
Andrew Connell has a video and some sample code from <a href="http://channel9.msdn.com/learn/courses/SharePoint2010Developer/ServicesArchitecture/CreatingCustomServiceApplications/" target="_blank">Channel9</a>. 
The video is very hard to watch but there are a few tid-bits that may prove useful. 
The sample code is also useful but not as complete as I’d like (for the client end
there is only a powershell script to test). 
</p>
        <p>
          <a href="http://sharepointsolutions.com/sharepoint-help/blog/index.php/2009/10/building-a-sharepoint-service-application-to-provide-auto-completion-services-for-ajax-enabled-rich-user-controls-%E2%80%93-part-1/#partone" target="_blank">Tony
Bierman</a> has a 4 part series that steps through the process and explains the various
files in some detail, but again, this is not totally complete (there are no sample
PS scripts) and the example is unusal (a web service for autocomplete).  Plus
he has added a few extra features to the code which are useful I’m sure – but confusing
when you are learning.
</p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ee536537(v=office.14).aspx" target="_blank">MSDN</a> of
course has a bunch of sample and documentation – but this seems to be the most incomplete
version I have found – I’m sure it will improve when SharePoint is actually released.  <a href="http://blogs.msdn.com/sridhara/archive/2010/04/03/custom-service-applications-in-sharepoint-2010.aspx" target="_blank">Sridhar
Raghunathan</a> has posted a fixed version of this sample but it is also somewhat
incomplete (no admin pages or deployment scripts).
</p>
        <p>
There is another one <a href="http://www.harbar.net/articles/sp2010sa.aspx" target="_blank">here</a> that
I haven’t looked at.
</p>
        <p>
I also got my hands on a presentation and some training kit material (not public yet
sorry) which helped a bit.
</p>
        <p>
My current solution is a blend of all of these samples – which are generally similar. 
How I just need to make it work.
</p>
        <p>
More later…
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=57fc986b-eb47-4ffc-925f-1227c97c81ff" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SharePoint 2010 Replaceable Parameters</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/07/SharePoint2010ReplaceableParameters.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,154fd9d6-fa1f-4968-a307-f007c4b98d6a.aspx</id>
    <published>2010-04-07T17:05:37.734375-05:00</published>
    <updated>2010-04-07T17:05:37.734375-05:00</updated>
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Loving SharePoint 2010 :) We are doing a LOT of work with this baby and so far it’s
been a fairly painless experience.  I’m currently diving deep into creating a
custom Service Application… more on these later.
</p>
        <p>
It’s the little things that make the difference for day to day SharePoint dev. 
Replaceable parameters are a fantastic worry-removing new features.  In the past
(SP 07) you had to include full assembly reference in .ASPX and similar files thus:
</p>
        <blockquote>
          <p>
            <font face="Courier New">SomeNamespace.SomeClass, SomeAssembly, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=6017a297d36052bf<br /></font>
          </p>
        </blockquote>
        <p>
The problems occur when you update the version of change an assembly name etc – things
that can happen quite often during the early stages of a product life cycle. 
Getting the key is also a complete PITA.
</p>
        <p>
With replaceable parameters you can let Visual Studio worry about these.
</p>
        <blockquote>
          <p>
            <font face="Courier New">SomeNamespace.SomeClass, $SharePoint.Project.AssemblyFullName$</font>
          </p>
        </blockquote>
        <p>
The parameter will be replace during packaging.  There is a bunch of different
parameters you can use in various types of files like XML and ASPX.
</p>
        <p>
HOWEVER, not all files are processed.  In my case I have a .SVC file (for WCF). 
Luckily, it’s very easy to add processing for this.  
</p>
        <ol>
          <li>
In Visual Studio, right click the SharePoint project and select Unload.<br /><a href="http://jonesie.net.nz/content/binary/WindowsLiveWriter/SharePoint2010ReplaceableParameters_8DDC/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jonesie.net.nz/content/binary/WindowsLiveWriter/SharePoint2010ReplaceableParameters_8DDC/image_thumb.png" width="437" height="92" /></a></li>
          <li>
Right click the project again and select Edit</li>
          <li>
At the end of the first property group in the proj file, add this:  
<br /><a href="http://jonesie.net.nz/content/binary/WindowsLiveWriter/SharePoint2010ReplaceableParameters_8DDC/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jonesie.net.nz/content/binary/WindowsLiveWriter/SharePoint2010ReplaceableParameters_8DDC/image_thumb_1.png" width="438" height="33" /></a></li>
        </ol>
        <p>
You can list as many extensions as you want, seperated by ;.
</p>
        <p>
        </p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ee231545(VS.100).aspx" target="_blank">Full
documentation is on MSDN.</a>
        </p>
        <p>
 
</p>
        <p>
Enjoy
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=154fd9d6-fa1f-4968-a307-f007c4b98d6a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Great Error Reporting – SharePoint and Visual Studio</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/04/07/GreatErrorReportingSharePointAndVisualStudio.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,79448598-24a8-47fe-ae06-1fd43f36225f.aspx</id>
    <published>2010-04-07T15:06:34.75-05:00</published>
    <updated>2010-04-07T15:06:34.75-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="Sharepoint" label="Sharepoint" scheme="http://jonesie.net.nz/CategoryView,category,Sharepoint.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here’s an example of great UX.  Error reporting and possible solutions are presented
in SharePoint 2010 Central Admin thus:
</p>
        <p>
          <a href="http://jonesie.net.nz/content/binary/WindowsLiveWriter/GreatErrorReportingSharePointandVisualSt_71F7/image_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jonesie.net.nz/content/binary/WindowsLiveWriter/GreatErrorReportingSharePointandVisualSt_71F7/image_thumb.png" width="393" height="180" />
          </a>
        </p>
        <p>
Selecting an item in the list displays:
</p>
        <p>
          <a href="http://jonesie.net.nz/content/binary/WindowsLiveWriter/GreatErrorReportingSharePointandVisualSt_71F7/image_4.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jonesie.net.nz/content/binary/WindowsLiveWriter/GreatErrorReportingSharePointandVisualSt_71F7/image_thumb_1.png" width="387" height="363" />
          </a>
        </p>
        <p>
 
</p>
        <p>
Key Points.
</p>
        <p>
1) The categorisation of the lists.
</p>
        <p>
2) The message in the list is human readable – not just some stupid error number and
cryptic message.
</p>
        <p>
3) The explanation of the problem is clear and concise.
</p>
        <p>
4) The remedy is similarly understandable 
</p>
        <p>
and, best of all
</p>
        <p>
5) The remedy contains a link to the solution
</p>
        <p>
 
</p>
        <p>
Wouldn’t it be fantastic if all products were so well designed?  How much more
productive would programming be if Visual Studio worked like this.  eg:
</p>
        <blockquote>
          <p>
Warning: You have a compiler error in a LINQ query with a join.  <u>Click here
for a solution</u>.
</p>
        </blockquote>
        <p>
Clicking would show the native compiler error, a few links to MSDN documentation,
the top 10 web search hits for the issue and a link to see more in Bing/Google.
</p>
        <p>
You could maybe also add in automatic refactoring, tied to code analysis rules or
whatever.
</p>
        <p>
Hey, how about this one:
</p>
        <p>
 
</p>
        <blockquote>
          <p>
Warning: The application you are creating has already been created by 12,875,435 other
developers.  Would you like to download one of these instead?
</p>
        </blockquote>
        <p>
 
</p>
        <p>
:)
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=79448598-24a8-47fe-ae06-1fd43f36225f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Why does anyone still use IE 8?</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/03/10/WhyDoesAnyoneStillUseIE8.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,3f748810-afa0-4836-80c6-c2ccd02a6ace.aspx</id>
    <published>2010-03-09T19:58:36.310375-06:00</published>
    <updated>2010-03-09T19:58:36.310375-06:00</updated>
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'll freely admit that I'm often first to defend Microsoft in just about everything
they do.  For development tools you can't beat Visual Studio and .Net. 
Office 2010 rocks.  Yes, I even love SharePoint (again :).
</p>
        <p>
HOWEVER, Internet Explorer 8 is the biggest waste of time I have ever seen.  
</p>
        <p>
According the Tom's Hardware Review (<a href="http://www.tomshardware.com/reviews/firefox-chrome-opera,2558.html">http://www.tomshardware.com/reviews/firefox-chrome-opera,2558.html</a>)
Chrome is the #1 browser and I'm inclined to agree.  The things that really nailed
it for me are the lack of standards support and the javascript speed in IE. 
These are the 2 most important features for successful modern web sites and having
60-ish percent of users with a slow buggy browser is bad news.  The most
damning eveidence is clear - only a 20% pass rate on Acid3 (<a href="http://en.wikipedia.org/wiki/Acid3">http://en.wikipedia.org/wiki/Acid3</a>).
</p>
        <p>
I switched to Chrome for most work a while ago and version 4 of this slipped quietly
onto my machines without me noticing.  It's a pleasure to use.  It's fast,
stable, simple and nearly all web sites work flawlessly - the few that don't tend
to be IE specific sites.
</p>
        <p>
My message to Microsoft is this.  <strong><font size="4">Give up!!  You've
lost.</font></strong>  You've had 10 years? to give the world a better
browser.  Google has done it in 1 year.  The only reason IE has 60%
dominance is because it's on every copy of Windows that gets installed and most corporate
users don't want the hassle of a non-integrated browser.  If you really want
to have a browser worthy of forcing onto everyones desktop then please just use WebKit
and add whatever tweaks you need to that.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=3f748810-afa0-4836-80c6-c2ccd02a6ace" />
      </div>
    </content>
  </entry>
  <entry>
    <title>iPad - yes or no?</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2010/01/29/iPadYesOrNo.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,035943e5-6d03-4a84-86d9-df10235aed70.aspx</id>
    <published>2010-01-29T14:50:10.237-06:00</published>
    <updated>2010-01-29T15:40:25.69025-06:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <h2>Pro's 
</h2>
        <ul>
          <li>
It would match my iPhone. 
</li>
          <li>
It's shiny 
</li>
          <li>
I would be cool for 5 minutes (probably in my mind only)</li>
        </ul>
        <h2>Con's
</h2>
        <ul>
          <li>
No Flash 
</li>
          <li>
No (real) .Net / Silverlight 
</li>
          <li>
Safari on the iPhone is complete shite so I'm not hopeful a bigger version would be
any better 
</li>
          <li>
Shiny screen makes it useless for reading books for any duration, unless the lighting
conditions are perfect 
</li>
          <li>
No camera 
</li>
          <li>
No USB or SD 
</li>
          <li>
Small capacity - 64Gb is ok but barely 
</li>
          <li>
Support for Exchange mail and calendaring is critical for work use - not likely to
see Outlook for i* anytime soon 
</li>
          <li>
Expensive when compared to a comparably featured notebook 
</li>
          <li>
I'm beginning to hate Apple (see below)</li>
        </ul>
        <p>
Ok, so some of these points are very personal to me, but the point I'm trying to make
is this is definately a v1 device.  The OS may be slick but some critical
features are missing.  I have a small notebook that already does more than the
iPad. It's cheaper, faster, more capable and almost as portable.  But the
battery only lasts 6 hours and it doesn't have fruit on the lid.
</p>
        <p>
The thing that worries me the most is that the iPad is produced by Apple.  They
are such a closed company.  They are very reticent to talk about anything that
might upset their carefully crafted image and brand.  They are overly secretive. 
They are expensive.
</p>
        <p>
As Apple grows and gains even more dominance over their market slice they will inherit
the title that Microsoft used to hold - that of the most hated IT company on the planet. 
Sure there are still those that believe Microsoft are evil.  These are people
that don't work with Microsoft products and people every day. Their opinion is
based on ignorance and arrogance.  Much like me and Apple really.
</p>
        <p>
I have no desire to become an Apple techie.  I see these things as consumer devices. 
Great for doing what they are intended to do but controlled by a maniacle tyrant who
won't listen to criticism and will kill anyone who speaks out against them. 
Much like the Chinese government or Islam.
</p>
        <p>
So now I have painted myself into a corner, I will pobably still get one.  Becuase
I am weak and easily attracted to shiny stuff and becuase everything Apple does is
just soooo cool and fantastic that I can't possibly not have one.
</p>
        <p>
I hate myself.
</p>
        <p>
 
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=035943e5-6d03-4a84-86d9-df10235aed70" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PDC Day 2</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/11/19/PDCDay2.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,69a22d8f-7e33-484c-8472-7d2f5f491418.aspx</id>
    <published>2009-11-19T09:37:40.9290246-06:00</published>
    <updated>2009-11-19T09:37:40.9290246-06:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="PDC09" label="PDC09" scheme="http://jonesie.net.nz/CategoryView,category,PDC09.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Day 2 began with more sizzle – lots of announcements and goodies.
</p>
        <p>
          <strong>SilverLight 4</strong>
        </p>
        <p>
Scott Guthrie - as always – gets to make the best announcements.  SilverLight
4 is out in Beta now and release will be 1st half of next year (probably around MIX
time I’d guess).  Here’s the highlights:
</p>
        <ul>
          <li>
            <strong>Support for external devices </strong>including cameras and microphones. 
Scott did a fun little demo using a web cam and some special effects. You can also
interact with the stream – in another demo that took a snapshot of a barcode and did
a lookup for the book.</li>
          <li>
            <strong>Printing</strong>.  Let me say that again<strong> PRINTING!!!</strong> Awesome!! 
Custom print preview also.</li>
          <li>
Multicasting support.  Don’t know what this is but it got a couple of ooo’s and
ahhhh’s.</li>
          <li>
            <strong>RichText</strong>, <strong>Clipboard</strong> (system or app), <strong>MouseWheel</strong>, <strong>Right
Click</strong> and <strong>Drag and Drop</strong>. They demoed some of these using
an awesome (so I say awesome too much?) Facebook client (the code for which is available).</li>
          <li>
            <strong>Command Manager and MVVM framework</strong>.  Our SL gurus spend a lot
of time getting this basic code working on every significant SL project.  This
will save many hours!</li>
          <li>
            <strong>HTML Control</strong>. Totally awesome!  You can use this to display
any old HTML including plugins such as Flash. In this demo they played a Rick roll
video off YouTube in a HTML control that was embedded in a SL app.  Then they
chopped up the ‘page’ into a jigsaw and shsuffled the pieces.  All this while
the video was still playing!  Incredible stuff!</li>
          <li>
            <strong>Shared Assemblies</strong>.  No more sharing of code and recompiling. 
Assemblies compiled in .Net 4 will be able to be used from SilverLight and non SilverLight
apps. Another big timesaver there.</li>
          <li>
            <strong>WCF &amp; REST enhancements</strong> including support for <strong>TCP Channels</strong>!!
OMG!</li>
          <li>
Intellisence for data binding.</li>
          <li>
            <strong>COM automation</strong> via the DLR.  They demoed this by creating items
in Outlook. Very easy and natural.</li>
          <li>
Implicit Styles.  
</li>
          <li>
Keyboard in fullscreen mode.</li>
          <li>
Profiling support.</li>
          <li>
            <strong>CHROME</strong> support.  Ha!  Take that Google.</li>
          <li>
            <strong>And best of all – fully trusted applications outside the browser!!  WICKEDLY
AWESOME!</strong>
          </li>
          <li>
            <strong>Oh and it’s still only ~5MB and it’s twice as fast.</strong>
          </li>
        </ul>
        <p>
The relevance of WPF is in question now I think.  SilverLight 3 now has a 45%
install base (that’s 45% of all PC’s on the planet I think).  
</p>
        <p>
          <strong>SharePoint and Office 2010</strong>
        </p>
        <p>
Apart from watching an awesome SharePoint and SilverLight demo involving a racing
car that looked strangely familiar there wasn’t a lot of stuff shown.  Highlights
were using the new tools in Visual Studio 2010 to create SharePoint Solutions. 
This has improved the experience by several orders of magnitude. Main features I caught:
</p>
        <ul>
          <li>
Sandbox deployments</li>
          <li>
F5 compile and debug – no more compile, deploy, activate, run, attach blah blah.</li>
          <li>
Can develop without SharePoint installed locally.</li>
        </ul>
        <p>
Beta is out now.
</p>
        <p>
          <strong>Goodies</strong>
        </p>
        <p>
They demoed a bunch of the latest hardware and some of the cool new things you can
do with this gear.  Stuff like HD, MultiTouch and many cores.  Then they
announced that every attendee at PDC would get a free notebook!  AWESOME!! 
I didn’t think this would include me – given the nature of my attendence – but I asked
and I recevied!  Woo hoo.  I love Microsoft.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=69a22d8f-7e33-484c-8472-7d2f5f491418" />
      </div>
    </content>
  </entry>
  <entry>
    <title>The Sound of Azure</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/11/18/TheSoundOfAzure.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,1524c997-a802-471c-8993-c954c60800b8.aspx</id>
    <published>2009-11-18T09:58:41.61825-06:00</published>
    <updated>2009-11-18T10:10:09.0245-06:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="PDC09" label="PDC09" scheme="http://jonesie.net.nz/CategoryView,category,PDC09.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The worlds most expensive hair dryer!
</p>
        <p>
          <a title="http://jonesie.net.nz/video/M2U00303.MPG" href="http://jonesie.net.nz/video/M2U00303.MPG">http://jonesie.net.nz/video/M2U00303.MPG</a>
        </p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=1524c997-a802-471c-8993-c954c60800b8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SQL Azure Futures from PDC09</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/11/17/SQLAzureFuturesFromPDC09.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,359a7982-d0f2-48a4-9d4b-3b1909452031.aspx</id>
    <published>2009-11-17T17:50:52.30575-06:00</published>
    <updated>2009-11-18T10:11:29.915125-06:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="PDC09" label="PDC09" scheme="http://jonesie.net.nz/CategoryView,category,PDC09.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m sitting in a session at PDC 09 on SQL Azure futures.  Here’s some notes for
me and anyone else who cares.
</p>
        <p>
          <strong>Backups and Clones</strong>
        </p>
        <ul>
          <li>
Backups are coming.  Can now(?) create a clone of a database.  Something
like CREATE DATABASE fred AS CLONE OF bob.</li>
        </ul>
        <p>
          <strong>Operations</strong>
        </p>
        <ul>
          <li>
API for provisioning – useful for SaaS providers.  Great for Multi-tenant too. 
</li>
          <li>
Better deployment and upgrades. 
</li>
          <li>
Data Sync. 
</li>
          <li>
Upgrade and downgrade options between db sizes  (1 &amp; 10 GB).</li>
        </ul>
        <p>
          <strong>Scale-Out</strong>
        </p>
        <ul>
          <li>
Woa!  TicketDirect mentioned again! 
</li>
          <li>
Dynamic database splits.  And merge back of course. 
</li>
          <li>
Additional db size options. Maybe up to 50 GB. 
</li>
          <li>
Multiple db connections. 
</li>
          <li>
Fan out query for multiple db’s.</li>
        </ul>
        <p>
          <strong>Other</strong>
        </p>
        <ul>
          <li>
Support for profiler 
</li>
          <li>
Full Text Search 
</li>
          <li>
CLR 
</li>
          <li>
BI</li>
        </ul>
        <p>
          <strong>Sensitive Data</strong> - Codename Vidalia – woosh – this went over my head.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=359a7982-d0f2-48a4-9d4b-3b1909452031" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Rocking at PDC</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/11/17/RockingAtPDC.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,740a114b-7f35-4a1c-b8d4-a619338f7432.aspx</id>
    <published>2009-11-17T16:20:21.837-06:00</published>
    <updated>2009-11-17T16:20:21.837-06:00</updated>
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
We are already into the 2nd day of Microsoft’s Professional Developers Conference
(PDC 09).  This year the theme is very clearly Cloud Computing and Azure but
there are a sprinkling of sessions on Visual Studio 2010, Team System, Languages and
even a little SharePoint and CRM/XRM.
</p>
        <p>
Day 0 was workshop day and I attended and slightly assisted ‘The Yellow Croc Man’
(aka Chris Auld) with his sessions on developing for the Azure Platform.  Chris
did a fantastic job – pointing out a lot of things that us developers don't normally
care/think about as much as we should – i.e., pricing and data sovereignty. 
These are very important issues with Azure and cloud computing in general.  Bad
programming can cost a lot of dosh.  Our TicketDirect project was used extensively
during Chris’ preso and at the end of the day, Mat Davey (TicketDirect CEO), Chris
and I took the stage to answer questions (which was slightly scary).
</p>
        <p>
Today was Key Note day with Ray Ozzie (Microsoft Chief Architect) and a host of walk-on
‘softies and 3rd parties.  Key points here were the announcement of :
</p>
        <p>
          <strong>PinPoint</strong> – a market place for all things Microsoft.  It’s up
now - <a title="http://pinpoint.microsoft.com" href="http://pinpoint.microsoft.com">http://pinpoint.microsoft.com</a></p>
        <p>
          <strong>Project Dallas</strong> – data as a service.  In CTP now - <a title="http://www.theregister.co.uk/2009/11/17/microsoft_dallas_data_service/" href="http://www.theregister.co.uk/2009/11/17/microsoft_dallas_data_service/">http://www.theregister.co.uk/2009/11/17/microsoft_dallas_data_service/</a> 
</p>
        <p>
          <strong>SQL Data Sync</strong> – Synchronise data from SQL Local to/from SQL Azure. 
I think this is part of SQL 08 R2 – CTP available now.
</p>
        <p>
          <strong>Project Sydney</strong> – this allows you to connect direct to on-premise
SQL Server from cloud roles.  
</p>
        <p>
          <strong>AppFabric</strong> – Will include caching (velocity), workflow, monitoring,
service bus, service hosting and access control.  Most usefully this will enable
multi-tenant apps. CTP will be out early next year.  This is a host for applications
and replaces the .Net Services SDK.  More on this after later sessions.
</p>
        <p>
          <strong>Visual Studio 2010</strong> will also include a bunch of new stuff to make
deployment much much simpler for cloud and non-cloud applications.  
</p>
        <p>
          <strong>System Centre and IIS</strong> – admin tools to support AppFabric.
</p>
        <p>
          <strong>BizTalk 2009 R2</strong> – updates for new SQL and Windows server R2 releases.
PowerShell access. Mapping enhancements and updated B2B accelerators. 
</p>
        <p>
Interestingly, WordPress is now hostable on Azure – this is still a PHP Apache app
– no .Net there.   Microsoft are providing a production ready service for
this ahead of the office switch-flick on January 1.
</p>
        <p>
Following the keynote we attended the Lap Around Azure session by the Direct of the
Platform, Manuvir Das.  Once again, TicketDirect  was shown and received
a very favourable response.
</p>
        <p>
 
</p>
        <p>
Day 1 is only half over! I’ll update with more news later.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=740a114b-7f35-4a1c-b8d4-a619338f7432" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SQL Azure Throttling – Retries</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/11/17/SQLAzureThrottlingRetries.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,bf9248b3-2d3f-4977-84ed-58823137cd9a.aspx</id>
    <published>2009-11-17T15:20:39.258875-06:00</published>
    <updated>2009-11-17T15:20:39.258875-06:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="SQL" label="SQL" scheme="http://jonesie.net.nz/CategoryView,category,SQL.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
SQL Azure will throttle your connections to protect resources in the data centre. 
When SQL Azure does this is non-deterministic – or at least, Microsoft cannot specifically
tell you when it will do this because there are many complicated factors. It could
be the number of concurrent requests, the CPU or IO usages, the weather – who knows! 
In the end it doesn’t really matter – you, THE DEVELOPER, must but be aware of this
and deal with it.
</p>
        <p>
SQL Throttling is manifested by a dropped connection.  This may appear as a Native
Error 10054 when you try to open a connection or some other error if the connection
is dropped after being opened.
</p>
        <p>
To cope with this throttle a retry will normally be all that is required.  At
the connection and command level this is easy but it can be complicated by unstructured
code.  So, having a nice clean data layer will make the solution much easier
to implement, but this applies equally to ‘messy’ code :)
</p>
        <p>
We reused the Retry Policy mechanism that is provided with the Storage Client. 
In the old sample storage client the syntax was a lot simpler but in the interest
of less confusion I wont talk about that.  The new November SDK works just as
well, but you need to do a tad more work.  The following sample is a connection
manager that is used by the data layer. 
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
              <span style="color: blue">using</span> System;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Data;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Data.SqlClient;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> Microsoft.WindowsAzure.StorageClient;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
              <span style="color: blue">namespace</span> MyApp.DataLayer
</p>
            <p style="margin: 0px">
{
</p>
            <p style="margin: 0px">
  <span style="color: blue">public</span><span style="color: blue">class</span><span style="color: #2b91af">ConnectionManager</span></p>
            <p style="margin: 0px">
  {
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;summary&gt;</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"> Maximum
number of retries</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;/summary&gt;</span></p>
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: blue">const</span><span style="color: blue">int</span> MAX_RETRIES
= 3;
</p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;summary&gt;</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"> The
retry policy for operations that can be retried (sql etc)</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;/summary&gt;</span></p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: #2b91af">RetryPolicy</span> RetryPolicy
{ <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;summary&gt;</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"> Wait
5 seconds between retries</span></p>
            <p style="margin: 0px">
    <span style="color: gray">///</span><span style="color: green"></span><span style="color: gray">&lt;/summary&gt;</span></p>
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: blue">const</span><span style="color: blue">int</span> WAIT_BETWEEN_RETRIES
= 5000;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    <span style="color: blue">public</span> ConnectionManager()
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: blue">this</span>.RetryPolicy = <span style="color: #2b91af">RetryPolicies</span>.Retry(MAX_RETRIES, <span style="color: #2b91af">TimeSpan</span>.FromSeconds(5));
</p>
            <p style="margin: 0px">
    }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
  
</p>
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: #2b91af">SqlConnection</span> OpenConnection(<span style="color: blue">string</span> connectionString)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: #2b91af">SqlConnection</span> con
= <span style="color: blue">null</span>;
</p>
            <p style="margin: 0px">
      <span style="color: blue">try</span></p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: #2b91af">DieHard</span>.RequestWithRetry(RetryPolicy,
() =&gt;
</p>
            <p style="margin: 0px">
            {
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
              <span style="color: #2b91af">SqlConnection</span> connection
= <span style="color: blue">new</span><span style="color: #2b91af">SqlConnection</span>(connectionString);
</p>
            <p style="margin: 0px">
              connection.Open();
</p>
            <p style="margin: 0px">
              con
= connection;
</p>
            <p style="margin: 0px">
            });
</p>
            <p style="margin: 0px">
        <span style="color: blue">return</span> con;
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
      <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: blue">throw</span><span style="color: blue">new</span><span style="color: #2b91af">Exception</span>(<span style="color: #a31515">"Error
connecting to " </span>+ connectionString, ex);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
    }
</p>
            <p style="margin: 0px">
  }
</p>
            <p style="margin: 0px">
}
</p>
          </div>
        </blockquote>
        <p>
The interesting part is the DieHard helper class.
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
              <span style="color: blue">using</span> System;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Collections.Generic;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Linq;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Text;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> Microsoft.WindowsAzure.StorageClient;
</p>
            <p style="margin: 0px">
              <span style="color: blue">using</span> System.Threading;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
              <span style="color: blue">namespace</span> MyApp.DataLayer
</p>
            <p style="margin: 0px">
{
</p>
            <p style="margin: 0px">
  <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">class</span><span style="color: #2b91af">DieHard</span></p>
            <p style="margin: 0px">
  {
</p>
            <p style="margin: 0px">
    <span style="color: blue">public</span><span style="color: blue">static</span> T
RequestWithRetry&lt;T&gt;(<span style="color: #2b91af">RetryPolicy</span> retryPolicy, <span style="color: #2b91af">Func</span>&lt;T&gt;
action)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: #2b91af">ShouldRetry</span> shouldRetry
= retryPolicy();
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: blue">int</span> retryCount = 0;
</p>
            <p style="margin: 0px">
      <span style="color: blue">while</span> (<span style="color: blue">true</span>)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: #2b91af">TimeSpan</span> delay
= <span style="color: #2b91af">TimeSpan</span>.FromSeconds(0);
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
        <span style="color: blue">try</span></p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          <span style="color: blue">return</span> action();
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          <span style="color: blue">if</span> (!shouldRetry(retryCount,
ex, <span style="color: blue">out</span> delay))
</p>
            <p style="margin: 0px">
            <span style="color: blue">throw</span>;
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        retryCount++;
</p>
            <p style="margin: 0px">
        <span style="color: #2b91af">Thread</span>.Sleep(delay);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
    }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    <span style="color: blue">public</span><span style="color: blue">static</span><span style="color: blue">void</span> RequestWithRetry(<span style="color: #2b91af">RetryPolicy</span> retryPolicy, <span style="color: #2b91af">Action</span> action)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: #2b91af">ShouldRetry</span> shouldRetry
= retryPolicy();
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: blue">int</span> retryCount = 0;
</p>
            <p style="margin: 0px">
      <span style="color: blue">while</span> (<span style="color: blue">true</span>)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: #2b91af">TimeSpan</span> delay
= <span style="color: #2b91af">TimeSpan</span>.FromSeconds(0);
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
        <span style="color: blue">try</span></p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          action();
</p>
            <p style="margin: 0px">
          <span style="color: blue">return</span>;
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          <span style="color: blue">if</span> (!shouldRetry(retryCount,
ex, <span style="color: blue">out</span> delay))
</p>
            <p style="margin: 0px">
            <span style="color: blue">throw</span>;
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
        retryCount++;
</p>
            <p style="margin: 0px">
        <span style="color: #2b91af">Thread</span>.Sleep(delay);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
    }
</p>
            <p style="margin: 0px">
  }
</p>
            <p style="margin: 0px">
}
</p>
          </div>
        </blockquote>
        <p>
 
</p>
        <p>
DieHard has 2 variants of the same Retry invoker – 1 for void actions and the other
for a generic return value.
</p>
        <p>
There is a couple of points to mention.  The timeout and the number of retries
to attempt may vary depending on your situation and other factors – don’t use my 5
second 5 retries settings as the best possible option for you.  You need to be
aware of transactions.  Retries should encapsulate the transaction as dropping
a connection will rollback the transaction.  So, except for this example of retrying
the open connection you should use the retry mechanism at the higher domain level.
</p>
        <p>
Enjoy!
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=bf9248b3-2d3f-4977-84ed-58823137cd9a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Processing a SQL Batch</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/10/27/ProcessingASQLBatch.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,1cb48594-ebac-467e-a7ec-c6976bd53c8b.aspx</id>
    <published>2009-10-26T20:20:37.477625-05:00</published>
    <updated>2009-10-26T22:24:38.133875-05:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="SQL" label="SQL" scheme="http://jonesie.net.nz/CategoryView,category,SQL.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is something I have wanted for a while now.  Today I finally got around
to doing something about it. I created a simple console application that can execute
a SQL script file that you would normally use in Management Studio or SQLCMD. 
You might well ask why I would do such a thing.  
</p>
        <ol>
          <li>
SSMS and SQLCMD is not always available or in the right place 
</li>
          <li>
I don't have the code for SSMS and SQLCMD so I cant change the way they work</li>
        </ol>
        <p>
In you read my previous post on deploying to SQL Azure then the first point will make
sense.  The next step is to make this script processing code work in Azure so
I don't have to create databases from my client.  Hopefully this will speed things
up a little or a LOT.
</p>
        <p>
Anyways, since I've always wanted someone to write this code and never found any,
here it is in case you are in the same boat. 
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
              <p style="margin: 0px">
                <span style="color: blue">class</span>
                <span style="color: #2b91af">Program</span>
              </p>
              <p style="margin: 0px">
  {
</p>
              <p style="margin: 0px">
    <span style="color: blue">static</span><span style="color: blue">int</span> Main(<span style="color: blue">string</span>[]
args)
</p>
              <p style="margin: 0px">
    {
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
      <span style="color: blue">string</span> connectionstring
= args[0];
</p>
              <p style="margin: 0px">
      <span style="color: blue">string</span> sql;
</p>
              <p style="margin: 0px">
      <span style="color: blue">try</span></p>
              <p style="margin: 0px">
      {
</p>
              <p style="margin: 0px">
        <span style="color: blue">using</span> (<span style="color: #2b91af">FileStream</span> fs
= <span style="color: blue">new</span><span style="color: #2b91af">FileStream</span>(args[1], <span style="color: #2b91af">FileMode</span>.Open, <span style="color: #2b91af">FileAccess</span>.Read))
</p>
              <p style="margin: 0px">
        {
</p>
              <p style="margin: 0px">
          <span style="color: blue">byte</span>[]
bytes = <span style="color: blue">new</span><span style="color: blue">byte</span>[fs.Length];
</p>
              <p style="margin: 0px">
          fs.Read(bytes, 0, (<span style="color: blue">int</span>)fs.Length);
</p>
              <p style="margin: 0px">
          sql = <span style="color: #2b91af">Encoding</span>.UTF8.GetString(bytes);
</p>
              <p style="margin: 0px">
        }
</p>
              <p style="margin: 0px">
      }
</p>
              <p style="margin: 0px">
      <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
</p>
              <p style="margin: 0px">
      {
</p>
              <p style="margin: 0px">
        <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Unable
to read sql script: "</span> + ex.Message);
</p>
              <p style="margin: 0px">
        <span style="color: blue">return</span> 1;
</p>
              <p style="margin: 0px">
      }
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
      <span style="color: blue">string</span> batchTerminator
= <span style="color: #a31515">@"##GO##"</span>;
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
      <span style="color: green">//Regex regex = new Regex(@"(^|\s+)"
+ batchTerminator + @"\s", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);</span></p>
              <p style="margin: 0px">
      <span style="color: blue">string</span>[] strings =
sql.Split(<span style="color: blue">new</span><span style="color: blue">string</span>[]
{batchTerminator}, <span style="color: #2b91af">StringSplitOptions</span>.None);
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
      <span style="color: blue">using</span> (<span style="color: #2b91af">SqlConnection</span> con
= <span style="color: blue">new</span><span style="color: #2b91af">SqlConnection</span>(connectionstring))
</p>
              <p style="margin: 0px">
      {
</p>
              <p style="margin: 0px">
        con.Open();
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
        <span style="color: #2b91af">SqlCommand</span> cmd
= <span style="color: blue">new</span><span style="color: #2b91af">SqlCommand</span>();
</p>
              <p style="margin: 0px">
        cmd.CommandType = System.Data.<span style="color: #2b91af">CommandType</span>.Text;
</p>
              <p style="margin: 0px">
        cmd.Connection = con;
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
        <span style="color: blue">for</span> (<span style="color: blue">int</span> i
= 0; i &lt; strings.Length; i++)
</p>
              <p style="margin: 0px">
        {
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
          <span style="color: #2b91af">Console</span>.Title
= <span style="color: #a31515">"Processing "</span> + i.ToString() + <span style="color: #a31515">"
of "</span> + strings.Length.ToString();
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
          <span style="color: green">//if
((!regex.IsMatch(strings[i])) &amp;&amp; (!string.IsNullOrEmpty(strings[i].Trim())))</span></p>
              <p style="margin: 0px">
          <span style="color: blue">if</span> (!<span style="color: blue">string</span>.IsNullOrEmpty(strings[i].Trim()))
</p>
              <p style="margin: 0px">
          {
</p>
              <p style="margin: 0px">
            <span style="color: #2b91af">Console</span>.WriteLine(strings[i]);
</p>
              <p style="margin: 0px">
            <span style="color: blue">try</span></p>
              <p style="margin: 0px">
            {
</p>
              <p style="margin: 0px">
              cmd.CommandText
= strings[i];
</p>
              <p style="margin: 0px">
              cmd.ExecuteNonQuery();
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.ForegroundColor
= <span style="color: #2b91af">ConsoleColor</span>.Green;
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"O.K."</span>);
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.ForegroundColor
= <span style="color: #2b91af">ConsoleColor</span>.Gray;
</p>
              <p style="margin: 0px">
            }
</p>
              <p style="margin: 0px">
            <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
</p>
              <p style="margin: 0px">
            {
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.ForegroundColor
= <span style="color: #2b91af">ConsoleColor</span>.Red;
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Error:
"</span> + ex.Message);
</p>
              <p style="margin: 0px">
              <span style="color: #2b91af">Console</span>.ForegroundColor
= <span style="color: #2b91af">ConsoleColor</span>.Gray;
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
              <span style="color: blue">return</span> 2;
</p>
              <p style="margin: 0px">
            }
</p>
              <p style="margin: 0px">
            <span style="color: #2b91af">Console</span>.WriteLine();
</p>
              <p style="margin: 0px">
            <span style="color: #2b91af">Console</span>.WriteLine();
</p>
              <p style="margin: 0px">
          }
</p>
              <p style="margin: 0px">
        }
</p>
              <p style="margin: 0px">
        <span style="color: blue">return</span> 0;
</p>
              <p style="margin: 0px">
        <span style="color: green">//Console.WriteLine("Press
ENTER when complete");</span></p>
              <p style="margin: 0px">
        <span style="color: green">//Console.ReadLine();</span></p>
              <p style="margin: 0px">
 
</p>
              <p style="margin: 0px">
      }
</p>
              <p style="margin: 0px">
    }
</p>
              <p style="margin: 0px">
  }
</p>
            </div>
          </div>
        </blockquote>
        <p>
 
</p>
        <p>
Ok, so it’s not the prettiest or most bullet proof code on the planet, but it works.  <strike>The
RegEx is the key to the process.  It’s not perfect – it expects  GO commands
to separate the batches and you need to have GO on a line by itself.  It’s easy
to extend this should you wish</strike>.<font color="#ff0000"> [<strong>Update</strong>]</font> Regex
don't work!  It’s just too hard to find all the GO’s accurately.  Instead,
I manually search and replace Go with ##GO##.  This is a lot easier/safer to
split with.  I also removed all PRINT statements from my scripts but you could
easily parse these out when processing and have then display as progress messages
(no need to send them to the server).
</p>
        <p>
Enjoy!
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=1cb48594-ebac-467e-a7ec-c6976bd53c8b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Migrating and Partitioning a Database to SQL Azure</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/10/25/MigratingAndPartitioningADatabaseToSQLAzure.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,0fe03aa3-97e0-40d6-ac72-2786c894fb45.aspx</id>
    <published>2009-10-25T17:07:49.962-05:00</published>
    <updated>2009-10-25T17:08:59.30575-05:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="SQL" label="SQL" scheme="http://jonesie.net.nz/CategoryView,category,SQL.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Moving data from one SQL Server to another is a fairly trivial task these days. 
You have many options – backup/restore the database, SSIS, detach/copy/attach, ADO.Net,
BCP, blah blah blah.  Moving data to SQL Azure is more challenging.  Here
is my experience and some details of the solution.
</p>
        <p>
          <strong>The Scenario</strong>
        </p>
        <p>
The application we are creating has a master application database and database per
‘client’.  The per client database will be partitioned into many smaller databases
– each being a replica of the source database with a filter on one or two tables.
The creation of the partitions will require the client application to be shut down
for a period of time – not ideal but acceptable.  
</p>
        <p>
SQL Azure does not (yet) include any support for partitioning or <a href="http://en.wikipedia.org/wiki/Shard_(database_architecture)" target="_blank">sharding</a> so
we knew we would have to create the solution ourselves.
</p>
        <p>
          <strong>Options</strong>
        </p>
        <p>
We wanted to have a flexible partitioning solution so from the outset I thought that
SSIS would provide a mechanism that would allow the client to create their own partition
rules as required. When I started creating the solution BCP was not available.  
</p>
        <p>
          <strong>Trials and Tribulations</strong>
        </p>
        <p>
Before partitioning of the database could be performed it was necessary to move the
source database to SQL Azure. Before moving the database it’s necessary to have a
script that will create the empty database schema.  When I first did this there
where no tools so I used the database tools in VSTS to import from the local database
and then manually tweaked the script to make it compatible with SQL Azure.  These
days there is the <a href="http://sqlazuremw.codeplex.com/" target="_blank">Migration
Wizard on CodePlex</a> which does pretty good (but not perfect) job of migrating your
schema and optionally data.
</p>
        <blockquote>
          <p>
            <u>Problem 0</u>
          </p>
          <p>
Executing the schema script is very very slow.  Locally it takes seconds. 
In SQL Azure it can take up to fifteen minutes. We have tested this from several connections
(inside and outside our network and with different service providers) and it’s never
been less than eight minutes. Our contacts at Microsoft can run the same script in
three minutes.  I have some ideas why this is slow and a possible solution… more
on this later if I solve it… but for now this is a big problem – 15 x 42 (the number
of partitions) = way too long!
</p>
        </blockquote>
        <p>
It’s been a long time since I’ve had to do anything with SQL Server beyond creating
databases for SharePoint or EPiServer and SSIS was completely new to me.  However,
I managed to piece together a package that copied the tables from one database to
another.  This package called other packages – 1 for each table – that would
truncate the destination table and copy the records.  
</p>
        <blockquote>
          <p>
            <u>Problem 1</u>
          </p>
          <p>
Because there we 30 or so packages I used xml package configuration files to specify
the database connections so that I could change the source and destination in one
place.  When running the packages in Visual Studio this would constantly remind
me that the connection had changed (when it hadn’t) so I had to turn this off. 
Not a big problem but annoying.
</p>
          <p>
            <u>Problem 2</u>
          </p>
          <p>
Running each separate table copy worked fine most of the time but running all of the
packages in sequence (see problem 3) would fail in different places for various reasons. 
Sometimes I would get duplicate key errors – which was theoretically impossible.
</p>
          <p>
            <u>Problem 3</u>
          </p>
          <p>
All but two of the tables have identity columns.  To move the data I had to SET
IDENTITY_INSERT ON for the destination table.  OLE DB Destination tasks in the
dataflow let you specify identity inserts but these don't work in SQL Azure – you
must currently use ADO.Net source and destinations tasks.
</p>
          <p>
You can only have a single SET IDENTITY_INSERT ON per database so this means I had
to run all these identity table packages sequentially which makes the whole process
very slow.
</p>
          <p>
            <u>Problem 4</u>
          </p>
          <p>
Reliability.  SSIS in Visual Studio seems to me to be very unreliable and flaky. 
I was plagued with performance issues and crashes.  
</p>
        </blockquote>
        <p>
In the end, frustration got the better of me and I gave up on SSIS.  Thankfully,
BCP for SQL Azure became available last week so that provided an option with more
control and visibility. ADO.Net includes a SQLBulkCopy class.  This will let
you move data from many different sources to a database table.  It provides a
few options to control the behaviour of the operation and this seemed like the best
option – the last time I used command line BCP was back in ‘95 with SQL Server 6.5
I think – or it might have been Sybase (which in those days was pretty much the same
thing).
</p>
        <p>
I whipped up a simple unit test and some classes to test SQLBulkCopy and it didn’t
take long to realise that this wasn’t going to work either.
</p>
        <blockquote>
          <p>
            <u>Problem 5</u>
          </p>
          <p>
I kept getting errors about not having SET XACT_ABORT set ON.  Binging for this
led me down the DTC path.  This is the same path that leads to hell! I couldn’t
understand why DTC was getting involved because I had not invoked any transactions. 
I thought that BCP or my source data reader query was doing something funky so I just
added the following SQLCommand query before I started the bulk copy:
</p>
          <p>
    SqlCommand xact = new SqlCommand("set xact_abort on", dst);<br />
    xact.ExecuteNonQuery(); 
</p>
          <p>
  
</p>
          <p>
This seemed to work, for a while.
</p>
          <p>
(It turned out that the base class for my unit test was declaring a TransactionScope
that wrapped everything in my unit test.  I didn’t spot this until I have up
with SQLBulkCopy so it may well be that this is not necessary now).
</p>
          <p>
            <u>Problems 6, 7 &amp; 8</u>
          </p>
          <p>
I’m not exactly sure when I decided to give up on SQLBulkCopy but it was somewhere
around the problems with timeouts, lockups and random results.
</p>
        </blockquote>
        <p>
My options were now reduced to a short list of one – command line BCP.  After
a few false starts (I don’t read instructions as well as I could) I managed to get
something working quite well.
</p>
        <p>
          <strong>Success! Moistly…</strong>
        </p>
        <p>
I created a batch file to test the various options with BCP.  It’s really pretty
simple to use but I wanted the simplest possible solution that would be easy to support
and maintain.  Using the native option (-n) provided this but it does mean that
should and destination tables need to be almost identical. When creating the schema
script I had re-ordered the columns on one table.  This was enough to cause a
problem for native mode which generated some cryptic errors.  Thankfully the
error file (-e option) provided enough clues to figure out what was wrong.
</p>
        <p>
          <strong>
            <u>Throttling</u>
          </strong>
        </p>
        <p>
SQL Azure will drop connections when/if there is a heavy load on a database. 
This it to enable high availability – which sounds silly – how can it be highly available
if the connections keep dropping? – but in reality this just means you need to be
prepared for a connection to drop and transactions to fail if the load on the database
/ server is exceeded.
</p>
        <p>
Determining what the threshold is for throttling of the connections is difficult. 
So difficult in fact that one might say impossible. Throttling is triggered by activity
by all users of a server. The server is also virtual (not as in a virtual machine
but as in a virtual connection to one or more virtual machines).  
</p>
        <p>
My BCP commands on one table (the largest) would consistently cause the throttling
to kick in.  This table has about 230,000 rows – not huge by and stretch of the
imagination.  Thankfully, BCP allows to to specify the batch size and the first
and last rows to use.  For this table I found that 10,000 rows per batch worked
most of the time and executing BCP on chucks of 50,000 records seems to have stopped
the throttling.  Using the first and last row options also provided the opportunity
to retry a chuck of records should throttling kill the connection.
</p>
        <p>
The final (so far) code for running command line BCP in a mode that SQL Azure can
handle looks like this.  This code is far from complete but should be sufficient
to explain the process. Please feel free to adopt and enhance as you see fit.
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
              <span style="color: blue">private</span>
              <span style="color: blue">void</span> copyTableWithCmdLineBCP(<span style="color: blue">string</span> sourceServer, <span style="color: blue">string</span> sourceDatabase, 
</p>
            <p style="margin: 0px">
  <span style="color: blue">string</span> sourceTable, <span style="color: blue">string</span> sourceRule, <span style="color: blue">string</span> sourceUserName, <span style="color: blue">string</span> sourcePassword,
</p>
            <p style="margin: 0px">
  <span style="color: blue">string</span> destinationServer, <span style="color: blue">string</span> destinationDatabase, <span style="color: blue">string</span> destinationTable, <span style="color: blue">string</span> destinationUserName, 
</p>
            <p style="margin: 0px">
  <span style="color: blue">string</span> destinationPassword, <span style="color: blue">int</span> rowsToCopy)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: blue">string</span> ofile = <span style="color: #2b91af">Path</span>.GetTempFileName();
</p>
            <p style="margin: 0px">
      <span style="color: blue">string</span> sourceQ = getSourceQuery(sourceDatabase
+ <span style="color: #a31515">".dbo."</span> + sourceTable, sourceRule);
</p>
            <p style="margin: 0px">
      <span style="color: blue">string</span> countQ = getCountQuery(sourceDatabase
+ <span style="color: #a31515">".dbo."</span> + sourceTable, sourceRule);
</p>
            <p style="margin: 0px">
      <span style="color: blue">string</span> args;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: green">// export to a temp file</span></p>
            <p style="margin: 0px">
      <span style="color: blue">if</span> (sourceUserName
== <span style="color: blue">null</span>)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: green">// no user name
so use trusted security</span></p>
            <p style="margin: 0px">
        args = <span style="color: blue">string</span>.Format(<span style="color: #a31515">"\"{0}\"
queryout \"{1}\" -S {2} -T -n -E"</span>, sourceQ, ofile, sourceServer);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
      <span style="color: blue">else</span></p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        args = <span style="color: blue">string</span>.Format(<span style="color: #a31515">"\"{0}\"
queryout \"{1}\" -S {2} -U {3} -P {4} -n -E"</span>, 
</p>
            <p style="margin: 0px">
                
sourceQ, ofile, sourceServer, sourceUserName, sourcePassword);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      execProcessAndCheck(Properties.<span style="color: #2b91af">Settings</span>.Default.BCPCMDPath,
args, <span style="color: #a31515">"Bulk copy export failed for table "</span> + 
</p>
            <p style="margin: 0px">
               
sourceTable);
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: green">// import the file one chuck
at a time</span></p>
            <p style="margin: 0px">
      <span style="color: blue">for</span> (<span style="color: blue">int</span> startRow
= 1; startRow &lt;= rowsToCopy; startRow += MAX_ROWS_PER_BATCH)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: blue">int</span> tries
= 0;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
        <span style="color: blue">if</span> (destinationUserName
== <span style="color: blue">null</span>)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          <span style="color: green">//
no user name so use trusted security</span></p>
            <p style="margin: 0px">
          args = <span style="color: blue">string</span>.Format(<span style="color: #a31515">"{0}.dbo.{1}
in {2} -S {3} -T -n -b 10000 -E -F {4}"</span>,
</p>
            <p style="margin: 0px">
            destinationDatabase,
destinationTable, ofile, destinationServer, startRow);
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        <span style="color: blue">else</span></p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          args = <span style="color: blue">string</span>.Format(<span style="color: #a31515">"{0}.dbo.{1}
in {2} -S {3} -U {4} -P {5} -n -b 10000 -E -F {6}"</span>,
</p>
            <p style="margin: 0px">
            destinationDatabase,
destinationTable, ofile, destinationServer, destinationUserName,
</p>
            <p style="margin: 0px">
            destinationPassword,
startRow);
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        <span style="color: blue">int</span> endRow
= startRow + MAX_ROWS_PER_BATCH - 1;
</p>
            <p style="margin: 0px">
        <span style="color: blue">if</span> (endRow
&lt; rowsToCopy)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          args += <span style="color: #a31515">"
-L "</span> + endRow.ToString();
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
        <span style="color: green">// execute with
retries</span></p>
            <p style="margin: 0px">
        <span style="color: blue">while</span> (!execProcessAndCheck(Properties.<span style="color: #2b91af">Settings</span>.Default.BCPCMDPath,
args, 
</p>
            <p style="margin: 0px">
           <span style="color: #a31515">"Bulk
copy import failed for table "</span> + destinationTable) &amp;&amp; ++tries &lt;=
MAX_RETRIES)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          Logger.WriteLog(<span style="color: #2b91af">LogCategory</span>.Error, <span style="color: #a31515">"Operation
failed due to connection failure.  Will retry."</span>);
</p>
            <p style="margin: 0px">
          <span style="color: #2b91af">Thread</span>.Sleep(WAIT_BETWEEN_RETRIES);
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
    }
</p>
          </div>
        </blockquote>
        <p>
This uses a couple of helper methods.  getSourceQuery and getCountQuery simply
return queries for a specified table name and ‘rule’  The rule is a string which
defines how to partition the table.  A switch statement is used to determine
the WHERE clause for a table based on the table name and rule value.
</p>
        <p>
execProcessAndCheck executes a command line with arguments and captures the output. 
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: blue">bool</span> execProcessAndCheck(<span style="color: blue">string</span> cmdLine, <span style="color: blue">string</span> args, <span style="color: blue">string</span> errorMessage)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      _processOutput = <span style="color: blue">new</span><span style="color: #2b91af">StringBuilder</span>();
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: #2b91af">ProcessStartInfo</span> psi
= <span style="color: blue">new</span><span style="color: #2b91af">ProcessStartInfo</span>(cmdLine,
args);
</p>
            <p style="margin: 0px">
      psi.RedirectStandardError = <span style="color: blue">true</span>;
</p>
            <p style="margin: 0px">
      psi.RedirectStandardOutput = <span style="color: blue">true</span>;
</p>
            <p style="margin: 0px">
      psi.UseShellExecute = <span style="color: blue">false</span>;
</p>
            <p style="margin: 0px">
      psi.CreateNoWindow = <span style="color: blue">true</span>;
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: #2b91af">Process</span> prs = <span style="color: blue">new</span><span style="color: #2b91af">Process</span>();
</p>
            <p style="margin: 0px">
      prs.OutputDataReceived += <span style="color: blue">new</span><span style="color: #2b91af">DataReceivedEventHandler</span>(prs_OutputDataReceived);
</p>
            <p style="margin: 0px">
      prs.StartInfo = psi;
</p>
            <p style="margin: 0px">
      prs.Start();
</p>
            <p style="margin: 0px">
      prs.BeginOutputReadLine();
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: blue">if</span> (prs != <span style="color: blue">null</span>)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        prs.WaitForExit(MAX_PROCESS_TIME);
</p>
            <p style="margin: 0px">
        <span style="color: blue">if</span> (!prs.HasExited)
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          prs.Kill();
</p>
            <p style="margin: 0px">
          <span style="color: blue">throw</span><span style="color: blue">new</span><span style="color: #2b91af">Exception</span>(errorMessage
+ <span style="color: #a31515">" - command has exceeded the maximum allowable time
and was exterminated."</span>);
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: blue">return</span> checkProcessResults(prs,
errorMessage);
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    }
</p>
          </div>
        </blockquote>
        <p>
 
</p>
        <p>
The output is captured by a simple event handler:
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
    <span style="color: blue">void</span> prs_OutputDataReceived(<span style="color: blue">object</span> sender, <span style="color: #2b91af">DataReceivedEventArgs</span> e)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: blue">if</span> (!<span style="color: blue">string</span>.IsNullOrEmpty(e.Data))
</p>
            <p style="margin: 0px">
        _processOutput.AppendLine(e.Data);
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
    }
</p>
          </div>
        </blockquote>
        <p>
 
</p>
        <p>
_processOutput is a class scoped StringBuilder.
</p>
        <p>
The results from the process are checked by checkProcessResults:
</p>
        <blockquote>
          <div style="font-family: courier new; background: white; color: black; font-size: 10pt">
            <p style="margin: 0px">
    <span style="color: blue">private</span><span style="color: blue">bool</span> checkProcessResults(<span style="color: #2b91af">Process</span> prs, <span style="color: blue">string</span> message)
</p>
            <p style="margin: 0px">
    {
</p>
            <p style="margin: 0px">
      <span style="color: blue">if</span> (prs.ExitCode !=
0)
</p>
            <p style="margin: 0px">
      {
</p>
            <p style="margin: 0px">
        <span style="color: green">// look for
error 10054 - this means that SQL Azure has throttled and we should retry</span></p>
            <p style="margin: 0px">
        <span style="color: blue">string</span> output
= _processOutput.ToString();
</p>
            <p style="margin: 0px">
        <span style="color: blue">if</span> (output.Contains(<span style="color: #a31515">"NativeError
= 10054"</span>))
</p>
            <p style="margin: 0px">
        {
</p>
            <p style="margin: 0px">
          <span style="color: blue">return</span><span style="color: blue">false</span>;
</p>
            <p style="margin: 0px">
        }
</p>
            <p style="margin: 0px">
        message += <span style="color: #a31515">":
Error Code = "</span> + prs.ExitCode.ToString() + <span style="color: #a31515">" :
Message = "</span> + output;
</p>
            <p style="margin: 0px">
        <span style="color: blue">throw</span><span style="color: blue">new</span><span style="color: #2b91af">Exception</span>(message);
</p>
            <p style="margin: 0px">
      }
</p>
            <p style="margin: 0px">
 
</p>
            <p style="margin: 0px">
      <span style="color: blue">return</span><span style="color: blue">true</span>;
</p>
            <p style="margin: 0px">
    }
</p>
          </div>
        </blockquote>
        <p>
 
</p>
        <p>
This is all very specify to the way BCP.exe and SQLCMD.exe work – if you want to use
this for other command line tools then some tweaking will no doubt be required.
</p>
        <p>
          <strong>Summary</strong>
        </p>
        <p>
SQL Azure is an extremely powerful platform - despite the issues described above. 
It will definitely get better as the product gets closer to release.  Most of
my problems are caused by my recent inexperience with SQL tools and the general nature
of an unfinished product.  Learning how to do this stuff now will provide a better
understanding of the realities of cloud based computing as opposed to hosting a SQL
Server on some internet connected remote server.
</p>
        <p>
Performance of the database creation, upload and partitioning could be enhanced in
several ways.  Threading could help enormously when creating the partition databases
but throttling may reduce any benefit when it comes to uploading the data.  Using
multiple SQL Azure servers would also help a little. Moving the functionality into
the cloud could be possible if SQLBulkCopy would work betterer and if I had a mechanism
for creating the database schema other than SQLCmd.exe.  
</p>
        <p>
All of these options are possible given more time – but <a href="http://microsoftpdc.com/" target="_blank">PDC09</a> is
our hard deadline - so what I have so far will hopefully be good enough for a wicked
kick-arse sexed-up demo of what is possible with this awesome platform! I’ll talk
more about this application when I can… :)
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=0fe03aa3-97e0-40d6-ac72-2786c894fb45" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Deploying and Load Balancing EPiServer 5.2</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/09/28/DeployingAndLoadBalancingEPiServer52.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,913738ea-f664-4228-8d31-5b8b6dfacb50.aspx</id>
    <published>2009-09-28T03:40:52.72325-05:00</published>
    <updated>2009-09-28T14:27:47.645125-05:00</updated>
    <category term="EPiServer" label="EPiServer" scheme="http://jonesie.net.nz/CategoryView,category,EPiServer.aspx" />
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="PowerShell" label="PowerShell" scheme="http://jonesie.net.nz/CategoryView,category,PowerShell.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
It’s been a while since I’ve blogged anything about EPiServer – 2 reasons - 
1) I haven’t done an awful lot with it lately and 2) it’s just so easy it seems silly
to blog about. However, over the last couple of weeks I’ve been helping out on a web
site replacement project and one of my tasks was to install and configure the various
servers – development, staging, UAT &amp; production.  So, me thinks it’s time
to talk about it.
</p>
        <h5>SuperDeploy
</h5>
        <p>
Normally EPiServer installation is performed manually using the EPiServer setup and
Deployment Centre tools.  However, for this project we attempted to script the
entire process using PowerShell scripts.  We have created a deployment tool with
PowerShell – aptly named SuperDeploy – that we use for SharePoint installation and
database creation.  This is very useful for creating fully automated installations
that we can use during development and when we need to install on the clients environment. 
So, it seemed natural that we should extend this to work with EPiServer.  SuperDeploy
uses a simple XML file to define what to install and where - the how is hard coded
into PowerShell functions in the script.
</p>
        <p>
Anyways, SuperDeploy works very well and provided a nice repeatable installation for
all servers – up to a point.  With a bit more work it could do everything but
time is.. you know what, so some manual steps were needed to finish off the production
server.
</p>
        <p>
The final production installation had 2 web servers identically configured. 
The EPiServer site files were installed to a folder on F:\ and this folder was mirrored
between the 2 servers using Windows DFS – so changes to files on one server were automatically
and instantly copied to the other server – essentially meaning we had a single set
of files for both servers.  We could have had the files on a external drive array
of some sort but this would mean a single point of failure.  Replicating the
files between servers provides an extra level of redundancy. The EPiServer virtual
file system (VPP) was also replicated using the same DFS mechanism. The SQL 2005 database
was on a third server and this was mirrored using log shipping to a forth server.
</p>
        <h5>Load Balancing
</h5>
        <p>
I’ve come to notice over recent years than when something looks hard and not very
well documented – it turns out to be obvious and simple.  Such is the case with
the configuration of EPiServer load balancing.  
</p>
        <p>
Documentation of the setup of EPiServer load balancing is hard to find. In fact the
only documentation I could find was <a href="http://labs.episerver.com/en/Blogs/Allan/Dates/112230/11/LoadBalancing-in-6-steps/" target="_blank">a
single blog post</a>.  This worried me somewhat as there isn’t a lot of detail
in this post and it wasn’t an official EPiServer document. But I needn’t have worried
– 5 of the 6 steps were correct but step 4 is applicable to IIS 6, not IIS 7 which
we were using.  For IIS 7, httpModules must be specified in the &lt;system.webserver&gt;
section of the web.config – not in &lt;system.web&gt;.  You can also configure
these in IIS Manager.
</p>
        <p>
The setup of Microsoft NLB was already done for us and the tool linked to in the above
post proved that the network was indeed setup correctly.  
</p>
        <p>
The hardest part was testing that the servers were actually load balanced.  Fortunately
– a mistake by me editing the IIS config meant that one of the sites would not run. 
Browsing from a test client machine gave me an HTTP 500 error from IIS. It was impossible
to know which server was failing so we disabled one of the servers from the load balancing
by turning off the NLB agent.  When the client browser was able to see the site
correctly we new a) which server was broken and b) NLB was working.  Crude? 
Yes, but good enough.  Some better testing is still required of course, but that's
another story.
</p>
        <p>
Even the smoothest installation can have surprises.  When we ran the site, we
were prompted to login to view the home page – which is strange as it’s a public web
site with anonymous access enabled.  We compared the production server configuration
of IIS and web.config to the other servers and these were identical – we thought. 
In the end, we configured the IIS anonymous access user to be the application pool
account rather than IUSR and the setup was done.
</p>
        <h5>Morals of the story
</h5>
        <p>
EPiServer installation is easy – even for multiple load balanced servers. If you do
have multiple server then ensure they are identically configured – Virtual Machines
are a life saver!  Mirroring or sharing the site installation folder will help
with this (but it also means a mistake on 1 server will potentially be a mistake on
all servers – instantly!).  
</p>
        <p>
Script your installation as much as possible.  It make repeating your installation
simple.
</p>
        <p>
Install often and early – preferably as part of your development cycle.  Don’t
wait till the end of the development to test your deployment – YOU WILL REGRET IT
– trust me!  If you can, have your automated build cycle run your deployment
script every night.
</p>
        <p>
Be pragmatic.  Perfect is great if you can afford it but customers and bosses
are rarely willing to pay for this.  Good enough is usually good enough!
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=913738ea-f664-4228-8d31-5b8b6dfacb50" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Slides &amp; Code from Azure Development Getting Started</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/08/20/SlidesCodeFromAzureDevelopmentGettingStarted.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,30c9d6d6-d5bf-4a5d-a731-d392139f682c.aspx</id>
    <published>2009-08-19T21:00:33.804-05:00</published>
    <updated>2009-08-20T20:03:44.554625-05:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <category term="NZ .Net User Group" label="NZ .Net User Group" scheme="http://jonesie.net.nz/CategoryView,category,NZNetUserGroup.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here’s the slides and code from my user group session last night – Getting Started
with Azure Development.
</p>
        <p>
I covered the basics of Web and Worker roles, storage and a bit of the service bus.
</p>
        <p>
Use as you see fit.
</p>
        <p>
          <a href="http://jonesie.net.nz/content/binary/Drizle.zip">Drizle.zip (3.53 MB)</a>
          <br />
        </p>
        <a href="http://jonesie.net.nz/content/binary/WindowsAzureStartingUp.zip">WindowsAzureStartingUp.zip
(229.92 KB)</a>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=30c9d6d6-d5bf-4a5d-a731-d392139f682c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Service Bus Version Weirdness</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/07/23/ServiceBusVersionWeirdness.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,d44c77cb-2b71-44e1-a21e-13bb2ac4b584.aspx</id>
    <published>2009-07-22T21:54:08.542666-05:00</published>
    <updated>2009-07-22T21:54:08.542666-05:00</updated>
    <category term="Azure" label="Azure" scheme="http://jonesie.net.nz/CategoryView,category,Azure.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://jonesie.net.nz/AzureNetServiceBusAmpTCP.aspx" target="_blank">After
posting about using TCP</a> with the .Net Service Bus and making it look sooooo simple,
I’ve lost most of today trying to get the fracking thing working!  I doesn’t
matter what I do in the config, the service host keeps prompting me for a Card (from
CardSpace) even though I had everything setup for UserNamePassword creds.
</p>
        <p>
After much stuffing around I noticed that my solution had the wrong version of the
service bus DLL (0.15.0.0 – March CTP I think).  This was my bad – I had copied
the DLL to a solution folder.  So I grabbed the '”new” version (0.16.7.0) from
the July CTP Assemblies folder and tried that.
</p>
        <p>
Same result!  Arg!
</p>
        <p>
Looking in the GAC I could see it had version 0.16.0.0.  What the ?!!
</p>
        <p>
Time for a reinstall me think.
</p>
        <p>
Download from MS.  Install. Chug chug….
</p>
        <p>
Ok, now I have version 0.16.71.1.  Right. Fine.
</p>
        <p>
But the GAC still has 0.16.0.0 and my app still is broked.  Lord - give me strength!
</p>
        <p>
I re-added the project assembly reference to my local non gac copy and set copy local
and now it all works again.
</p>
        <p>
I can’t delete the old version from the GAC without uninstalling the SDK completely
so it will have to stay there.
</p>
        <p>
Weird!  The Joy of CTP.
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=d44c77cb-2b71-44e1-a21e-13bb2ac4b584" />
      </div>
    </content>
  </entry>
  <entry>
    <title>What is Azure &amp;ndash; best explanation I&amp;rsquo;ve seen</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/07/21/WhatIsAzureNdashBestExplanationIrsquoveSeen.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,aafc80fc-4333-4f9a-85d2-5bb401b413ca.aspx</id>
    <published>2009-07-21T18:27:25.98778-05:00</published>
    <updated>2009-07-21T18:27:25.98778-05:00</updated>
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Checkout this cool video if you want a 4 minute elevator pitch (ok, so a slow elevator).
</p>
        <p>
          <a title="http://blog.smarx.com/posts/what-is-windows-azure-a-hand-drawn-video" href="http://blog.smarx.com/posts/what-is-windows-azure-a-hand-drawn-video">http://blog.smarx.com/posts/what-is-windows-azure-a-hand-drawn-video</a>
        </p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=aafc80fc-4333-4f9a-85d2-5bb401b413ca" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Azure .Net Service Bus &amp;amp; TCP</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/07/21/AzureNetServiceBusAmpTCP.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,a321ca0a-e86e-4af1-94fe-0f92c4d9616a.aspx</id>
    <published>2009-07-21T16:42:56.0477995-05:00</published>
    <updated>2009-07-21T16:42:56.0477995-05:00</updated>
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
We recently implemented the .Net Service bus to expose some in-house WCF services
to the world wide world. It may be useful for me and others if I describe how to do
this :) This setup allows you to switch between tcp and http relay binding with configuration.
</p>
        <h4>The Host
</h4>
        <p>
For the in-house systems you need to create a host – you cant use IIS as the service
bus requires a connection to be initiated by both ends of the communication. 
We created a Windows Service application that also runs as a console app.  This
is much simpler when developing and debugging.  To create this service:
</p>
        <p>
1) create a new windows service using the standard VS template and add a reference
to Microsoft.ServiceBus (in addition to your service and data contracts which I hope
are in separate assemblies!)
</p>
        <p>
2) change the Application Output Type to Console Applications.
</p>
        <p>
3) add some code to Program.cs to flick to console mode:
</p>
        <blockquote>
          <p>
            <font face="Courier New">if (args.Length &gt; 0 &amp;&amp; args[0].ToLower() == "/console")<br />
{<br />
  myService.RunConsole(args);<br />
}<br />
else<br />
{<br />
  ServiceBase.Run(ServicesToRun); 
<br />
}</font>
          </p>
        </blockquote>
        <p>
4) in your service code add the following method:
</p>
        <blockquote>
          <p>
            <font face="Courier New">internal void RunConsole(string[] args)<br />
{<br />
  OnStart(args);<br />
  Console.WriteLine("My ServiceHost is running... Press Enter to stop the service");<br />
  Console.ReadLine();<br />
  OnStop();<br />
}</font>
          </p>
        </blockquote>
        <p>
Now for the service bus stuff.
</p>
        <p>
5) in the service class, add a member for the service host:
</p>
        <p>
ServiceHost _host = null;
</p>
        <p>
6) in the OnStart method of your service add the following :
</p>
        <blockquote>
          <p>
            <font face="Courier New">// create a behavior for the service bus – it need creds
of some type<br />
TransportClientEndpointBehavior behavior = new TransportClientEndpointBehavior();<br />
behavior.CredentialType = TransportClientCredentialType.UserNamePassword;<br />
behavior.Credentials.UserName.UserName = Properties.Settings.Default.ServiceBusSolutionName;<br />
behavior.Credentials.UserName.Password = Properties.Settings.Default.ServiceBusPassword;</font>
          </p>
          <p>
            <font face="Courier New">// create an address for the service bus.  config allows
a switch between tcp and http<br />
Uri address;<br /><br />
if(Properties.Settings.Default.ServiceBusBinding == "nettcp") 
<br />
{</font>
            <font face="Courier New">
              <br />
  address = ServiceBusEnvironment.CreateServiceUri("sb", Properties.Settings.Default.ServiceBusSolutionName,
Properties.Settings.Default.ServiceBusServiceName); 
<br />
}<br />
else 
<br />
  if(Properties.Settings.Default.ServiceBusBinding == "basichttp")<br />
  {<br />
    address = ServiceBusEnvironment.CreateServiceUri("http", Properties.Settings.Default.ServiceBusSolutionName,
Properties.Settings.Default.ServiceBusServiceName);<br />
  }<br />
  else<br />
    throw new ArgumentException("Invalid binding for Service Bus");</font>
          </p>
          <p>
            <font face="Courier New">// create the host<br />
_host = new ServiceHost(typeof(MyService), address);<br /><br />
// update all the end points with the new behavior – you may need more than one –
or not – up to you<br />
foreach (ServiceEndpoint endpoint in _host.Description.Endpoints)<br />
{<br />
    endpoint.Behaviors.Add(behavior);<br />
}<br /><br />
// open the portal to another dimension – a dimension of sight and sound<br />
_host.Open();</font>
          </p>
        </blockquote>
        <p>
Now for some config.  For me this was the hardest part.  Hard coding WCF
config is much simpler!
</p>
        <p>
7) create some service model bindings for netTcpRelayBinding &amp; basicHttpRelayBinding
</p>
        <blockquote>
          <p>
            <font face="Courier New">&lt;bindings&gt;<br />
  &lt;netTcpRelayBinding&gt;<br />
    &lt;binding name="default" /&gt;<br />
  &lt;/netTcpRelayBinding&gt;<br />
  &lt;basicHttpRelayBinding&gt;<br />
    &lt;binding name="default"&gt;<br />
      &lt;security mode="None" /&gt;<br />
    &lt;/binding&gt;<br />
  &lt;/basicHttpRelayBinding&gt;<br />
&lt;/bindings&gt;</font>
          </p>
        </blockquote>
        <p>
8) add an endpoint for your service:
</p>
        <blockquote>
          <p>
            <font face="Courier New">&lt;endpoint name="MyServiceEndpoint"<br />
          address=""<br />
          binding="netTcpRelayBinding"<br />
          contract="MyApp.ServiceContracts.IMyService"<br />
          bindingConfiguration="default"
/&gt;</font>
          </p>
        </blockquote>
        <p>
 
</p>
        <p>
9) if you want to use  basic http then add this instead:
</p>
        <blockquote>
          <p>
            <font face="Courier New">&lt;endpoint name="MyServiceEndpoint"<br />
               
address=</font>
            <a href="http://mysolution.servicebus.windows.net/MyService">
              <font face="Courier New">http://mysolution.servicebus.windows.net/MyService</font>
            </a>
            <br />
            <font face="Courier New">               
binding="basicHttpRelayBinding"<br />
               
contract="MyApp.ServiceContracts.IMyService"<br />
               
bindingConfiguration="default" /&gt;</font>
            <br />
          </p>
        </blockquote>
        <p>
And that’s about it for the service host.  If you need to have metadata support
(WSDL) then that’s a whole other story that I will try to blog about seperately.
</p>
        <h4>The Client
</h4>
        <p>
Azure worker roles do not have a web or app .config you can use for WCF configuration
settings.  Web roles do have a web.config but this can only be changed by a redeploy
of package so it’s not the best idea to put anything but service configuration in
there.  In my case, I needed to access the in-house services from both the web
and worker roles so I created a class lib project with a single helper class.
</p>
        <p>
1) create a Windows Class Library and add references for Microsoft.ServiceBus plus
your service and data contracts.
</p>
        <p>
2) Create a static class with a single static method – call it what you like but something
like GetClientChannel() will do.  Add the following code:
</p>
        <blockquote>
          <p>
IMyChannel channel;  // this is a simple combo interface of IChannel and IMyService<br /><br />
Uri address; 
</p>
          <p>
            <br />
// create the behavior for SB creds<br />
TransportClientEndpointBehavior behavior = new TransportClientEndpointBehavior();<br />
behavior.CredentialType = TransportClientCredentialType.UserNamePassword;<br /></p>
          <p>
// get the creds from the cloud config<br />
behavior.Credentials.UserName.UserName = RoleManager.GetConfigurationSetting("ServiceBusSolutionName");<br />
behavior.Credentials.UserName.Password = RoleManager.GetConfigurationSetting("ServiceBusPassword"); 
<br /><br />
// create a channel factory 
</p>
          <p>
ChannelFactory&lt;IMyChannel&gt; channelFactory = new ChannelFactory&lt;IMyChannel&gt;(); 
<br /><br />
// create the binding – config allows us to select http or tcp 
</p>
          <p>
if (RoleManager.GetConfigurationSetting("ServiceBusBinding").ToLower() == "basichttp")<br />
{<br />
  channelFactory.Endpoint.Binding = new BasicHttpRelayBinding(EndToEndBasicHttpSecurityMode.None,
RelayClientAuthenticationType.None);<br />
  address = ServiceBusEnvironment.CreateServiceUri("http", RoleManager.GetConfigurationSetting("ServiceBusSolutionName"),
RoleManager.GetConfigurationSetting("ServiceBusServiceName"));<br />
}<br />
else if (RoleManager.GetConfigurationSetting("ServiceBusBinding").ToLower() == "nettcp")<br />
{<br />
  channelFactory.Endpoint.Binding = new NetTcpRelayBinding(EndToEndSecurityMode.Transport,
RelayClientAuthenticationType.None);<br />
  address = ServiceBusEnvironment.CreateServiceUri("sb", RoleManager.GetConfigurationSetting("ServiceBusSolutionName"),
RoleManager.GetConfigurationSetting("ServiceBusServiceName"));<br />
}<br />
else<br />
{<br />
  throw new ArgumentException("Invalid service bus binding configuration option:
" + RoleManager.GetConfigurationSetting("ServiceBusBinding"));<br />
} 
<br /><br />
// update the factory for A B &amp; C 
</p>
          <p>
channelFactory.Endpoint.Address = new EndpointAddress(address);<br />
channelFactory.Endpoint.Behaviors.Add(behavior); 
</p>
channelFactory.Endpoint.Contract.ContractType = typeof(ICRMChannel);<br /><p>
channel = channelFactory.CreateChannel(new EndpointAddress(address));<br />
channel.Open(); 
</p><p>
return channel;
</p></blockquote>
        <p>
  
</p>
        <p>
Tada!  All done.  Provided I haven’t introduced any bugs then this should
give you a connection to you in-house services, by passing any firewall crap that
those pesky IT people seem to insist on.
</p>
        <p>
Enjoy :)
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=a321ca0a-e86e-4af1-94fe-0f92c4d9616a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>A Twit for One Week</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/07/17/ATwitForOneWeek.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,08ab31a0-7548-4d11-8255-94ed4c36247e.aspx</id>
    <published>2009-07-16T22:42:30.5186885-05:00</published>
    <updated>2009-07-16T22:42:30.5186885-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
So far, so good. Twitter has not taken over my life.  I’ve tweeted and chirped
a little this week and have found a few colleagues to follow and vice versa. It’s
also been a little useful and has helped me solve a couple of problems quicker than
the usual methods (forums and web searches).
</p>
        <p>
It’s interesting to see Twitter going main stream.  When one of our sales guys
asked which twitter client to use I thought ‘oh well, twitter is surely dead now!’
but then I read that CRM 5 will have a Twitter interface and I’m guessing (truly –
no insider info anymore) we will see similar functionality in Office 2010. Google
Wave has this too.
</p>
        <p>
I’m not tempted to create the next killer twitter client yet.  Tweetdeck works
well enough for me at this stage but I can see that I will soon run out of screen
real estate.
</p>
        <p>
Best thing about twitter?  It’s go me blogging again :)
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=08ab31a0-7548-4d11-8255-94ed4c36247e" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell Love &amp;ndash; Converting a comma delimited string to an array</title>
    <link rel="alternate" type="text/html" href="http://jonesie.net.nz/2009/07/16/PowerShellLoveNdashConvertingACommaDelimitedStringToAnArray.aspx" />
    <id>http://jonesie.net.nz/PermaLink,guid,3e997791-403e-439c-aeda-22c78896fe10.aspx</id>
    <published>2009-07-16T18:33:27.5906275-05:00</published>
    <updated>2009-07-16T18:33:27.5906275-05:00</updated>
    <category term="General" label="General" scheme="http://jonesie.net.nz/CategoryView,category,General.aspx" />
    <category term="PowerShell" label="PowerShell" scheme="http://jonesie.net.nz/CategoryView,category,PowerShell.aspx" />
    <author>
      <name>Peter</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
PowerShell takes a while to learn – especially if you have an aversion to manuals
as I do – I prefer to learn on the fly.  So, when I wanted to convert a variable
containing a comma delimited string into an array I was lost.  After a bit of
playing and ‘binging’  I found that it was actually very very easy:
</p>
        <blockquote>
          <p>
# start with a string 
<br />
$roles = "db_owner"<br /><br />
# now it’s an array of 1 element<br />
$roles = ,$roles
</p>
        </blockquote>
        <p>
Sweet!
</p>
        <img width="0" height="0" src="http://jonesie.net.nz/aggbug.ashx?id=3e997791-403e-439c-aeda-22c78896fe10" />
      </div>
    </content>
  </entry>
</feed>