barbitoff programmer`s blog

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

среда, 25 декабря 2013 г.

WSO2 ESB 4.5.1: Callout-mediator и ConnectionPoolTimeoutException

Проблема

В прокси-сервисе используется callout-медиатор для вызова некоторого веб-сервиса. Вызов приводит к ошибке (ошибка может быть любым AxisFault'ом, например, таймаутом, но в моем случае это была HTTP-ошибка 404). Проблема заключается в том, что после 2-3 вызов корректная ошибка сменяется на "org.apache.commons.httpclient.ConnectionPoolTimeoutException: Timeout waiting for connection", которая продолжает валиться даже после того, как вызываемый сервис починен и начал корректно отвечать. Через некоторое время проблема сама собой уходит, и конечный сервис начинает вызываться (если же его не починили - снова начинает падать с 404-ой ошибкой).

Причина

При возникновении AxisFault'а callout-медиатор не возвращает http-соединение в Connection-пул, в итоге пул кончается, и попытки достать из него соединение заканчиваются ошибкой (таймаутом ожидания соединения из пула). Через некоторое время такие невозвращенные коннекты сами закрываются по таймауту, и пул снова начинает выдавать коннекты.
Был заведен соответствующий баг (https://wso2.org/jira/browse/ESBJAVA-922), вроде бы исправленный в 4.5.0 M4, тем не менее, он снова воспроизводится на 4.5.1, может смерджить забыли =)

Решение

Берем сорцы synapse 2.1.0 (http://svn.apache.org/viewvc/synapse/tags/2.1.0/), там открываем проект synapse-core (modules/core), идем в класс org.apache.synapse.mediators.builtin.CalloutMediator, на строку 114, и приводим catch-блок к виду:
            } catch (AxisFault axisFault) {
                sc.cleanupTransport();
                handleFault(synCtx, axisFault);
            }
Собираем проект, берем скомпилированный класс CalloutMediator.class, подкладываем его в %WSO2_HOME%/repository/components/plugins/synapse-core_2.1.0.wso2v8.jar/org/apache/synapse/mediators/builtin/ (на остановленной шине), стартуем шину, радуемся.

понедельник, 23 декабря 2013 г.

Java: работа с беззнаковым байтом

Задача

На входе имеем байт (типа byte), хранящий некоторое беззнаковое целое. Нужно привести его к типу int.

Решение

Как известно, в Java нет unsinged-типов, т.е. сам по себе byte трактуется как знаковое целое. Нам же нужно, чтобы байт был истрактован как беззнаковое целое, т.е. чтобы его старший разряд имел вес 128 вместо -128 (для представления отрицательных чисел в Java используется дополнительный код). Чтобы преобразовать беззнаковый байт в int, нужно сделать следующее:
int num = (int) bite & 0xFF
Побитовый "&" нужен вот зачем: при обычном касте  байта к int произойдет расширение знакового разряда, т.е., например, если на входе был байт 1000 0000 (двоичное представление беззнакового числа "128"), после приведения к 4-ехбайтовому int получим:
1111 1111  1111 1111  1111 1111  1000 0000 
, что является двоичным представлением знакового целого "-128", тогда как нам нужно:
0000 0000  0000 0000  0000 0000  1000 0000
, т.е. знавое целое "128".
Это самое "расширение" знакового разряда и исправляется побитовым "И" с числом 0xFF:
1111 1111  1111 1111  1111 1111  1000 0000
&
0000 0000  0000 0000  0000 0000  1111 1111
=
0000 0000  0000 0000  0000 0000  1000 0000

вторник, 17 декабря 2013 г.

WSO2 ESB JMS-прокси: использование transport.jms.ContentType для POX и SOAP-сообщений в очереди

Вопрос

Пусть есть некий JMS-to-XXX прокси-сервис (в роли XXX может быть HTTP или что-то более экзотическое). Вопрос: какое значение нужно устанавливать в параметре transport.jms.ContentType сервиса в зависимости от того, что лежит в JMS: готовое SOAP-сообщение или только полезная нагрузка (т.е. POX):
    <parameter name="transport.jms.ContentType">
        <rules xmlns="http://ws.apache.org/ns/synapse">
            <jmsProperty>contentType</jmsProperty>
            <default>???</default>
        </rules>
    </parameter>
Ответ
  • Для SOAP 1.1: text/xml
  • Для SOAP 1.2: application/soap+xml
  • Для POX: application/xml
(насчет SOAP 1.2 точно не уверен - сам не тестировал)

ЗЫ Описанное выше справедливо и для VFS-to-XXX прокси-сервиса.

суббота, 14 декабря 2013 г.

WSO2 ESB: редеплой сервиса, использующего VFS TransportReceiver

Проблема

Сделал редеплой прокси-сервиса (нажатием на соотв. кнопку в веб-консоли или просто изменив xml-ку конфигурации прокси и сохранив изменения, не суть), использующегося VFS в качестве входящего транспорта. После этого в логах стали наблюдаться ошибки вида:
2013-10-16 21:10:01,598 [-] [evfs-Worker-18] DEBUG VFSTransportListener Error receiving message
org.apache.axis2.AxisFault: The <Proxy_service_name> service, which is not valid, does not belong to the <Proxy_service_name> service group.
at org.apache.axis2.context.ServiceGroupContext.getServiceContext(ServiceGroupContext.java:143)
...
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:168)
at org.apache.axis2.transport.base.AbstractTransportListener.handleIncomingMessage(AbstractTransportListener.java:328)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:498)
...
2013-10-16 21:10:01,613 [-] [evfs-Worker-18] ERROR VFSTransportListener Error processing File URI : file:////10.xxx.yyy.zzz/some/path/file12345.pdf
org.apache.axis2.AxisFault: Transport out has not been set
at org.apache.axis2.engine.AxisEngine.sendFault(AxisEngine.java:522)
at org.apache.axis2.transport.base.AbstractTransportListener.handleIncomingMessage(AbstractTransportListener.java:336)
at org.apache.synapse.transport.vfs.VFSTransportListenerExtendable.processFile(VFSTransportListener.java:498)
at ...
Причина

Причина здесь вероятнее всего в том, что в момент редеплоя прокси-сервиса его входящий транспорт находился в процессе обработки файлов, находящихся в его входящей директории, и после передеплоя сервиса не произошло прозрачного для транспорта переключения со старой версии прокси-сервиса на новую версию. Такая ситуация чревата чем, что все файлы, которые транспорт обработал после редеплоя прокси-сервиса будут обработаны как ошибочные (будут удалены / перемещены в соотв. директорию в зависимости от настроек прокси-сервиса).

Выводы

Чтобы безболезненно редеплоить прокси-сервис, использующий VFS-транспорт в качестве входящего, нужно либо чтобы во входящей директории не было файлов для обработки, либо, по крайней мере, чтобы транспорт находился в состоянии ожидания следующего момента просмотра входящей папки, а не в цикле ее просмотра.

четверг, 5 декабря 2013 г.

Симуляция Connection Timout

Иногда для тестирования необходимо симулировать таймаут соединения. Наиболее просто способ это сделать - попытаться подключиться на любой порт немаршрутизируемого ip-адреса, например, 10.255.255.1. Другой вариант - на какой-нибудь заведомо непрослушиваемый порт публичного хоста, на котором пакеты просто дропаются, например, ya.ru:8280.
ЗЫ Немного оффтопа: ошибка WSO2 ESB "Connection timeout For : xxx.xxx.xxx.xxx:yyyy" говорит не о таймауте соединения, а о таймауте чтения ("Read timeout"). Таймаут соединения в терминах WSO2 ESB звучит как "Timeout connecting to : /xxx.xxx.xxx.xxx:yyyy".

среда, 4 декабря 2013 г.

WSO2 ESB: развертывание Message Store из CAR-ника

Проблема

WSO2 ESB 4.5.1. Пытаюсь развернуть CAR-ник, собранный WSO2 Developer Studio 3.2.0 и содержащий Message Store. Хранилище не деплоится.

Причина

Соответствующий артефакт распаковывается в папку
%WSO2_HOME%\repository\deployment\server\synapse-configs\default\message-store
вместо
 %WSO2_HOME%\repository\deployment\server\synapse-configs\default\message-stores
Причина - баг в Carbon'е (https://wso2.org/jira/browse/CARBON-14063), исправлен в версии 4.1.0, а, значит, исправление попало только в WSO2 ESB 4.7.0+.

Решение

Либо деплоить Message Store руками, либо пересобирать SynapseAppDeployerConstants.

Windows: установка атрибута "Accessed" ("Открыт") у файлов / папок

Лично у меня в винде по-умолчанию время последнего доступа к файлу/папке не обновляется, т.к. соответствующая настройка выключена. Проверяется это выполнением из-под администратора команды:
fsutil behavior query disablelastaccess
Если команда выводит: 
DisableLastAccess = 1
значит, обновление данного атрибута действительно выключено. 
Если его нужно включить (например, данный флаг используется каким-либо ПО), нужно выполнить (опять таки из-под админа):
fsutil behavior set disablelastaccess 0
и перезагрузиться.