barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
Показаны сообщения с ярлыком MTOM. Показать все сообщения
Показаны сообщения с ярлыком MTOM. Показать все сообщения

пятница, 25 декабря 2015 г.

WSO2 ESB 4.9.0: пропадает контент бинарного узла при его создании с помощью ByteArrayInputStream + org.apache.axis2.builder.unknowncontent.InputStreamDataSource

Проблема

Некий кастомный Java-медиатор создает бинарный XML-узел, наполняя его из массива байт byte[], используя ByteArrayInputStream и org.apache.axis2.builder.unknowncontent.InputStreamDataSource:
ByteArrayInputStream stream = new ByteArrayInputStream(myBytes);
DataSource ds = new InputStreamDataSource(stream);
DataHandler dataHandler = new DataHandler(ds);
OMText binaryNode = factory.createOMText(dataHandler, true);
При этом созданный узел ведет себя крайне странно: если попробовать 2 раза подряд залогировать созданный XML, в первый раз он логируется корректно (бинарный узел логируется base64-кодированным), а при повторном логировании оказывается, что бинарный узел уже пуст.

Решение

Особо не разбирался, реализовал создание DataSource напрямую из массива байт:
DataSource ds = new org.apache.axiom.attachments.ByteArrayDataSource(myBytes);

четверг, 19 марта 2015 г.

WSO2 ESB: MTOM-оптимизация и JMS

Задача

Складывать MTOM-оптимизированные SOAP-сообщения в JMS и читать их оттуда.

Решение

Во-первых, перед тем, как класть сообщение в JMS, включаем для него MTOM-оптимизацию (если она выключена глобально на сервере):
<property action="set" name="enableMTOM" scope="axis2"
                type="STRING" value="true"/>
Далее указываем axis2 на необходимость положить сообщение как бинарное, а не текстовое:
<property action="set" name="JMS_MESSAGE_TYPE" scope="axis2"
                type="STRING" value="JMS_BYTE_MESSAGE"/>
Указываем, что тип сообщения будет multipart/mixed:
<property action="set" name="messageType" scope="axis2"
                type="STRING" value="multipart/mixed"/>
Говорим, что content-type нужно положить в JMS-свойство ContentType (сохранение content-type требуется, т.к. в случае с multipart он будет содержать разделитель частей, необходимый для корректного чтения этого multipart'а):
<property action="set" name="transport.jms.ContentTypeProperty" scope="axis2"
                type="STRING" value="ContentType"/> 
Далее, в принимающей проксе прописываем, что content-type сообщения нужно брать из JMS-свойства ContentType:
    <parameter name="transport.jms.ContentType">
        <rules xmlns="http://ws.apache.org/ns/synapse">
                <jmsProperty>ContentType</jmsProperty>
        </rules>
    </parameter> 
В сценарии JMS -> JMS, когда MTOM-оптимизированное сообщение извлекается из JMS, обрабатывается, и снова кладется в JMS (опять оптимизированным), нужно перед помещением сообщения в исходящую очередь чистить этот самый транспортный заголовок ContentType:
            <property action="remove" name="ContentType" scope="transport"
                type="STRING"/> 
В противном случае WSO2 оставляет в исходящем сообщении тоже значение этого JMS-свойства, что и во входящем сообщении, при этом бинарное тело уже перекодировано с использованием другого MIME-разделителя, что приводит к ошибкам при последующем чтении MIME-а из JMS:
ERROR - JMSMessageReceiver Unknown error processing message
org.apache.axiom.om.OMException: Mime parts not found. Stream ended while searching for the boundary        at org.apache.axiom.attachments.Attachments.<init>(Attachments.java:238)
        at org.apache.axis2.builder.BuilderUtil.createAttachments(BuilderUtil.java:594)
        at org.apache.axis2.builder.BuilderUtil.createAttachmentsMap(BuilderUtil.java:545)
        ...

четверг, 18 июля 2013 г.

validate-медиатор на WSO2ESB 4.5.1 и MTOM: NullPointerException

Проблема:

При валидации сообщения с помощью медиатора <validate>  в случае, когда сообщение содержит MTOM-оптимизированное вложение, валится исключение:
java.lang.NullPointerException
at org.apache.axiom.om.impl.llom.OMTextImpl.getTextCharacters(OMTextImpl.java:272)
at org.apache.axiom.om.impl.serialize.OMXMLReader.generateEvents(OMXMLReader.java:284)
at org.apache.axiom.om.impl.serialize.OMXMLReader.generateEvents(OMXMLReader.java:254)
at org.apache.axiom.om.impl.serialize.OMXMLReader.generateEvents(OMXMLReader.java:251)
at org.apache.axiom.om.impl.serialize.OMXMLReader.parse(OMXMLReader.java:171)
at org.apache.axiom.om.impl.serialize.OMXMLReader.parse(OMXMLReader.java:161)
at org.apache.xerces.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Unknown Source)
at org.apache.synapse.mediators.builtin.ValidateMediator.mediate(ValidateMediator.java:180)
at ...
at java.lang.Thread.run(Thread.java:722)
Причина:

Это известная проблема библиотеки Axiom, есть соотв. баг на баг-трекере (https://issues.apache.org/jira/browse/AXIOM-442), который исправлен в версии 1.2.14, тогда как в WSO2 ESB 4.5.1 используется версия 1.2.11.

пятница, 18 января 2013 г.

WSO2 ESB: исключение "com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog" при получении ответа конечного сервиса

Проблема:

Ситуация такая: некоторое сообщение шлется из прокси-сервиса А на одном экземпляре WSO2 ESB на прокси-сервис Б, развернутый на другом экземпляре WSO2. При обработке ответа  от сервиса Б сервис А валится с ошибкой:
com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-' (code 45) in prolog
при этом в логах сервиса Б сообщение никаких "-" в прологе не содержит, и выглядит очень даже корректно.

Причина:

На самом деле сервис Б выдает multipart-ответ вида:
HTTP/1.1 200 OK
Content-Type: multipart/related; boundary="MIMEBoundary_68536b3ce7bdd007e0bcc56b638c8e0f9b2cd5c381cba6e9"; type="application/xop+xml"; start="<0.78536b3ce7bdd007e0bcc56b638c8e0f9b2cd5c381cba6e9@apache.org>"; start-info="text/xml"
Accept-Encoding: gzip,deflate
Host: 10.24.12.132:8280
Date: Fri, 18 Jan 2013 15:40:19 GMT
Server: Synapse-HttpComponents-NIO
Transfer-Encoding: chunked
Connection: Keep-Alive

--MIMEBoundary_68536b3ce7bdd007e0bcc56b638c8e0f9b2cd5c381cba6e9
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.78536b3ce7bdd007e0bcc56b638c8e0f9b2cd5c381cba6e9@apache.org>

<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><!--...--></soapenv:Body></soapenv:Envelope>
--MIMEBoundary_68536b3ce7bdd007e0bcc56b638c8e0f9b2cd5c381cba6e9--
Причина такого ответа в том, что на втором сервере включена MTOM-оптимизация. А вот на первом она выключена, поэтому он оптимизированных ответов не понимает.

Решение:

Т.к. для данного конкретного сервиса (особенно для его ответов), оптимизация была не нужна, я её выключил установкой свойства:
<property name="enableMTOM" value="false" scope="axis2"/>
в цепочке медиации сервиса Б перед отправкой ответа (в out / faultSequence).
Можно также отключить MTOM параметром сервиса:
<parameter name="enableMTOM">false</parameter>