BizTalk Pipeline IBaseMessage IPropertyContext - biztalk

When a message comes to a BizTalk pipeline , does IBaseMessage instance stands for the incoming message ? and the property , and how to understand this?

The two parts you'll be mainly interested in from the IBaseMessage will be the BodParty.GetOriginalDataStream() and the Context objects. For example
Stream originalDataStream = pInMsg.BodyPart.GetOriginalDataStream();
string msgAsString;
XDocument msgAsXDoc;
StreamReader sr = new StreamReader(originalDataStream)
msgAsString = sr.ReadToEnd();
originalDataStream.Position = 0; // important to reset this before passing the message on!
msgAsXDoc = XDocument.Load(originalDataStream); // now you have it in an XDoc
originalDataStream.Position = 0;
XmlReader xr = XmlReader.Create(originalDataStream)
originalDataStream.Position = 0;
string strProperty = (string)pInMsg.Context.Read("propertyName", "http://PropertyNameSpace");
string anotherProperty = "Testing";
pInMsg.Context.Write("anotherPropertyName", "http://PropertyNamespace", anotherProperty)
pContext.ResourceTracker.Add(xr);
pContext.ResourceTracker.Add(sr);
etc.
A couple other notes:
Avoid 'using' constructs, they will end up disposing of the underlying stream and causing errors
Add any disposable objects to the context's resource tracker, which will make sure to properly call Dispose() on those objects when the underlying stream is ready to be disposed of.

Yes, this is correct.
IBaseMessage is the Message.
A clear explanation on how to create a custom pipeline component can be found here: http://geekswithblogs.net/bosuch/archive/2012/01/24/creating-a-custom-biztalk-2010-pipeline-componentndashpart-i.aspx
This should get you started.

Well, yes and no.
For clarity, IBaseMessage is an Interface that the actual message object's (.Net) Type implements. It works because .Net allows Interfaces to be used as Types.
Properties are contained in the .Context collection.
Also, BizTalk IBaseMessage implementations can have multiple Parts.

Related

faild to build body in activemq

I want use ActiveMQ in .net core,i use Apache.NMS.ActiveMQ for doing this but I have problem.
I see this error in ActiveMQ admin console:
Cannot display ObjectMessage body. Reason: Failed to build body from bytes. Reason: java.io.StreamCorruptedException: invalid stream header: 00010000
thats part of my code for doing this:
private const String QUEUE_DESTINATION = "test-queue";
private IConnection _connection;
private ISession _session;
public MessageQueue()
{
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616?wireFormat.maxInactivityDuration=5000000");
_connection = factory.CreateConnection();
_connection.Start();
_session = _connection.CreateSession();
}
IDestination dest = _session.GetQueue(QUEUE_DESTINATION);
using (IMessageProducer producer = _session.CreateProducer(dest))
{
var objectMessage = producer.CreateObjectMessage(newDoc);
producer.Send(objectMessage);
}
The fact that the admin console can't display the body of an ObjectMessage isn't really an error. It's the expected behavior. Remember, from the broker's perspective the message body is just an array of bytes. It could be text data (encoded many different ways), image data, custom binary data, etc. The broker has no idea how to decode it. It will try to display the body as text, but if it fails it won't try anything else.
To be clear, in order to see the contents of an ObjectMessage the web console would have to have the object's definition in order to deserialize it. There is no mechanism to tell the web console about arbitrary data formats so it can deserialize message bodies reliably (other than simple text). This is one reason, among many, to avoid ObjectMessage.
I recommend you use a simple text format (e.g. JSON, XML) to represent your data and send that in your message rather than using ObjectMessage.

Objects stored by riak-java-client end up as raw json when read by riak-python-client?

I might be confused about something, but when I store a custom object from the Java Riak client and then try to read that object using the Python Riak client, I end up with a raw json string instead of a dict.
However, if I store a the object in python, I am able to output a python dictionary when fetching that object.
I could simply use a json library on the python side to resolve this, but the very fact that I am experiencing this discrepancy makes me think that I am doing something wrong.
On the Java side, this is my object:
class DocObject
{
public String status; // FEEDING | PERSISTED | FAILED | DELETING
public List<String> messages = new ArrayList<String>();
}
class PdfObject extends DocObject
{
public String url;
public String base_url;
}
This is how I am storing that object in Riak:
public void feeding(IDocument doc) throws RiakRetryFailedException {
PdfObject pdfObject = new PdfObject();
pdfObject.url = doc.getElement("url").getValue().toString();
pdfObject.base_url = doc.getElement("base_url").getValue().toString();
pdfObject.status = "FEEDING";
String key = hash(pdfObject.url);
pdfBucket.store(key, pdfObject).execute();
}
And this is what I am doing in Python to fetch the data:
# Connect to Riak.
client = riak.RiakClient()
# Choose the bucket to store data in.
bucket = client.bucket('pdfBucket')
doc = bucket.get('7909aa2f84c9e0fded7d1c7bb2526f54')
doc_data = doc.get_data()
print type(doc_data)
The result of the above python is:
<type 'str'>
I am expecting that to be <type 'dict'>, just like how the example here works:
http://basho.github.com/riak-python-client/tutorial.html#getting-single-values-out
I am perplexed as to why when the object is stored from Java it is stored as a JSON string and not as an object.
I would appreciate if anybody could point out an issue with my approach that might be causing this discrepancy.
Thanks!
It would appear you've found a bug in our Python client with the HTTP protocol/transport.
Both the version you're using and the current one in master are not decoding JSON properly. Myself and another dev looked into this this morning and it appears to stem from an issue with charset parameter being returned from Riak with the content-type as Christian noted in his comment ("application/json; charset=UTF-8")
We've opened an issue on github (https://github.com/basho/riak-python-client/issues/227) and will get this corrected.
In the mean time the only suggestion I have is to decode the returned JSON string yourself, or using the 1.5.2 client (latest stable from pypy) and the Protocol Buffers transport:
client = riak.RiakClient(port=8087, transport_class=riak.RiakPbcTransport)
it will return the decoded JSON as a dict as you're expecting.

What is the point of JObject's CreateWriter if using the writer just throws ArgumentException?

I have a "legacy" method that takes a JsonWriter and dumps a bunch of json.. Out of this, I want a JObject instance, so I tried the following:
JObject myObj = new JObject();
using (var writer = myObj.CreateWriter())
{
TheLegacyMethod(writer);
}
// TODO: Do stuff with the nicely initialized JObject instance
The issue is that the first time "TheLegacyMethod" attempts to actually use the writer to do a:
writer.WriteStartObject();
I get an ArgumentException complaining that a JObject can't be added to a JObject.
I've used a smelly workaround, writing the Json to a StringBuilder first, then doing a JObject.Parse() on the result... but I would like to avoid this intermediate.
What is the point of JObject.CreateWriter() if you can't use it? Am I missing something? (I'm hoping I am).
Thanks,
Tyler
When writing values to an object the property name must be written before the value.

Windows Azure access POST data

Ok, so I can't seem to find decent Windows Azure examples. I have a simple hello world application that's based on this tutorial. I want to have custom output instead of JSON or XML. So I created my interface like:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(UriTemplate = "session/create", Method = "POST")]
string createSession();
}
public class MyService : IService
{
public string createSession()
{
// get access to POST data here: user, pass
string sessionid = Session.Create(user, pass);
return "sessionid=" + sessionid;
}
}
For the life of me, I can't seem to figure out how to access the POST data. Please help. Thanks!
If you have an HttpContext there may be a Request object that would have the form data. I'm basing part of this off the ASP.Net tag on this question, so if that is incorrect then there may be the need to handle this another way but it looks a lot like a web service to my mind.
EDIT: HttpRequest is the class that has the Form property that should be where the POST data is stored if this is an HTTP request. This is part of System.Web so it should be ready to be used pretty easily, as I recall.
Sample code showing the Request.Form property:
int loop1;
NameValueCollection coll;
//Load Form variables into NameValueCollection variable.
coll=Request.Form;
// Get names of all forms into a string array.
String[] arr1 = coll.AllKeys;
for (loop1 = 0; loop1 < arr1.Length; loop1++)
{
Response.Write("Form: " + arr1[loop1] + "<br>");
}
This presumed there was an HttpRequest instance around.
WCF Simplified Part 4: Comparing the Request/Reply and One-Way Patterns passes in a parameter so that your "createSession" method would have to take in those strings it would appear. I'm used to the ASP.Net world where there are some built-in objects like Request, Response, Server, Application and Session.
Yes, if you did try changing the method signature as there are ways to pass in parameters in that last example I linked though I don't know if that would work in your case or not.

TypeError: Error #1034: Type Coercion failed: cannot convert Object#1456c7b9 to mx.messaging.messages.IMessage

Im trying to connect a Flash client to BlazeDS. There has been some success with this from others using the vanilla BlazeDS setup. However I'm using the new Spring BlazeDS Integration from springsource and running aground.
The flash client actually seems to be working in that I can see the correct data in the body of the returned object, but for some reason unknown it fails casting as an IMessage. It fails in PollingChannel.as on this line with the subject line error
var messageList:Array = msg.body as Array;
for each (var message:IMessage in messageList) <--
On application load I register a whole bunch of classes like so
registerClassAlias( "flex.messaging.messages.RemotingMessage", RemotingMessage );
registerClassAlias("mx.messaging.messages.IMessage", IMessage);
etc..
my code is basically
var channelSet:mx.messaging.ChannelSet = new mx.messaging.ChannelSet();
var channel:mx.messaging.channels.AMFChannel = new AMFChannel("my-amf", "http://localhost:8400/SpringA/messagebroker/amf");
channelSet.addChannel(channel);
var consumer:mx.messaging.Consumer = new Consumer();
consumer.channelSet = channelSet;
consumer.destination = "simple-feed";
consumer.subscribe();
consumer.addEventListener(MessageEvent.MESSAGE, test);
private function test(event:IMessage)
{
trace("msg..");
// breakpoint never makes it here
}
I have a flex client which works 100% with same destination/channel.
The error in the title means that you, for some reason, got an object that is not implementing or extending the IMessage interface, therefore the loop can not cast it in this part:
for each (var message:IMessage in messageList){
Either you should somehow make sure that you don't add anything that is not extending or implementing IMessage, or check if the variable IS actually ext./imp. it. Also - if you want to do that, you will have to change the for each like this:
for each (var obj in messageList){
if (obj is IMessage){
var message:IMessage = obj as IMessage;
// DO STUFF HERE
}
}
Add this Object mapping:
registerClassAlias("flex.messaging.io.ObjectProxy", ObjectProxy);
If on your Java VO objects you have overridden the hashcode() method, this situation could happen.
Remove the hashcode() override (if you are able to).
See my blog for the backstory on how I discovered this. http://squaredi.blogspot.com/2013/12/remoting-landmine-without-stack-trace.html
I had the same error when trying to send an actionscript object to the backend. My problem was that my c# equivalent object was missing an public parameterless constructor.

Resources