Simon Fell > Its just code > May 2005

Saturday, May 28, 2005

There's a minor release of TcpTrace available which allows you to enter up to 500 characters now in the server name dialog.

Friday, May 27, 2005

To the PocketSOAP mailing list, 4 years old today and still going strong, which means PocketSOAP itself is around 4.5 years old now, that's a lot s:Envelope elements its moved on the years.

Wednesday, May 25, 2005

Using the Beta1 RC bits of Indigo, here's a sample of using Indigo with the Sforce enterprise WSDL

  1. Login to your account and download the enterprise WSDL (goto setup -> Integrate -> WSDL Generator)
  2. You need to modify the WSDL to work around a bug in svcutil relating to where namespaces are declared, copy the definition of the fns namespace from the root element, down into the schema element that is just before the <simpleType name="ExceptionCode"> element
  3. generate the Indigo proxy by running svcutil /uxs /tm /config:client.exe.config enterprise.wsdl
  4. edit the generated enterprise.soap.sforce.com.cs and add the Position attribute to the login_RequestMessage class, e.g.
    [System.ServiceModel.MessageContractAttribute()]
    public class login_RequestMessage
    {
        
        [System.ServiceModel.MessageBodyAttribute(Namespace="urn:enterprise.soap.sforce.com", Position=0)]
        public string username;
        
        [System.ServiceModel.MessageBodyAttribute(Namespace="urn:enterprise.soap.sforce.com", Position=1)]
        public string password;
    }
    
  5. compile the sample client code with csc client.cs enterprise.soap.sforce.com.cs /r:"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\System.ServiceModel.dll"
  6. run the generated client.exe, with client.exe <username> <password>

If you're used to working with Sforce from .NET then it should all look familiar yet different.

  • The proxy instance is created with SoapProxy proxy = new SoapProxy(new EndpointAddress("https://www.salesforce.com/services/Soap/c/5.0"), new BasicProfileBinding(BasicProfileSecurityMode.Https)); because using new SoapProxy("Soap") which should read the config from the generated config file fails.
  • The typed message model used by Indigo in this case means that what used to be a one liner to make the login call, now takes 4, urrgghhh, this is progress ?
  • To handle the server redirect part of the login process, it creates a new proxy using the previous Binding object, proxy = new SoapProxy(new EndpointAddress(res.serverUrl), proxy.Endpoint.Binding);
  • The proxy no longer holds the state of the headers between the different calls on the proxy, its now the client programmers job to track this, every authenticated Sforce call will need to set the SessionHeader property of the request message object for that call. (see above, urrgghhh, is this progress?)
  • Note that the nonsense with the Specified flags hasn't gone away.

I'm sure if you're doing Indigo to Indigo it rocks, but if you're connecting to an average no frills WS-I compliant service, then I really don't see why I'd be excited about Indigo, the only thing it seems to over the .NET client stack in Whidbey is the better handling of the detail element in soap faults. (but apparently without Whidbey's handling of HTTP response compression) I'm not sure that the verbose and tedious programming model is worth that benefit, YMMV, As I said yesterday the programming model feels like a clunky mix of messaging and rpc, either give me proxy.send(login_requestMessage) or proxy.login(username, password), not this weird hybrid

Tuesday, May 24, 2005

Got the new drop installed, although the final step, which I think is the docs, died with an AV. The good news is that the SSL problems that were plaguing me are gone, but I ran into one new problem, the generated config file just doesn't seem to work, calls to new SoapProxy("Soap") return an error

Unhandled Exception: System.InvalidOperationException: Could not find Channel element for configuration name Soap and contractType Soap, client, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.
at System.ServiceModel.Design.ConfigLoader.LoadChannelDescription(ChannelDescription channelDescription, ContractDescription contract, String configurationName, EndpointAddress address)
at System.ServiceModel.Design.ChannelLoader..ctor(Type contractType, String configurationName, EndpointAddress address)
at System.ServiceModel.ChannelFactory`1..ctor(String configurationName)
at System.ServiceModel.ProxyBase`1..ctor(String configurationName)
at client.Main(String[] args)

The problem with the missing Position attributes in the generated code is still there, but the problem around arrays not being declared as arrays is fixed. I was able to put together a quick sample that created some accounts and queried them back.

I finally worked out what it is about the programming model that bugs me, I have to create a request object that represents the entire request message, yet the proxy still have methods on it for each operation, so you end up with code like

create_RequestMessage crm = new create_RequestMessage();
// populate all the headers and body for crm
proxy.create(crm)

It seems weird that the operation to be invoked is both embodied by the type of the create message, and the method I pass it to on the proxy, It feels like some halfway house between the RPC style, and a more messaging style.

Monday, May 23, 2005

Currently installing the latest drop of Indigo, see what's improved from the last one. I'm confused by the Beta1 RC label though, is it, (a) a Release Candidate of Beta 1, or (b) the beta 1 of the Release Candidate ??

Sforce PM Benji Jasik will speaking at SDForum tomorrow on Web Services, looks like an interesting lineup including Jeremy Zawodny from Yahoo, Tim Bray from Sun and Jeff Barr from Amazon.

Tuesday, May 17, 2005

Using Kirill's tips, I was finally able to get a simple Indigo client up and running

  1. svcutil /uxs /tm /config:client.exe.config enterprise.wsdl
  2. modify the generated code to add the Position attributes to the login_RequestMessage class, as Kirill details.
  3. This is going over HTTP because I still haven't been able to get HTTPS work (tried a few different things with a variety of errors), so only use it with test logins!
  4. Change the generated config file to change the endpoint address to http from https
  5. Change the generated config file to increase the max message size
  6. Compile and run this code
SoapProxy proxy = new SoapProxy("Soap");
login_RequestMessage loginMsg = new login_RequestMessage();
loginMsg.username = "[your_login]";
loginMsg.password = "[your_password]";

login_ResponseMessage lr = proxy.login(loginMsg);
LoginResult res = lr.result;
Console.WriteLine(res.serverUrl);
Console.WriteLine(res.sessionId);

Binding bind = proxy.Endpoint.Binding;
proxy = new SoapProxy(new EndpointAddress(res.serverUrl.Replace("https:","http:")), bind);

query_RequestMessage qrm = new query_RequestMessage();
qrm.SessionHeader = new SessionHeader();
qrm.SessionHeader.sessionId = res.sessionId;
qrm.queryString = "Select Id, Name from Account";
qrm.QueryOptions = new QueryOptions();
qrm.QueryOptions.batchSize = 10;
qrm.QueryOptions.batchSizeSpecified = true;

query_ResponseMessage rm = proxy.query(qrm);		
Console.WriteLine(rm.result.size);		
foreach (Account o in rm.result.records) {
	Console.WriteLine("{0} {1}", o.Id, o.Name);
}		

And off you go, having to manually manage the header values between each call and the type message programming model makes it feel really cumbersome, I hope at least the operation_RequestMessage objects will get constructors that allow you to set all the values in one go.

I was also surprised to find that the resulting serialization to be unusual, seems more verbose that most of today's tools, I also noticed that it doesn't send up a Http User-Agent header.

<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Header>
      <h:QueryOptions
          xmlns="urn:enterprise.soap.sforce.com"
          xmlns:h="urn:enterprise.soap.sforce.com"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <batchSize>10</batchSize>
        </h:QueryOptions>
       <h:SessionHeader
          xmlns="urn:enterprise.soap.sforce.com"
          xmlns:h="urn:enterprise.soap.sforce.com">
         <sessionId>[mySessionId]</sessionId>
        </h:SessionHeader>
     </s:Header>
   <s:Body>
      <query
          xmlns="urn:enterprise.soap.sforce.com"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <queryString>Select Id, Name from Account</queryString>
        </query>
     </s:Body>
  </s:Envelope>

Monday, May 16, 2005

Kirill finally caved and started a blog, included are a bunch of notes on the issues I was running into with Indigo, thanks Kirill!

Sunday, May 15, 2005

Learning Python has been on my todo list for far too long, I finally got around to reading Dive Into Python and have been tinkering away (on Ubuntu, might as well learn everything at once) with some xml related ideas. I tried out Aaron's xmltramp, and it absolutely rocks, now if it could just do serialization as well, I'd be all set. I'm currently using the Python wrapper for GenX, which is working great, but feels long winded in the world of everything is a 5 line Python script.

Saturday, May 14, 2005

Turns out there was a bug in the tracing option for PocketHTTP 1.2.5 (it wouldn't trace the HTTP response), this is now fixed, and PocketHTTP 1.2.6 is now available. I also bundled up a new PocketSOAP version with the new PocketHTTP included.

Tuesday, May 10, 2005

Man, you leave the country for the weekend, and SOAPBuilders bursts back into life to discuss current interop issues, worth the read.

Wednesday, May 4, 2005

Just posted PocketSOAP v1.5.1 mainly bug fixes, includes

  • A fix for a problem recieving small attachments when the server is using a chunked response with a small chunk size.
  • A fix for the problem deserializing soap messages that contain an xmlns="" attribute.
  • SOAP faults could result in the entire HTTP response not being read, causing problems with PocketHTTPs tracing, and causing the connection to not get re-used correctly.
  • Upgraded to PocketHTTP 1.2.5.

Congrats to Glen, Dims and the rest of the Axis folks on shipping Axis v1.2.

Monday, May 2, 2005

Sunday, May 1, 2005

While over in the east bay for a fabulous sunny Sunday afternoon BBQ, I figured we'd drop in the Emeryville Apple store and now that Tiger's out finally pull the trigger on a Mac Mini. It didn't go well, I wanted the Bluetooth module, see if I could finally get something to sync my 3650 with and some extra memory, seemed straightforward enough to me, but no they don't have the Bluetooth module on its own, I have to get the Bluetooth & wireless combo. Wasn't really sure I wanted to blow an extra $100 just to get Bluetooth but decided to go ahead anyway, only to be told they'd put it together and call me in 48 hours or so to pick it up ! WTF, 48 hours ??, ok, I realize that someone has to pry the damned thing apart and fit the extra memory and Bluetooth module but 2 days, come on, that's insane. I'd just buy one from the online store, but no, the online store doesn't accept apple gift cards, they're only valid at retail stores. What the hell happened is it still 1995 or something ?? Oh, and no it comes with Tiger, but its not pre-installed, you need to do the upgrade yourself (and the Apple web site still says its comes with Panther!), if Apple ever wants to break out of their fanatic fan base, they really need to look at this, I'm sure when Windows 95 (or XP, or Longhorn when it ships) was released that it was available pre-installed from the minute it was released.

So now I'm home and Ubuntu is busy installing on a spare box, perhaps I'll just blow my apple gift card on some ipod socks

Tiger is all of 2 days old, yet J2SE 5.0 is a separate download, the bundled version is 1.4.2