martes, 6 de febrero de 2018

Obtener Contenido Binario Referenciado Usando OSB 12c


Algo que suele causar confusión y muchas veces dolores de cabeza... es el uso tanto de archivos adjuntos (Attachments) como de contenido binario (<binary-content ref="..."/>) en un flujo OSB.

Como gran parte de un servicio OSB es puro XML, no estamos acostumbrados a lidiar con contenido de este tipo (contenido binario), ya que al no ser XML merecen un trato especial. Por ello, en el presente articulo se detallaran algunos conceptos basicos y una pequeña guia que servirá de ejemplo para practicar un caso sencillo.




Entendiendo El Contenido Binario

En el caso de las variables body y attachments, el contenido basado en texto, XML y MFL se coloca directamente dentro de un elemento XML. Para el caso de los datos binarios, que contienen valores de bytes que son ilegales en XML, Oracle Service Bus no coloca el contenido binario en el elemento XML, sino que como el contenido binario no se puede manipular se maneja de manera eficiente.

Cuando se recibe contenido binario en tiempo de ejecución, Oracle Service Bus lo almacena en una tabla hash en memoria y se inserta una referencia a ese contenido en el elemento XML (body o attachments). Esta referencia está representada por el siguiente fragmento XML:

De esta manera cuando se desea acceder, Oracle Service Bus con esa referencia va a memoria y busca los bytes (arreglo de byte) y puede trabajar con ellos.




Manos A La Obra!

Desde el un pipeline en OSB, crear la variable $binaryContent con una actividad "Assign" y asignarle el path: $body/ctx:binary-content




De esta manera se está asignando el elemento <binary-content/> (que es quien tiene la referencia al contenido binario) como contenido de la variable $binaryContent. El mensaje que contiene $body en ese momento es el siguiente:


<Body xmlns="http://schemas.xmlsoap.org/soap/envelope/">
            <binary-content ref="cid:N7047268c:a:1616be45343:N7ffe" xmlns="http://www.bea.com/wli/sb/context"/>
</Body>



Luego, es necesario procesar el contenido binario al que hace referencia el elemento XML... esto se logra con una clase Java muy sencilla que permita obtener el String resultante. Crear la siguiente clase java:


package decoding.tools;

public class Binary {
   
    public static String getBinaryContentAsString(Object param) {
        System.out.println("Class=" + param.getClass().getName());
        System.out.println("Param=" + param);
        byte[] bytes = (byte[])param;

        String content = new String(bytes);
        System.out.println("Content=" + content);
        return content;
    }
   
}



Con la clase Java se toma el XML <binary-content ref="cid:N7047268c:a:1616be45343:N7ffe"/> como un Objeto, luego se toman los bytes de ese Objeto y son transformados en String. Al concluir la clase retorna ese String.



Utilizar una actividad "Java Callout" para invocar al archivo Java (.jar) que contiene la clase anterior, la cual debe recibir como parámetro de entrada la variable $binaryContent antes definida y asignar el resultado (el String que retorna) a una variable $stringContent que debe ser configurada en la misma actividad "Java Callout":






Al deployar el servicio OSB y probarlo... se puede visualizar en el trace de invocación como la variable $stringContent se genera con el contenido que devuelve la clase Java:





Cualquier duda o consulta puede debatirse libremente y con respeto en los comentarios de este articulo.

2 comentarios:

  1. Excelente explicacion, me sirvio mucho, pude detectar el mensaje que venia del otro lado.

    Pregunta sabes porque a veces osb lo recibe de esta manera, ya que prober directamente y me rpd un json , pero osb a veces lo coloca modo binario y otras veces me manda el json, sera por la estructura del mensaje o porque es muy largo

    ResponderEliminar
    Respuestas
    1. Te comparto el documento oficial que utilicé en su momento para entender toda esta situación:
      https://docs.oracle.com/cd/E14571_01/admin.1111/e15867/context.htm#OSBAG312

      Por lo que entiendo, depende mucho de el provider (de quien arma la respuesta). Porque puede configurar la forma en que mandara las cosas, por defecto es un array de bytes pero el runtime de OSB puede interpretar otra cosa segun lo que el provider mande en el response.

      Te sugieron que implementes un par de lineas en el Java para identificar si se trata de un binary content o de JSON, y en base a eso tomar una accion diferente segun el caso.

      Espero haberte ayudado con tu inquietud. Saludos!

      Eliminar