In WebSphere SOAP XOP attachments references are replaced with the attachment base64 value - web-services

I am facing the following problem:
when sending SAAJ requests with MTOM attachments , the original request body looks like this
<soapenv:Body>
<ns1:UploadMsgRq>
<ns2:Attachment><xop:Include href="cid:testfile.xml" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></ns2:Attachment>
</ns1:UploadMsgRq>
</soapenv:Body>>
The attachment tag value get transformed to
<ns2:Attachment>PHN0YXJ0Pkdhc3Nlcjwvc3RhcnQ+</ns2:Attachment>
which is the base64 value of my attachments, I don't want this to happen, specially that the attachment is already added as MTOM part.
Also the same code is working as desired on JBOSS.
Is there a special handling that I should do n websphere?

Here is the solutions that I've found:
Drop the SAAJ client and generate a client from the WSDL, this will automatically keep the XOP:Include as is.
Keep the SAAJ Client but for the include tag you must do one of the following a) make sure that the include tag has a space in its content <xop:Include href="cid:testfile.xml" xmlns:xop="http://www.w3.org/2004/08/xop/include"> </xop:Include> or b) add it dynamically using addChildElement. For both a and b your handler -if any- shouldn't call context.getMessage() or it will generate the bas64 again.

Related

BizTalk mapping: Getting a value from soapenv:Header

I'm trying to map a message from the following format via xslt:
<soapenv:Envelope xmlns:soapenv="..." ns...>
<soapenv:Header>
<ns:myHeader>
<ns1:myData>VALUE_I_WANT</ns1:myData>
</ns:myHeader>
</soapenv:Header>
<soapenv:Body>
<ns2:otherData>
...
</ns2:otherData>
</soapenv:Body>
</soapenv:Envelope>
Currently my mapping handles all of the fields in the soapenv:Body tag, but for one of my mapped nodes I need the value in soapenv:Header > ns:myHeader > ns1:myData.
Is it possible to get a value from the soap header in XSLT and what kind of xpath would I need to achieve this?
Assuming you use the WCF-BasicHttp adapter, you could use xslt like you wanted, but only if you specified Envelope -- entire <soap:Envelope> as data selection for the SOAP Body element. If you don't specify it, your header will be removed from the message body and xpath statements on the header will be impossible.
Your other option is getting the value from the context property InboundHeaders with namespace http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties. The adapter puts the SOAP header values into that InboundHeaders context property by default. If you need the context value in a mapping, without an orchestration, try looking into the community made Context Accessor Functoid.
Doing your own property promotion on header values, like you asked for in the comments, is also possible, but not in xslt. Only if you add an XML Disassembler Pipeline Component, then make a schema of the entire soap message, then set promotions on the schema and finally; specify the schema in the Document schemas part of the Pipeline Component. I wouldn't suggest using this approach, as it requires you to deploy a soap schema which will be duplicate with the default BizTalk soap schema.

Web service - SOAPui - Receiver Failed to serialize node AXIS2

Hy Guys,
I have a Web service problem. The used environment: SOAP - TOMCAT+AXIS2 - Gigaspace - Magic XPA 3.3
I have made 2 closely same external xpa program what gives back a blob in the Task's property sheet's Return value. It's "answer" back an XML, the simle different is that the first one make (XPA merge) a smaller (18KB) file (from a Filtered DB source), the bigger is write out the whole record aggregation. (1025KB)
When the soap UI receives the first one, everything is fine, i got the result XML on SOAP side. The bigger one shows this error:
With11Endpoint:
<soapenv:Fault>
<faultcode>soapenv:**Server**</faultcode>
<faultstring>**Failed to serialize node**</faultstring>
With12Endpoint:
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>soapenv:**Receiver**</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">**Failed to serialize node**</soapenv:Text>
</soapenv:Reason>
The only different is the size of files i think so. I have read some option to solve it like BasicHttpBinding's MaxReivedMessageSize and MaxBuffer size, but i could not find them to change values.
Does anyone have experience in this solutions?
Best Regards,
Gábor
For the future. The XML what has sent contained wrong values. Not tipical XML invalid character, instead an character. So i you have a SOAP error like that, try to Validate your XML file to search an option to solve your problem. ;)

JMeter - How to extract values from a response which has been decoded from base64 and stored in a variable? All under the same sampler

I am trying to test a webservice's performance, and having a few issues with using and passing variables. There are multiple sequential requests, which depend on some data coming from a previous response. All requests need to be encoded to base64 and placed in a SOAP envelope namespace before sending it to the endpoint. It returns and encoded response which needs to be decoded to see the xml values which need to be used for the next request. What I have done so far is:
1) Beanshell preprocessor added to first sample to encode the payload which is called from a file.
2) Regex to pull the encoded response bit from whole response.
3) Beanshell post processor to decode the response and write to a file (just in case). I have stored the decoded response in a variable 'Output' and I know this works since it writes the response to file correctly.
4) After this, I have added 4 regex extractors and tried various things such as apply to different parts, check different fields, check JMeter variable etc. However, it doesn't seem to work.
This is what my tree is looking like.
JMeter Tree
I am storing the decoded response to 'Output' variable like this and it works since it's writing to file properly:
import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;
String Createresponse= vars.get("Createregex");
vars.put("response",new String(Base64.decodeBase64(Createresponse.getBytes("UTF-8"))));
Output = vars.get("response");
f = new FileOutputStream("filepath/Createresponse.txt");
p = new PrintStream(f);
this.interpreter.setOut(p);
print(Output);
f.close();
And this is how I using Regex after that, I have tried different options:
Regex settings
Unfortunately though, the regex is not picking up these values from 'Output' variable. I basically need them saved so i can use ${docID} in the payload file for next request.
Any help on this is appreciated! Also happy to provide more detail if needed.
EDIT:
I had a follow up question. I am trying to run this with multiple users. I have a field ${searchuser} in my payload xml file called in the pre-processor here.
The CSV Data set above it looks like this:
However, it is not picking up the values from CSV and substituting in the payload file. Any help is appreciated!
You have 2 problems with your Regular Expression Extractor configuration:
Apply to: needs to be response
Field to check: needs to be Body, Body as a Document is being used for binary file formants like PDF or Word.
By the way, you can do Base64 decoding and encoding using __base64Decode() and __base64Encode() functions available via JMeter Plugins. The plugins in their turn can be installed in one click using Plugin Manager

Use WSDL dynamically in Delphi

How can I use dynamic WSDL, it's operations and parameters, which is given in program config file?
For example, we have a config file:
[Section]
WSDL=http://example.com/SomePub/ws/SomeService?wsdl
Username=myuser
Password=mypass
OperationName=MyOperation
ParameterName=MyParameter
I.e. we have to use web-service, which is unknown, but given (by ini-file) only in run-time. So, we cannot use WSDL Import wizard in Delphi.
Can we write in Delphi such a program, which would load these settings from configuration, and then pass data to specified operation in specified parameter on web-service, which specified by given WSDL?
Using SOAPUI, import the service and perform a sample call. Copy the raw request and the raw response into notepad. Modify the real data with 'tags' and include each raw template as a value in your INI. When you need to make the call, open your INI, grab the raw response template and replace tags with real values. Manually send the SOAP request and parse the response in the same way using the raw template.
The Delphi WSDL importer and the Free Pascal Web Service Toolkit do not provide a way to build a SOAP request dynamically based on a WSDL.
The Web Service Toolkit (and the WSDL importer) are only source code generators, so the code first needs to be compiled - this requires to include a compiler with your application.

In Camel, how to set a header value with result of XSL transform?

I am using camel to implement a proxy over a new backend that looks like an older interface. The older API has username/password credentials in the request body and the new backend service uses basic auth. I have an XSL that will extract the un/pw, do a simple lookup against an XML database (the credentials might not map exactly), and will return the correct credentials as a base64 encoded string. I cannot figure out how to set this as an http Authentication header value (e.g. how to process an XSL transform as an expression in .setHeader() call).
I have SOAP requests that look like this:
<soapenv:Envelope>
<soapenv:Body>
<XService>
<_Header username="demo" password="demo"/>
<_Body>
<_RequestParameters xsi:type="RequestServiceReport">
...
</_RequestParameters>
</_Body>
</XService>
</soapenv:Body>
and my route (using Java DSL) looks sort of like this:
from("jetty:http://161.228.88.168:8080/sap2rjm")
.choice()
.when().simple("${header.channel}")
...
.when().simple("${in.header.emx} == 'authenticate'")
...
.endChoice()
// If the request is for a report, route it to the new service
.when().xpath("//_RequestParameters[#type='RequestServiceReport']")
// TODO: How to get header from the body of the message and set as the header value?
// Stylesheet transform_credentials will extract username/password from body, transform
// for the new service (dev.reportjam) and will base4 encode to produce a string like this one...
.setHeader("Authorization", constant("Basic ZGVtbzpkZW1v"))
.to("xslt:transform_request.xsl")
.to("http://dev.reportjam.com/services/ReportMix?bridgeEndpoint=true")
.to("xslt:transform_response.xsl")
.removeHeaders("*")
.endChoice()
.otherwise()
...
.endChoice()
.end();
I do have another stylesheet that will process the soap request, extract the un/pw, apply some logic to transform it, and then base64 encode it but I do not know how to call this in the setHeader() call above.
Thanks
You can use xpath to grab something from an XML body and then store that as a header.
http://camel.apache.org/xpath
.setHeader("foo", xpath("/foo/bar"))
The trick is to write the xpath expression so it works. As your XML message uses namespaces you need to use them in the xpath expression also. See that link for more details.
Also you should enable stream caching as you will read the message body as part of this xpath expression evaluation.
See the top of this link about stream caching and jetty: http://camel.apache.org/jetty