IIB SOAP Service CDATA element to MQ - cdata

In IIB I've exposed a SOAP web service that accepts a CDATA element. I need to write that CDATA element to MQ. It's a simple IIB transformation:
SET OutputRoot.BLOB = InputRoot.SOAP.Body.ns:HL7ReqType.ReqBody;
And it does put the unwrapped CDATA information into a BLOB. But the MQOutput Node doesn't see it, and writes a zero length record to the queue.
How do I get that BLOB data written to the queue? Trace looks like this:
( ['SOAPRoot' : 0x1fa37b60]
(0x01000000:Name ):Properties = ( ['MQPROPERTYPARSER' : 0x1fa38280]
... etc ...
)
(0x03000000:NameValue):BLOB = 'MSH|^~||||XX|||ORM^A^M|
PID|1|123^| etc...' (CHARACTER)
)

I had to say
SET OutputRoot.BLOB.BLOB = CAST(... AS BLOB)
And then optionally I needed to add CCSID 1209 after the AS BLOB. CCSID 1209 means UTF-8. Otherwise the CAST doesn't know how the string is coded and attempts to treat it as a string of hex values.

Related

how to pass an attribute over ActiveMQ in Mule 4

We are migrating from Mule 3 to Mule 4 and in one of our functionalities we need to publish messages to a topic and downstream another mule component is consuming from the queue which is bridged to the topic.
Nothing special here .
To ensure we are able to trace the flow via logs we were sending a 'TrackingId' attribute while publishing messages to the topic ( Mule 3 )
message.setOutboundProperty("XYZ_TrackingID", flowVars['idFromUI']);
return payload;
However when I try the same in Mule 4 we get the following exception :
ERROR 2020-12-20 10:09:12,214 [[MuleRuntime].cpuIntensive.14: [mycomponent].my_Flow.CPU_INTENSIVE
#66024695] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
Message : groovy.lang.MissingMethodException: No signature of method:
org.mule.runtime.api.el.BindingContextUtils$MessageWrapper.setOutboundProperty() is applicable for
argument types: (java.lang.String, org.mule.weave.v2.el.ByteArrayBasedCursorStream) values:
[XYZ_TrackingID, "1234567"].\nError type : (set debug level logging or '-
Dmule.verbose.exceptions=true' for
everything)\n********************************************************************************
Checked internet and it seems in Mule4 setting outbound properties is removed as per here
So how do I achieve the same in Mule 4 ?
Don't even try to do that for several reasons. For one message structure is different, so output properties doesn't exist anymore and that method doesn't even exists. On the other hand, in Mule 4 components like the Groovy component can only return a value and cannot change the event. They can not decide to what that value is going to be assigned. You can set the target in the configuration (payload or a variable) and not change the attributes. Note that variables in Mule 4 are referenced by var., not by flowVars. like in Mule 3 (ie vars.idFromUI).
There is a simpler way to set message properties in the Mule 4 JMS connector. Use the properties element and pass it an object with the properties.
For example it could be something like this:
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
XYZ_TrackingID: vars.idFromUI
}]</jms:properties>
</jms:message>
</jms:publish>
It is in the documentation: https://docs.mulesoft.com/jms-connector/1.0/jms-publish#setting-user-properties. I adapted my example from there.
I am not sure if Correlation Id serves the purpose of a tracking ID for your scenario. But you can pass a CID as below. It's there in the mule documentation.
https://docs.mulesoft.com/jms-connector/1.7/jms-publish
<jms:publish config-ref="JMS_config" sendCorrelationId="ALWAYS" destination="#[attributes.headers.replyTo.destination]">
<jms:message correlationId="#[attributes.headers.correlationId]"/>
</jms:publish>
If your priority is to customise the Tracking ID you want to publish, then try passing below format. The key names may differ as per your use case.
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
AUTH_TYPE: 'jwt',
AUTH_TOKEN: attributes.queryParams.token
}]</jms:properties>
</jms:message>
</jms:publish>
In the above the expression attributes.queryParams.token is basically trying to access a token query parameters which is passed to JMS as a property AUTH_TOKEN key-name , consumed by the API through a HTTP Listener or Requestor earlier.
However, attributes.headers.correlationId is a header. Both queryParams and headers are part of attributes in Mule 4.

Parsing XML Response In GateWayScript

Hi i am new to API connect ... i have a use case where i have to merge responses coming from two endpoints in XML format based on certain conditions.
My flow in the assemble section is like this
1) INVOKE
(i make my
first service call
and capture the response
in a custom 'Response
object varibale' -XMLResponse1
2) INVOKE
(i make my
second service call
and here i am not using any
custom 'Response object varibale'
Instead i am using apim.getvaribale('message.body') to get the response
3)GATEWAYSCRIPT
Here i want to write my script for parsing the xml and merging the two responses
and send back the merged response to the consumer
I observed that the xml response is not getting captured in a custom Response object variable when i try to capture it like below
var test1= apim.getvariable('XMLResponse1');
test1.item(0).childNodes
it throws me an exception like this
test1.item is not a function
now for the second response like below where i am not capturing the response in a custom Response object variable it works well
var test2= apim.getvariable('message.body');
My question:
1)How do i capture the xml responses in a custom Response object variable?
2)How can i parse the response into a javascript object? are there any libraries supported in api connect?
Below is the samples found from IBM community. Hope this may help you.
**** Sample XML ****
<Routing>
<partner name="Partner A" key="1">
<from_ID>PartnerA-KEY1-INT</from_ID>
<to_ID>PartnerA-KEY1-EXT</to_ID>
<destination>PartnerA-KEY1-DESTINATION</destination>
</partner>
<partner name="Partner B" key="2">
<from_ID>PartnerB-KEY2-INT</from_ID>
<to_ID>PartnerB-KEY2-EXT</to_ID>
<destination>PartnerB-KEY2-DESTINATION</destination>
</partner>
<partner name="Partner C" key="3">
<from_ID>PartnerC-KEY3-INT</from_ID>
<to_ID>PartnerC-KEY3-EXT</to_ID>
<destination>PartnerC-KEY3-DESTINATION</destination>
</partner>
</Routing>
**** Corresponing Gateway Script *****
var response = apim.getvariable('XMLResponse1.body');
var objType = response.item(0);
var string = objType.getElementsByTagName("partner").item(0).getElementsByTagName("from_ID").item(0).textContent;
output ---> string = PartnerA-KEY1-INT
Why do you want to merge them in a GatewayScript node??
You could merge them in a mapping node, in wich you have 2 variables as input (refered to the output objects of your invokes) and one XML object as output...
If you have to apply some conditions or comparisons, you could do them in the code part of the mapping nodes

mule multi language data transfer support via http

I wanna help in achieving below mule use-case.Mule flow contains http-inbound-endpoint and object-string transformer(optional) and logger which prints the payload.
Requirement is that i am invoking flow with rest client with a json string
{
"name":"ساختبار",
"age":"25"
}
in the json string name can of different language for example Arabic language string.
I tried with same implementation with sample json string with name defined in Arabic input string from rest client.But while checking the logger output prints
{
"name":"???????",
"age":"25"
}
instead of actual input.
How i can get the actual Arabic or any language input string printed in logger.
As per forum, set the correct Eclipse console encoding following these instructions and set the appropiate encoding on your endpoints.

after receiving soap response modify xml and send to anther service using http adapter

while using http adapter I need to call first service that return XML,
after receiving the response I want to change values and send back to anther service,
how can I do it ?
do http adapter has json to xml function ?
WL adapter will automatically convert XML to JSON for you, however it doesn't have any manual JSON<->XML conversion APIs.
In your case possible solution might be to retrieve XML as plaintext by supplying returnedContentType:"plain" in invocation options. Alter whatever you need using regex/string replace. Use resulting string in 2nd procedure invocation as post body.
Alternatively, you can use 3rd party library to parse/convert/do whatever you need with XML, e.g. http://www.json.org/java/ (more info about how to use it in your adapter - http://public.dhe.ibm.com/software/mobile-solutions/worklight/docs/v506/04_08_Using_Java_in_adapters.pdf)
After checking number of solutions, I state the the http result will be a plain text,
then made a call to java function sending the xml as String, and used
javax.xml to hold and alter the XML.
XPath to retrieve the correct node using org.w3c.dom.*
Hope this will help you too.

Bad request with base64 encoded parameter in WCF rest url on IIS 7

I have a rest wcf 4.0 service that takes in a base64 encoded string as a parameter. It works properly when I run the service in Visual Studio using casini, but gives an Error 400 message when I run the same service under IIS 7.5. The break point doesn't get hit. I guess its not a problem with the code because it works under casini with the same code and web.config.
What changes do I need to make to enable the service to function under IIS 7.5?
This is the URL
http://localhost/MyServices/MyServ.svc/Accept/eyJXb3JkY291bnQiOjMwLCJJbWFnZWNvdW50IjoxMCwiU2VsZWN0ZWRMYW5ndWFnZXMiOlt7ImlkIjoxLCJsYW5ndWFnZTEiOiJIaW5kaSIsIkdyb3VwX0xhbmd1YWdlc19pZCI6bnVsbH0seyJpZCI6MSwibGFuZ3VhZ2UxIjoiTWFyYXRoIiwiR3JvdXBfTGFuZ3VhZ2VzX2lkIjpudWxsfSx7ImlkIjoxLCJsYW5ndWFnZTEiOiJGcmVuY2giLCJHcm91cF9MYW5ndWFnZXNfaWQiOm51bGx9LHsiaWQiOjEsImxhbmd1YWdlMSI6IkdFcm1hbiIsIkdyb3VwX0xhbmd1YWdlc19pZCI6bnVsbH0seyJpZCI6MSwibGFuZ3VhZ2UxIjoiSXRhbGlhbiIsIkdyb3VwX0xhbmd1YWdlc19pZCI6bnVsbH0seyJpZCI6MSwibGFuZ3VhZ2UxIjoic3BhbmlzaCIsIkdyb3VwX0xhbmd1YWdlc19pZCI6bnVsbH1dfQ==
Thanks.
The equal sign has a special meaning in the URL. It separates a parameter key from its value. The way you use the trailing equal signs, IIS will reject it.
Note that the Base 64 encoding uses additional characters that have a special meaning in a URL and cause problems (namely + and /). Therefore I recommend to use a modified Base 64 encoding that uses only URL safe characters.
Typically, the following characters are replaced:
+ with -,
/ with _, and
= with *.
Update:
The Javascript code you use for Base 64 encoding is easy to modify. Just replace this line:
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
with
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_*";
And
return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
with:
return (r ? enc.slice(0, r - 3) : enc) + '***'.slice(r || 3);
Update 2:
I'm afraid the Base 64 URLs are never going to work with IIS. IIS still treats every part of an URL as a file or directory name. There are many problems with this implementation (just try COM2 or PRN as a URL segment).
You'll need to come up with a different URL scheme or request type. Either use a POST request to transmit the Base64 encoded part or use a URL like:
http://server/MyServices/MyServ.svc/Accept?data=eyJXb3JkY291bnQiOjMwLCJ...VsbH1dfQ**
But the second case will only work if the URL isn't too long. It wouldn't expect URLs of more than 1000 characters to work.