NServiceBus consume 3rd party xml - nservicebus

All, can anyone provide me some guidance on allowing NServiceBus to consume XML messages off a queue that were not created by NServiceBus. I am trying to integrate with a 3rd party system that drops XML messages to a queue. I have VERY little control over the XML the 3rd party produces.
I have tried wrapping their XML with the -Messages/- tag and I can get the message to hit the right handler, but many of the fields (especially in child classes) just deserialize to null. The 3rd party produces several "types" of messages but in all cases the XML is reasonably simple.
I'm trying to avoid writing an adapter that just reads XML and drops messages on the bus.
Any advise would be appreciated.
Thanks

The key lies in how you generate the message classes. If you can, you should get the XSD schemas from the third party that represent the XMLs they are sending you.
Then you can generate classes off the schemas using xsd.exe which will pretty much guarantee clean de-serialisation from XML to type.
If you can't get the schemas then you can again use xsd.exe to infer the schemas from the messages. However this method is not particularly fail-safe, and will expose you negatively to anything unexpected the message which does not conform to your inferred schema.

The serialization in NSB is abstracted so you could write your own serializer based on that format. You can then tell NSB to use your serializer instead of one of the built in ones.

Related

Self-contained or versionable messages?

I'm having some message design head-aches. I want to start up an NServiceBus saga for a long running process. Part of the data needed to do the initialization is a list of constraints, which are implementations of an abstract base class. As I've understood the design philosophy, messages should ideally be
Self-contained, that is contain all the data needed to process them. Following this, I would pass along all the list of constraints in the message.
Versionable. NServiceBus does this by using an XML serializer which does not pass along type information (see this thread answer by Udi). In my case, that means I cannot on the recieving end pick up the specifics of the constraints.
The serialization problems can be "solved" by using the BinarySerializer, but this does not seem to be a recommended practice since it breaks versioning. The alternative is to send along some identifier so that the constraints can be retrieved from some datastore, but that would remove the "self-containedness".
Is there a third way here, or do I simply have to choose some "least bad" solution?
There is also the option of having these objects injected into your saga via DI.
Just create a boostrapping class that at startup will call:
Configure.Instance.Configurer.ConfigureProperty<yourSaga>(s => s.SomeProperty = value);

Message validation with Schema in WCF

What I want is to decorate my data contracts with few attributes (e.g. min,max, string length etc.) and get the XML schema generated for my SOAP (non .net) clients. After some research on internet, I have come across the following article:
http://wcfsecurity.codeplex.com/wikipage?title=How%20To%20-%20Perform%20Message%20Validation%20with%20Schemas%20in%20WCF
This seems to be pretty manual to me. I am after some more decent solution and out of the box functionality. With WCF offering so much, I will be surprised if it has missed this whole concept of SOAP standard validation.
Any help on this will be much appreciated.
The XML schemas for the DataContract objects are found in the WSDL for the service. WCF does not explicitly validate soap messages against these schemas for a number of reasons. First, the process of deserializing soap messages, in effect, performs validation based on the DataContract or XML serialization defined on the data classes. Next, there is a definite performance hit if every soap message was being validated against the XML schemas. Lastly, WCF supports soap message versioning for both forward and backward compatibility through the IExtensibleDataObject optional interface capability. To do this, XML schema validation would most likely be too strict.

How the term "WSDL" is related to programming when consuming webservices?

I have read several posts about WSDL and SOAP but still I'm confusing the actual meanings of those terms. Now, I understand that you need to construct a request message in order to consume a webservice, would it be post or get message. When talking about SOAP based webservices, you need to communicate with a webserver via constructed XML documents that are SOAP compliant. So, you need to build that manually or using proper libraries. What about WSDL, when this thing comes in?
Wikipedia states "WSDL is often used in combination with SOAP and an XML Schema to provide Web services over the Internet. A client program connecting to a Web service can read the WSDL file to determine what operations are available on the server.". So that means that WSDL is just some file describing what services are available on webserver, and I guess, such communication must also be done using SOAP. But if I know all the webservices I use, I mean, if they are hardcoded then that means that I'm not dealing with WSDL at all. IMHO WSDL is just for very smart systems where before using webservices a program needs to read status and determine what to read. Am I right?
WSDL is a means to describe what operations (method) the webservice has as well as the input/output of those methods. In the past, way before the mobile becomes popular, WSDL is used as a means for creating what is known as a stub/proxy classes.
These classes is basically generated by specific Generator (such as WSDL2Java for Java or WSDL.exe for .NET) whose job is to read the WSDL, get the methods along with its input/output and generate a language specific classes to expose those services natively. In effect, it is hiding the SOAP messages from the user and the from the consumer of the webservice point of view, they are dealing with the native classes of their language of choice.
WebService with SOAP thus was heralded as means of integration between heterogeneous systems, allowing a communication that is language independent. For example the language for implementation for the service could be in C# but the consumer of the webservices can be in Java. If the consumer is Java programmer, by using the WSDL to auto generate the classes, the Java programmers don't even need to know the concept of SOAP or XML. All the programmers know that they are dealing with Java object.
Nowadays, SOAP is more transparent and well known than it was in the past. As a result, by choice programmer can directly code the SOAP message, bypassing the need to generate the code via WSDL

MsmqIntegrationBinding Serialization with Unknown Message Body Types

I'm looking to use the MsmqIntegrationBinding to integrate with a legacy queue which has a serialized object as the message body. Has anyone come up with a way to obtain the "metadata" of the message body and create a service side class to use within the service?
For example, if I put in a serialized Product object from System A and my service needs to consume it, how do I provide MsmqMessage the type if I do not have the Product class on my side? I was thinking of reading off a message in a separate program, deserializing, and then emitting via the code dom. Ideas?
I wholeheartedly recommend against attempting to emit the deserialized type at runtime in the message destination. Either work with the XML at the destination to obtain the data you desire, or build data contracts that both the source and destination can adhere to.
Hmm... in WCF, you can define service methods which take (and optionally return) an untyped Message type. This seems to fit your bill quite nicely.
Other than with strongly typed messages, you'll have to do all the putting together of the message on the client and the taking apart on the server by means of reading the raw XML - but that seems to be what you're looking for, right?
Find more information and samples here:
WCF - Handling Generic Messages
How to pass a generic object through WCF
Untyped messages on WCF
Untyped messages have some restrictions, e.g. you can only read them once on the server, but you should be able to manage your scenario with this, I think.
Marc

WCF System.ServiceModel.Channel.Message: binary message contents (non-XML)?

I need to retrieve binary (non-XML) documents as Messages in a custom WCF LOB Adapter (for consumption by BizTalk). The messages need to be represented as instances of System.ServiceModel.Channel.Message.
I can't find how to create an instance of this class when the content is binary (by "binary" I mean any arbitrary byte array or Stream, and not only binary representations of XML documents).
Is this possible? Or would wraping the binary contents in an XML enveloppe be the only way to do this in WCF?
Fundamentally, WCF messages are XML, since the S.S.C.Message class uses the Xml InfoSet as the base message representation.
So yes, in some way you need to "wrap" your binary content into an XML envelope (which doesn't need to be a SOAP envelope, mind you, depending on how your binding is configured).
That said, note that this doesn't preclude streaming to deal with large message payloads without buffering the entire message in memory; WCF still allows you to do this, though sometimes it's not greatly obvious how it works.
Since you're working with a custom channel, you've got one of two choices, I think:
Have your own channel add the XML wrapper around your binary content before passing it upwards or
Create a custom MessageEncoder that adds it in for you automatically.
In either case, if you're dealing with large messages, you'll want to make sure you use the MessageEncoder overloads that handle Streams instead of buffers, as they are the ones that give you the option of doing coordinated streaming with the service implementation.
WCF offers some ways to send binary attachments and stream data in various ways. We have an application at work that does this, but I haven't had a chance to dig through the code, so I can't offer too much help. Here are a few links that might get you started (Nicholas Allen's Indigo Blog is a great place for WCF info):
http://blogs.msdn.com/drnick/archive/2006/03/31/565558.aspx
http://weblogs.asp.net/cibrax/archive/2007/08/29/sending-attachments-with-wcf.aspx