OSB : "Transport Error" à l'appel d'un Web Service externe

Dernièrement, j’ai rencontré une erreur assez peu explicite :

Unhandled error caught by system-level error handler
com.bea.wli.sb.pipeline.PipelineException: Transport error (error code=BEA-382032):

lors d’un appel de web service tiers. Le Web Service appelé est exposé par un progiciel appartenant au SI de l’entreprise.
Vous trouverez ci-dessous une description de l’erreur, l’explication et la résolution du problème.

Erreur rencontrée

L’erreur constatée dans les logs survient à l’appel du Web Service :

Unhandled error caught by system-level error handler
com.bea.wli.sb.pipeline.PipelineException: Transport error (error code=BEA-382032):
 Le message doit être une instance de :
 {http://schemas.xmlsoap.org/soap/envelope/}Envelope
	at com.bea.wli.sb.pipeline.Node.processMessage(Node.java:79)
	at com.bea.wli.sb.pipeline.PipelineContextImpl.execute
	at com.bea.wli.sb.pipeline.Router.processMessage(Router.java:214)
	at com.bea.wli.sb.pipeline.MessageProcessor.processResponse
	at com.bea.wli.sb.pipeline.RouterCallback.onError(RouterCallback.java:145)
	at com.bea.wli.sb.transports.LoadBalanceFailoverListener.onError
        [...]

J’ai d’abord fait des traces des messages envoyés pour valider leur structure mais je n’ai rien trouvé d’anormal …
J’ai alors augmenté les niveaux de logs suivants :

<java:alsb-pipeline-debug>true</java:alsb-pipeline-debug>
<java:alsb-transports-debug>true</java:alsb-transports-debug>

Cette configuration est accessible dans le fichier alsbdebug.xml se trouvant à l’emplacement suivant : /opt/oracle/Middleware/user_projects/domains/OSB_domain
Une fois les logs augmentés et l’appel ré-exécuté, j’ai obtenu une trace plus complète :

<osb_server1> <[ACTIVE] ExecuteThread: '5' for queue:
'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <>
<BEA-000000> <HttpOutboundMessageContext: Response MetaData:
<xml-fragment xmlns:tran="http://www.bea.com/wli/sb/transports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.bea.com/wli/sb/transports/http">
<tran:headers xsi:type="http:HttpResponseHeaders">
<http:Connection>close</http:Connection>
<http:Content-Length>1313</http:Content-Length>
<http:Content-Type>text/xml; charset=utf-8</http:Content-Type>
<http:Server>GtMonitor version unknown</http:Server>
</tran:headers>
<tran:response-code>1</tran:response-code>
<tran:response-message>Bad Request - POST with no entity</tran:response-message>
<tran:encoding>utf-8</tran:encoding>
<http:http-response-code>400</http:http-response-code>
</xml-fragment>>

Explication & Solution

On remarque dans l’en-tête que le paramètre Connection est positionné à Close, ce qui signifie que le serveur http cible a désactivé le keep-alive.
Autrement dit, à chaque requête cliente, une nouvelle connexion est créée …
Par ailleurs, on a la possibilité depuis l’OSB d’envoyer les messages par morceaux via l’utilisation de l’option : « Use Chunked Streaming Mode ». Il s’agit du comportement par défaut de l’OSB, les messages sont découpés et envoyés par morceaux.
Ce mode d’envoi n’est pas compatible avec la désactivation de l’option keep-alive sur le serveur cible puisqu’il n’autorise plus la persistance des connexions.
La solution est donc de décocher cette case dans l’onglet HTTP Transport du Business Service faisant l’appel :