I only realized just now that the checkbox Native format translation is not required (Schema is Opaque) in many of the JCA adapter (wizard)s that we use with SOA Suite and Service Bus does not mean that the opaqueElement can be fed with just any content whatsoever and it will pass it onwards.
I tried to do just that, and ran into various errors, such as
Caused By: ORABPEL-11101
Translation Failure.
Translation to native failed. IO Failure in translator.
IO failure because the translator failed to to copy InputStream to OutputStream. .
Check the error stack and fix the cause of the error. Contact oracle support if error is not fixable.
.
The data does not conform to the NXSD schema. Please correct the problem.
at oracle.tip.pc.services.translation.xlators.opaque.OpaqueTranslator.translateToNative(OpaqueTranslator.java:35
0)
at oracle.tip.adapter.jms.outbound.JmsProducer.translateToNative(JmsProducer.java:106)
at oracle.tip.adapter.jms.outbound.JmsProducer.constructOutboundAdapterMessage(JmsProducer.java:201)
at oracle.tip.adapter.jms.outbound.JmsProducer.execute(JmsProducer.java:339)
and in the stacktrace:
Caused By: com.sun.mail.util.DecodingException: BASE64Decoder: Error in encoded stream: needed 4 valid base64 characters
but only got 3 before EOF, the 10 most recent characters were: “5T12:00:12”
at com.sun.mail.util.BASE64DecoderStream.decode(BASE64DecoderStream.java:256)
at com.sun.mail.util.BASE64DecoderStream.read(BASE64DecoderStream.java:144)
As it turns out, whatever is fed to the opaque element in the opaque ‘schema’ should in fact be base64 encoded data! Not just any string or XML block – as I originally thought.
And as it also happens: it is not so simple taking any piece of text of XML and turning it into base64. There is no standard XPath function available to perform this encoding. (I have to research whether perhaps the native format translation in SOA Suite 12c can be used for this). There are several resources on the internet by friends and peers that explain how a BPEL Java Embedded activity can be created to do the job, or a Java Call out in Service Bus or even a custom XPath function:
Edwin Biemond on Java Embedded activity in BPEL for Base64 encoding http://biemond.blogspot.nl/2011/09/base64-encoding-in-oracle-bpel-11g.html
Maarten Smeets on a Custom XPath functions to do the Base64 encoding from within any component that can uses XPath: http://javaoraclesoa.blogspot.nl/2012/03/base64encode-and-base64decode-in-bpel.html
The SOA Guy on a Java Call out from Service Bus – http://thesoaguy.com/?p=63
A very good introduction into Base64 is provided by Ramkumar Menon’s Blog: https://blogs.oracle.com/rammenon/entry/base64_explained
If the content you want to send is XML there is a relatively easy way to do this. First, make sure that your jca adapter takes a single string as input. You can do this by making an NXSD with a single element of type string, looking something like this:
xsd:element name=”Content” type=”xsd:string” nxsd:style=”terminated” nxsd:terminatedBy=”${eof}”/
Next, you need to convert the xml you want to send to string. Fortunately, oracle has an xpath funtion for that: ora:getContentAsString(element elementAsNodeList)
This function takes any xml node or node-set as input and converts it to a string. This string can then be used as input for you jca adapter.
I have tested this approach and it works.
The recieving end should be able to use the oraext:parseEscapedXML() custom xpath function to convert the xml string back to actual xml, though I did not test this part.
yes it’s a tragic thing that such a common requirement entails that you have to make a java callout… maybe in SoaSuite 27, base64 encoding will be part of the standard XQuery library…