Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Wednesday, August 13, 2008

Web Service Message Level Implementations

If you're like me and prefer working with the raw XML in your web service implementations instead of dealing with the mess of generated data binding code, this article will show you how to do so using JAX-WS and XPath. In this example, we use this approach to implement a WS-Notification consumer service that receives WSDM-based messages for monitoring the health and performance of services.

JAX-WS has the Provider interface that you can implement to get access to the raw XML message. You have the choice of implementing Provider<Source>, Provider<DataSource>, or Provider<SOAPMessage>. We'll be using the Provider<Source> in this example. The invoke(Source) method is what gets called to process a service request. We'll break down the implementation of that method step-by-step.

First we send the source through a Transformer to get a DOM tree that we can use for XPath processing:

DOMResult dom = new DOMResult();
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(source, dom);

Next, we instantiate an XPathFactory and create an XPath that we'll use to process the DOM tree against. The third line calls the setNamespaceContext() method and uses a custom class I created that provides a mapping of namespace URI's to prefixes and vice-versa. You can find more information on how to implement such a class here. We need this because we'll be using namespace prefixes in our expressions.

XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
xp.setNamespaceContext(MyNamespaceContext.getInstance());

Now we'll process our first expression to extract the NotificationMessage elements from the message, passing in the XPath expression for the NotificationMessage and our DOM tree to evaluate the expression against. A WS-Notification message may contain multiple NotificationMessages so we get a NodeList in return.

NodeList resultList = (NodeList)xp.evaluate("/wsnt:Notify/wsnt:NotificationMessage", dom.getNode(), XPathConstants.NODESET);

Then we'll iterate through each item in the NodeList, i.e. each NotificationMessage, and process another expression against it to extract the ResourceId element and print it out.
String exprPrefix = "";
int len = resultList.getLength();
for (int i=1;i<=len;i++) {
String expr1 = "/wsnt:Notify/wsnt:NotificationMessage[" + i
+ "]" + "/wsnt:Message/muws1:ManagementEvent"
+ "/muws1:SourceComponent/muws1:ResourceId";
String resourceId = xp.evaluate(expr1, dom.getNode());
System.out.println("Resource ID: " + resourceId);
}
The entire source code listing can be found here. You'll notice that the class has the following two annotations:

@WebServiceProvider()
@ServiceMode(value=Service.Mode.PAYLOAD)

The first one tells JAX-WS that this class is a Provider endpoint. The second one says that we only want to work with the message at the payload level, i.e. we don't need to access the message headers. In addition to these annotations, we have to customize the WSDL to mark the port as a Provider interface. This can be done by embedding the customizations directly within the WSDL or through a separate customization file. We'll do it using a separate provider-customize.xml file--you can find this file here.


Bookmark and Share

Friday, April 20, 2007

Guard Your Data Services Carefully

A common thing to do these days is to create data access web services directly on top of your databases to open up access to that data to other services and applications, essentially creating a data services layer for your SOA. I've even recommended such an approach before. While conceptually this may be a good idea, this also presents an increased security risk.

To be widely usable (or reusable), these data services tend to need to support a general querying interface. A lot of EII products will in fact let you create data services that will take XQuery to query the data source. This is in effect analogous to widely opening up a SQL interface into your database. There's a reason why direct connections to databases are not made widely available--either someone can issue malicious queries to the database or some inept developer can create some massive query that will bring the database to its knees.

Besides not widely opening up direct database connections, RDBMSes also have pretty fine-grained access control so that you can specify what users have what kind of access to specific tables and columns. The data services in your SOA will also need such fine-grained access control policies. In this case, they will be specifying access control on the specific operations and XML elements and attributes. The key is to be able to specify and enforce the policies down to the specific elements and attributes.

Ideally, this would be done through a tight integration between the service's policy enforcement point and the XQuery processor (assuming you're supporting XQuery on your data service) so that if your XQuery references attributes and elements you don't have access to, the query wouldn't even be processed. I don't know of any products that do this, but there are some other ways to do it.

Assuming the source of your data service is an RDBMS, you could set up an access control policy internal to the RDBMS that maps to the access control policy of the data service so that once the XQuery is translated to SQL and executed in the RDBMS you let the RDBMS's security mechanisms enforce the access control.

If maintaining two sets of mapped access control policies like this sounds like a pain in the ass, the other approach is to have a post processing step where you can strip out data from the XML using XSLT for the parts that the client does not have access to. With this approach, you need to make sure that you've designed the XML schema such that once you've stripped out those parts you still have a valid XML document. Also this approach may not be the most efficient--bringing back all the data as XML and then applying XSLT to filter stuff out. It would be much more efficient to do that in the RDBMS.

And then lastly, similar to how direct access to databases are not made widely available, you're going to have to be more restrictive about who you grant access to your data services. This will also prevent any Joe Schmoe developer in your enterprise from issuing some crazy XQuery that will bring down your data service and the database behind it. Such restrictiveness may be in direct conflict with one of your reasons for creating data services in the first place, but it's probably a necessary compromise.

Saturday, November 04, 2006

OpenDocument and Microformats

Microformats allow you to embed chunks of semantic metadata into XHTML documents using simple extensions to the existing tags. Some simple examples are embedded event and people information using the hCalendar and hCard microformats. What's nice about this is that now machines can accurately parse and extract key entities out of web pages that embed microformat metadata. Microformats are really starting to take off now on the web, especially with the Web 2.0 sites. OpenDocument is an OASIS XML standard for storing and exchanging office documents (i.e. reports, spreadsheets, presentations, etc.). Given that most of the information being generated by organizations today are such office-type documents, if the OpenDocument format really takes off, it would be nice to be able to embed semantic metadata into these types of documents using Microformats. A lot of organizations are employing content-management type of solutions to be able to better manage and use their corporate information. A lot of these types of solutions employ sophisticated text mining components to extract key entities out of such documents so that they can be better categorized and searched against. Imagine how much more accurate such text mining could be if there were Microformat metadata embedded in the office documents. Not only would it improve the accuracy of the text mining, but it would open up all that corporate information to a whole new world of interesting things that could be done to it as we are seeing with information on the web.

, ,

Wednesday, September 27, 2006

XML Compression is Not the Answer to Your SOA Performance Woes

Articles like this are misleading. XML compression will reduce the size of the message and thus reduce the time to transfer the message. But if you've ever done any performance testing and profiling on Web services, you will know that most of the times the performance bottlenecks are not in the message transfer but the XML processing, i.e. parsing the message. Thus, compressing the message will not do you much good. Some may say that in a bandwidth constrained environment, the compression does help. But if you're working in a bandwidth constrained environment, you probably shouldn't even be using such technologies in the first place. What does help tremendously is offloading the XML processing to dedicated XML appliances and the article does point that out.

, ,

Monday, April 17, 2006

XML Parser that Uses Pointers to Locations in the File

Reminds me of something I did for Mercator back when I was working on their transformation engine that was part of their integration broker. Can't get into too much detail since that product's still in existence although under a different company and different product name. The idea is good when dealing with large XML files since you don't have to load the whole document into memory. I can certainly see how this can improve memory requirements but I'm a bit skeptical about the performance, especially if you have to do file i/o whenever you need to get some attribute or element. Take a look at the Xerces-C code. If it hasn't changed too drastically since I last looked at it (about 3 years ago), it's not that difficult to build some mods that hook into their scanner classes to do this as well. Maybe that way you can get the improved memory usage as well as conformance to the W3C XML specs.