Archives

Archives / 2004 / May
  • Enumerated types in Web service interfaces and BizTalk

    On my last Biztalk project, I had to call a Web service interface containing an operation with an enumerated data type. As it turned out, that’s a non-trivial task. You would think that importing the WSDL would create a .NET enumerated type which you can use in a Message Assignment shape.

    Instead BizTalk creates an XML Schema for the enumerated type. You can get see the schema file if you expand the Reference.map node under your Web Reference

    In the schema you’ll find a simpleType definition and a corresponding element definition. What’s odd is that the parameter in for the enumerated type expects you to assign the full element, not just a valid value of the enumeration.

    This may seem odd to you if you are used to consuming Web services in .NET applications, where you simply assign the parameter value. Let’s take a look at the enumeration definition in the following schema and I’ll show you what I am talking about:

    <xs:schema xmlns:tns=" urn:my-log-service" elementFormDefault="qualified" targetNamespace=" urn:my-log-service" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="Severity" type="tns:SeverityType" />
      <xs:simpleType name="SeverityType">
        <xs:restriction base="xs:string">
          <xs:enumeration value="Debug" />
          <xs:enumeration value="Information" />
          <xs:enumeration value="Warning" />
          <xs:enumeration value="FatalError" />
        </xs:restriction>
      </xs:simpleType>
    </xs:schema>

    If you were to consume a Web service that has a parameter of the SeverityType in a regular C# application then wsdl.exe would generate an enum for the SeverityType and a methods that takes a parameter of that type like this:


        [System.Xml.Serialization.XmlTypeAttribute(Namespace=" urn:my-log-service")]
        public enum SeverityType {
            Debug,
            Information,
            Warning,
            FatalError,
        }


        public void Log(SeverityType sev, string text)


    When I need to send a Log message to the Web service, the imported enumeration allows me to write simple C# code like this:

    LogService svc = new LogService();
    svc.Log( SeverityType.FatalError, logText );

    and the Xml serialization plumbing in the Web service proxy will produce the a SOAP message with an XML representation like this:

      <soap:Body>
        <Log xmlns="urn:my-log-service"/>
          <sev>FatalError</sev>
          <text>Things are really messed up right now</text>
        </Log>
      </soap:Body>

    Both parameters are embedded in the body.

    In BizTalk, the programming model is different. It's not as simple as just assiging the literal value to the sev parameter. If  Message_1 is the message you are sending to the Web service, you cannot just say:

    Message_1.sev = “FatalError“;

    because the sev parameter is of type SeverityType. If you're familiar with XML Schemas then you might argue that SeverityType is really just a string that can only take certain values -- and you're fully correct. However, BizTalk think about it slightly different. It expects that you assign a SeverityType to sev. How would you do that?

    You actually have to assign the complete <Severity> element from the schema, which is of type SeverityType, to the <sev> parameter, even though only the element value needs to go into the message sent to the service.

    One way to set up the message in BizTalk is to load the XML element into a variable of the .NET XmlDocument type. If Message_1 is the message to send to the service and doc is an XmlDocument variable then you would populate the message in a MessageAssignment shape with the following code:

    doc.LoadXml("<Severity xmlns='urn:my-log-service'>FatalError</Severity>");
    Message_1.sev = doc;
    Message_1.text = "Things are really messed up right now";

    This looks like the SOAP message would contain an extra Severity element:

          <sev><Severity>FatalError</Severity></sev>

    but that is not the case. The message going to the service is the same as in the C# example above.

    If your orchestration deals with many messages that contain enumerated types then writing all the message generation code in a separate .NET assembly is a good idea. It would keep the code in the message assignment shapes much cleaner and the orchestration developers don’t need to think about extraneous XML elements.

    Read more...

  • Flying Pointy Brackets == Anglebrackets?

    I recently listened to Christian’s web cast on WSE 2.0, which is in German. I noticed a couple of things:

     

    • Christian uses English terms for most technical items he's talking about.
    • Americans always tease me how the German languase is so expressive. This is particuarly true in this case. The German expression for angle brackets would translate to “flying pointy bracket” – or in German: fliegende spitze Klammer. I can’t imagine talking about flying pointy brackets … that just sounds so weird. Pointy yes, buy flying?

    Read more...

  • Doug Purdy on Remoting

    About a month ago, there was a flurry of activity around the question if remoting is dead. Now some people think that it's not dead, it just smells funny.

    However, Doug Purdy pointed out today in his versioning talk at TechEd that a number of features in Longhorn are built using .Net remoting. Now we have BizTalk 2004 and Longhorn both using remoting. I think that is a clear statement that remoting will stick with us for a while. It's important to understand who each technology fits.

    One has to carefully evaluate if remoting is the right choice to connect applications running on different servers. Web services provide a solution that will easily integrate with applications built with Indigo (which is still years away).  If you need to communicate across AppDomains on the other hand, then remoting is your only option in the .Net Framework and future integration with Indigo is likely not an important consideration.

    Read more...

  • Message Tracing in BizTalk Web Service Proxies

    I blogged about the message tracing feature in WSE yesterday, but WSE isn’t the only recent Microsoft product with a built-in tracing feature.

     

    If you look at the code generated by the BizTalk Web Services Publishing Wizard you might notice a couple of things:

     

    • Two commented out SoapExtensions LINK in the web.config file.
      <webServices>

             <soapExtensionTypes>

               <!-- add type="$SoapExtensionType.FullName$, $AssemblyName.Name$"

                 priority="1" group="0" /-->

          </soapExtensionTypes>

          <soapExtensionReflectorTypes>

            <!-- add type="$SoapExtensionReflectorTypes.FullName$, $AssemblyName.Name$" /-->

          </soapExtensionReflectorTypes>

         </webServices>

    • Two C# source code files, TraceExtension.cs and WsdlExtension.cs. Those files house the source code for the SoapExtension and the SoapExtensionReflector to be referenced in the web.config file. Yet neither one of these files is part of the BizTalk Web Service Proxy project by default.

     

     

    The SoapExtensionReflector allows customization of the WSDL document returned by the proxy Web service. The SoapExtension allows you to trace messages processed by the Web service proxy. Enabling tracing at the web service layer helps end-to-end troubleshooting of orchestrations exposed via web services, since the BizTalk message tracing only captures messages that are actually processed by a BizTalk receiver location. If for some reason the proxy cannot send the SOAP message to the receiver location, then addind tracing to the proxy is a great troubleshooting help.

     

    To enable message tracing for the Web service proxy, you have to add the TraceExtension.cs file to the Visual Studio solution and build it. Then you have to activate the SOAP trace extension in the web.config file. Uncomment the <add> element and specify FullName and the assembly name of the TraceExtension to have the ASP.NET Web services plumbing to load the SoapExtension in the SOAP processing pipeline.

     

    <soapExtensionTypes>

      <add type="Orchestration_Proxy.TraceExtension, Orchestration_Proxy" priority="1" group="0" />

    </soapExtensionTypes>

     

    Now you can deploy the generated assembly and the updated web.config file to the ASP.NET web service and all SOAP requests and responses are written to a tracing file. By default, this tracing file lives in the <Temp Directory>/BizTalkWebServices<AssemblyName>_<AssemblyVersion>, but you can customize the location by adding a [<ProjectProjectNamespace>.TraceExtension] attribute to the [WebMethods] of the proxy service.

     

    [WebMethod]

    [TraceExtension(Pathname=”C:\\MyTraceDir\”]

    public void DoStuff()

    {

    // …

    }

     

    One final thing to keep in mind for the tracing extensions is performance. The code for these proxies is not intended for high-throughput scenarios. You should only take this approach during development or in debugging activities in isolated environments to. For everything else, you should stick to the message tracking features in Biztalk.

    Read more...

  • Tracing capablities in WSE2

    WSE 2.0 was released at TechEd today. Congratulations to the WSE team with Rebecca Dias, Keith Ballinger and the rest of the WSE Team. Version 2 comes with support for WS-Addressing, WS-Security, WS-Policy and a few other WS-* standards.

     

    WS-Addressing moves the destination URL of the message into the message to enable routing and scenarios where messages are delivered over multiple protocols. Before WS-Addressing the URL of the destination was only available in the protocol part of the message. Is you were sending a SOAP message over HTTP, the URL was stored in the HTTP part of the message. You had no access to the URL from within your SOAP processor – unless your Web server vendor chose to give you access to the HTTP headers.

     

    Now with WS-Addressing built into WSE, the Web service platform can actually determine if a message was indeed intended for the service that received it because WSE adds the <to> element to the header of the SOAP message:

     

          <wsa:To xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">

    http://MyServer/MyService/Service.asmx</wsa:To>

     

    WSE is actually being smart about the header and rejects messages where the destination in the <wsa:To> header and the URL in the HTTP header do not match.

     

    One unfortunate consequence of this behavior is that you cannot use transparent tracing tools like tcpTrace and MSSoapT for message debugging. These tools act like an intermediary receiver and they do cause the URLs in the <To> header and in the HTTP header to not match. If you tried, the WSE web service returns a nice, descriptive fault telling you exactly what’s going on:

     

    Microsoft.Web.Services2.Addressing.AddressingFault: Destination Unreachable ---&gt; System.Exception:

    WSE816:

    The &lt;To&gt; header must match the value of an incoming message's HTTP Request Url if the soap receiver does not have an actor name.

    The &lt;To&gt; header received contained "http://localhost:8080/WSEWebService/Service1.asmx"

    while the HTTP Request Url was "http://localhost/WSEWebService/Service1.asmx".

     

    You could fix the problem by modifing the WSE server code that is sending the message to tell the receiver about the URL of the tracing tool by adding a SoapActor attribute to the service.

     

    <System.Web.Services.WebService(Namespace:="http://tempuri.org/WSEWebService/Service1"), _

    SoapActor("http://localhost:8080/WSEWebService/Service1.asmx")> _

    Public Class Service1

     

    But that defeats the purpose of a transparent tracing tool and in many cases it may just not be feasible to modify the service code for troubleshooting purposes.

     

    The good new is though that you no longer need tracing tools when you need to debug SOAP messages processed by a WSE service. You simple configure WSE to trace the output for you using the WSE 2.0 Settings tool. On the “Diagnostics” tab of the tool you will find the two sections “Message Tracing” and “Policy Tracing”. When you check the “Message Tracing” check boxes, WSE will write all processed messages – sent and received – to a trace file.

     

    The “Policy Tracing” setting is even better though. With the powerful, declarative, policy based model, WSE does a lot of message processing with no coding involved. For example WSE will reject SOAP messages that violate the policy configuration. If the policy requires messages to be signed with a particular security token, but the message contains the wrong signature, WSE will simply return a policy violation fault. Unfortunately, the error message is not quite as descriptive as it was for the missing SoapActor attribute.

     

    The policy trace output is extremely handy in this scenario, because it will tell you which policy was violated. The result of the policy enforcement step for each received message is written as a <message> element to the policy trace file:

     

      <wset:message to="http://localhost/MyWebMethodsWse/Service1.asmx" from="http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous" action="http://example.org/mortgage-tools/CalculateMortgage" messageId="uuid:5334eabc-58e7-4220-984e-35cc2c5309ce" appDomain="/LM/W3SVC/1/Root/MyWebMethodsWse-16-127289102890960160" time="2004-05-12T22:52:19.7795824-05:00">

        <wset:verify qname="wsp:Policy" wsu:Id="#Sign-Username-2" usage="Required" satisfied="false">

          <wset:verify qname="wsp:MessagePredicate" usage="Required" satisfied="true" />

          <wset:verify qname="wssp:Integrity" usage="Required" satisfied="false" />

        </wset:verify>

      </wset:message>

     

    The example above shows that the required Integrity assertion of a policy named “Sign-Username-2” failed – the satisfied attribute for this assertion is set to false. Now you can check the policyCache.webinfo file for the policy with a wsu:Id attribute set to "Sign-Username-2":

     

    <policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">

      <policies …>

        <wsp:Policy wsu:Id="Sign-Username-2">

          <wssp:Integrity wsp:Usage="wsp:Required">

     

     

    and verify what Integrity claims the policy required. Finally, you can cross-check the claims against the received message and you can determine the cause of the assertion failure. I really like the fact that tracing is now a framework feature. It seems to be the Microsoft way to handle this, more on that soon.

    Read more...

  • Tablet, Centrino, Battery life and CPU clock speed

    I recently got my Acer Tablet with the power-saving Centrino technology. I am getting very decent battery times out of it, too. 4-6 hours with wireless on if I am not coding and running the compiler a lot.

     

    One of the ways Centrino conserves battery power is to slow down the CPU. You can see the speed your CPU is running at if you bring up the properties dialog for “My Computer”.

    In the lower right corner you see the maximum speed the processor can run at, and the current speed.

    The maximum speed the processor will actually run on is determined by the selected Power Scheme.

    When the computer runs on the “Max Battery” setting, the CPU clock speed never exceeds 600MHz. With other power schemes selected the CPU can run up to the “advertised speed” of 1.5 GHz.


    What I haven’t found though, is a detailed listing of the actual capabilities of any given Power Scheme. Is this accessible via WMI? Can I create my own profile? Does anybody know?

    Read more...

  • The Power of the Pen - and BizTalk doesn't use it

    Am I the only one to use the BizTalk Orchestration Designer on a Tablet PC? The drawing UI metaphor of the Orchestration Designer works really nice on a tablet with a pen. I think it's totally cool to draw orchestrations on the screen, instead of using the mouse -- it's almost like in the movie “Minority Report“, where Tom Cruise moved images on those giant transparent displays by waving his hands.

    While “drawing the orchestration” with a is a nice user experience, there are some features in the UI that are very pen unfriendly. Drag-and-drop support from the Orchestration View onto the designer surface or the property editor would help the mouse users, but it would make the pen experience downright awesome. For example, I would love to just drag a port type to port on the desinger surface, drop message types onto operations or access my binding files from a chooser UI and drop it onto the orchestration in the BizTalk explorer.

    Can I have these features in the next BizTalk service pack ? ;)

    Read more...

  • My TechEd Schedule

    I'll be the cabana boy in the Web services cabana:

    Monday 11:30-3:30 pavilion

    Wed 12:30-3:30 pavilion

    and proctor the WSE Hands-On-Lab

    Tuesday and Wednesday afternoon.

    Update: I'm not a cabana boy. I'm a booth babe in the pavilion instead.

    Read more...

  • I'm the Indigo guesser!

    Didn't I speculate that we'll see Indigo before Longhorn a little while ago?

    Here's what Eric Rudder says now:

    "We have the ability to release Indigo Web services technology and have it run on Windows Server 2003, have it run on Windows XP client and just be included when you install Windows Longhorn," Rudder said. "We haven't decided on a date, but we are going to make Indigo available on other (Windows) road maps."

    It may not be Whidbey, but we don't have to wait until Longhorn for the official of Indigo ;)

    Read more...