Friday, March 30, 2012

Wcf to WebSphere interop: ActivityId is not protected

@YaronNaveh

I recently had to call a secured WebSphere service from a Wcf client. Fine tuning all the settings was challenging so I turned on Wcf tracing. The latter gave me detailed errors which helped me to see where I was wrong. But after fixing everything I knew of, I got this new error:

An element, ActivityId, with nsuri, http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics, is not protected by signing algorithm, sha1, and digest algorithm Rejected by filter; SOAP fault sent

Having no idea where this ActivityId element comes from , I took a quick look at the message my Wcf client was sending:

  <s:Header>
    <ActivityId CorrelationId="db5feb51-ae82-4c1b-bd68-1bdb2d09bbc6" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">f5aada53-669f-46d7-acc5-8d45e437ed86</ActivityId>
  </s:Header>


Where does this ActivityId come from?
Turns out this header is emitted by Wcf when we turn tracing on. Wcf uses this header to color the message as it flows between various layers so it can later show a single view of it.
In my case the WebSphere expected clients to sign all headers. This particular header was not signed (since wcf tracing just adds it as is) so WebSphere complained about a policy violation.
After turning off the Wcf trace settings the integration worked like a charm. So you can say the whole issue was kind of a drug side affect.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Thursday, March 29, 2012

Xml stack for node.js that works on windows

@YaronNaveh

When I developed wcf.js I extensively used xml operations. Finding the right libraries was not an easy task so I thought to share my findings here. My requirements were to use dom style xml parsing and that the whole stack will be multi-platform (read: work on windows). It turned out that there are many libraries that fulfill one of these requirements but it was very hard to find one which fulfills both. Then I wanted to run xpath operations on the dom. And again I needed a library that works on windows and integrates well with the former dom parser.

I started my journey with googling for "node.js xml parser". I immediately found node-xml which is a pure javascript sax parser. Finding other sax parsers was also easy but that was not what I had in mind. I then moved to "node.js xml dom". This actually led me to the main listing of node libraries sorted by category, and I immediately turned to the xml section. I felt like I was drinking from the firehose: Over 15 xml parsers were listed. It was very disappointing to find out that most of them are based on libxml2 which means they will work on windows only via cygwin. That's evil.


xmldom
Just before I started to roll my own xml parser I have found xmldom. Xmldom is a pure javascript implementation of dom (and sax) which makes it fully portable to any environment.

xpath.js
I also needed an xpath engine. Finding one that is cross platform was not an easier task. I have finally found xpath.js. The latter was actually not written as a node.js module (it dates back to 2006) but it was fairly easy to migrate it there. As you can see here, I just added to it this method in the end:

function SelectNodes(doc, xpath)

{
  var parser = new XPathParser();
  var xpath = parser.parse(xpath);
  var context = new XPathContext();
  context.expressionContextNode = doc.documentElement;
  var res = xpath.evaluate(context)
  return res.toArray();
}

exports.SelectNodes = SelectNodes;

Making it all work together
The following sample shows how to parse an xml document and match an xpath on it.
Note you should include the updated xpath.js as part of your project (e.g. in /lib) and the second line in the sample should reference that path. You should also install xmldom using  npm install xmldom.

var select = require('./xpath').SelectNodes   //the path to xpath.js in your project
  , Dom = require('xmldom').DOMParser

var doc = new Dom().parseFromString('<x><y id="1"></y></x>')
  , res = select(doc, "//*[@id]") //select all nodes that has an "id" attribute

 if (res.length==1)
  console.log(res[0].localName); //prints "y"

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!