Simon Fell > Its just code > December 2005

Saturday, December 31, 2005

You may remember I tried the Nov CTP of Indigo without much luck, it would insist on sending the WS-Addressing headers with mustUnderstand='1' on them, which would cause the request to correctly fail. My plea on the indigo newsgroup was met with stark silence. I finally stumbled over how to do it, in the cofig file you change the mapAddressingHeadersToHttpHeaders attribute from false to true, which turns off WS-Addressing in favor of HTTP addressing. So, here's a step by step guide to get you started with Indigo and Sforce.

  1. Login to your salesforce account and download the enterprise WSDL.
  2. Run svcUtil /tm /uxs /config:client.exe.config enterprise.wsdl to have it generate the stubs from the WSDL, the /tm & /uxs switches tell it to use typed messages and the xmlSerializer, this used to be the only way Indigo would handle the WSDL, not sure if that's still the case.
  3. Ignore the reams of warnings like Warning: Fault named LoginFault in operation login cannot be imported. Type named LoginFault from namespace urn:fault.enterprise.soap.sforce.com cannot be imported by XmlFormatter. looks like they've still got a ways to go on the fault handling.
  4. Write your client code, to make the login call you'll need something like
    SoapProxy proxy = new SoapProxy();
    loginResponse lr = proxy.login(new loginRequest(new loginRequestBody(username, password)));
    LoginResult res = lr.Body.result;
    Console.WriteLine("Logged in, SessionId is {0}", res.sessionId);
    Console.WriteLine("serverUrl is {0}", res.serverUrl);
    
  5. Now you need to redirect the proxy to the new serverUrl, from reading the docs you ought to be able to do
    proxy.Endpoint.Address = new EndpointAddress(res.serverUrl)
    but it seems to ignore this and continue to send requests to the original url, so you need to create a new instance of the proxy with a different address, at the same time, go ahead and setup the SessionHeader instance
    proxy = new SoapProxy("", res.serverUrl);
    // setup the session header
    SessionHeader sid = new SessionHeader();
    sid.sessionId = res.sessionId;
  6. Now you can make a call, here's a call to describeSObject
    DescribeSObjectResult desc = proxy.describeSObject(new describeSObjectRequest(sid, new describeSObjectRequestBody("Account"))).Body.result;
    foreach (Field f in desc.fields)
    {
    	Console.WriteLine("{0}", f.name);
    }
    
  7. Compile it up and off you go, but it won't work, you'll get the can't understand headers fault back, so go into the client.exe.config file and change mapAddressingHeadersToHttpHeaders="false" to mapAddressingHeadersToHttpHeaders="true"

You can grab a zip of the demo client and a make file : sforceIndigoClient.zip. Some things I noticed are that the serialization contains multiple duplicate namespace declarations (for the xml schema & xml schema instance) and doesn't even use them, but hey bandwidth is cheap!. I also see that there's no User-Agent HTTP header, seems like a fairly lame omission, hopefully that'll get addressed. The Out of box experience is frankly pretty shitty, the default settings mean an Indigo client is going to fail by default with pretty much any service that wasn't written in Indigo.

As far as a .NET soap stack for use with Sforce, I see nothing in Indigo that would make me switch away from the existing .NET soap stack, the programming model is more verbose and cumbersome, and still seams heavily focused purely on Indigo -> Indigo scenarios. There are still missing features that are in the .NET 2.0 soap stack like support for response compression, I hope in the remaining 12 months before they ship they can address some of more egregious stuff, but realistically I can imagine they're already in lockdown mode, punting anything that's not a critical bug to a future release, we'll have to wait and see.

Sunday, December 18, 2005

Congrats to the Ritual crew on being on the cover of Barista Magazine

Thursday, December 15, 2005

Freshly arrived from ebay, meet Major Tom on right (a Mazzer Major), along side his little sister Mini

When I first got the Mazzer Mini, I wondered how they gave it that name and kept a straight face, I mean, come on, the thing is big, don't drop it on your foot, you'll have no foot left (20+ lbs in weight and 17" height). But its completely dwafted by the Major, which weights in at a whopping 45lbs!, the thing is built like a tank, no wonder they're the industry standard.

Thursday, December 15, 2005

Russell, come on man, Starbucks, really ??? The bay area has some awesome coffee venues now, one of them right on your doorstep, get yourself down to Barefoot Coffee Roasters, and sample the delights of some real coffee. If you're in San Francisco, then get yourself over to Cafe Organica, Ritual or Blue Bottle, you won't regret it.

Wednesday, December 14, 2005

Am I the only one running into this?, most of the graphics aren't loading, plus the add to cart button is a JS driven graphic, so no image, no buying. Looks like whatever generates all the imgage URLs is broken, most of the images are trying to display http://g-images.amazon.com/images/G/01/misc/untranslatable-image-id.jpg

Thursday, December 8, 2005

I started checking out the latest version of Indigo, see if its gotten any better. It seems to really like WS-Addressing, I mean *really* like it, like HTF do you turn it off ???

Sunday, December 4, 2005

We've been long saying that one of the most important things you can do to improve the perf of your Sforce integration is to make sure you're using gzip compression on the http request/response. There's been a lot of talk both internally and externally this week about perf so I wanted to see exactly how much difference the various recommendations make. I put together a fairly simple Sforce client application in .NET that exports all the data for a single sObject to a local CSV file. It has options to control, gzip, batch sizes, HTTP keepalives. In addition it implements a "read-ahead" for query/queryMore calls, where you make the next queryMore call in parallel with processing the last set of results. (The Sforce Office toolkit also implements this). You can grab just the binary and/or source and check it out yourself. I was fairly shocked by some of the numbers i saw

 16, 16, 15
-nokeepalive16, 19, 16
-nokeepalive -batchsize 10022, 26, 25
-batchsize 10019, 18, 20
-noreadahead35, 16, 85, 15
-nogzip106, 105, 102
times in seconds to download 6415 accounts.

Things were pretty much as I expected, not using HTTP keep-alives becomes more expensive as you make more round trips. bigger batch sizes mean fewer round trips, therefore better throughput. The shocker though is how much difference turning off gzip makes, the gzip case is a whopping 6x faster overall. If you do nothing else, make sure you're using gzip compression, and I think its safe to say that anyone offering web services over the internet should make sure they're supporting HTTP compression as well. Now if the tools would only support it better.

Usage is

SforceExporter username password sObjectType [-nogzip] [-nokeepalive] [-noreadahead] [-batchsize XXXX] [-url http://some.url/]

Thursday, December 1, 2005

Things are really coming together on the latte art front (click for larger versions)