Opaque does not mean: just pass anything in. It has to be base64! JCA Adapters

2

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.

image

 

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)

image

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)

image

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

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director and Oracle Developer Champion. Solution architect and developer on diverse areas including SQL, JavaScript, Kubernetes & Docker, Machine Learning, Java, SOA and microservices, events in various shapes and forms and many other things. Author of the Oracle Press book Oracle SOA Suite 12c Handbook. Frequent presenter on user groups and community events and conferences such as JavaOne, Oracle Code, CodeOne, NLJUG JFall and Oracle OpenWorld.

2 Comments

  1. Joost Lambregts on

    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.

  2. Pierluigi Vernetto on

    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…