barbitoff programmer`s blog

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

воскресенье, 6 октября 2013 г.

WSO2 ESB: вызов sequence с игнорированием ошибок

Задача

Вызвать один sequence из другого так, чтобы ошибка внутри вложенного sequence (например, сетевая ошибка при выполнении callout-медиатора) не приводила к ошибке наружного.

Решение

Т.к. средствами sequence-медиатора такое поведение нереализуемо, пришлось вызывать sequence из groovy-кода. Данная операция требует некоторых манипуляций с axis-контекстом, передаваемым вызываемой sqeucence. Немного длинно, но работает:
  <script language="groovy"><![CDATA[ import org.apache.commons.logging.LogFactory; import org.apache.synapse.core.axis2.Axis2MessageContext; try { /* create Axis2MessageContext, as ScriptMessageContext often can't be used to call this sequence - for example callout mediator in it will fail */ def mc2 = new Axis2MessageContext(new org.apache.axis2.context.MessageContext(),mc.getConfiguration(), mc.getEnvironment()); // copy existing envelope def newEnvelope = org.apache.axiom.om.util.CopyUtils.copy(mc.getEnvelope()); mc2.setEnvelope(newEnvelope); // propagate some properties to child context mc2.setProperty("prop1", mc.getProperty("prop1")); // force child sequence to use proxy-service logger mc2.setServiceLog(LogFactory.getLog("SERVICE_LOGGER.ProxyServiceName")); // execute child sequence mc.getSequence("ChildSequenceName").mediate(mc2); // restore envelope mc.setEnvelope(mc2.getEnvelope()); // restore some properties mc.setProperty("prop2", mc2.getProperty("prop2")); } catch(Exception ex) { LogFactory.getLog("SERVICE_LOGGER.ProxyServiceName").warn("Child sequence failed, continuing",ex); } ]]></script> 

четверг, 6 июня 2013 г.

WSO2 ESB: задание тела запроса из свойства

Задача

В некотором property хранится сериализованное тело запроса. Нужно установить его в запрос, заменив существующее тело.

Решение

Использовать enrich-медиатор не получится: он скопирует содержимое свойства как строку, заменив недопустимые в xml символы соотв. сущностями. Для того, чтобы распарсить содержимое свойства как xml и установить его единственным сыном soap:body, можно воспользоваться таким коротким скриптлетом:
<script language="groovy"><![CDATA[
mc.setPayloadXML(mc.getProperty("myprop"));
]]></script>
, где  myprop - имя свойства, хранящего содержимое запроса.

понедельник, 27 мая 2013 г.

WSO2 ESB: логирование из groovy-скрипт-медиатора

Вызов mc.getServiceLog() возвращает объект org.apache.commons.logging.Log (логгер имеет имя "org.apache.synapse.mediators.bsf.ScriptMessageContext"):
mc.getServiceLog().error("123")
выводит в wso2carbon.log:
TID: [0] [ESB] [2013-05-27 12:00:21,855] ERROR {org.apache.synapse.mediators.bsf.ScriptMessageContext} -  123 {org.apache.synapse.mediators.bsf.ScriptMessageContext} 

понедельник, 18 февраля 2013 г.

WSO2 ESB: замена пространств имен в сообщении перед проксированием на конечный сервис

Задача:

Во входящем сообщении перед его проксированием на конечный сервис у всех элементов в пространстве имен "http://ns1" установить пространство имен "http://ns2".

Решение:

Возможно, можно как-то лучше, но пока реализовал так:

<script language="js"><![CDATA[
var targetNs = new Namespace("http://ns2");
var srcNs = new Namespace("http://ns1");
var payload = mc.getPayloadXML();
var payloadElems = payload..srcNs::*;
for(i in payloadElems)
{
if(payloadElems[i].namespace()!=null)
{
payloadElems[i].setNamespace(targetNs);
}
}
mc.setPayloadXML(payload);
]]></script>
Проверка пространства имен на null в цикле выполняется из-за того, что в payloadElems попадают зачем-то текстовые узлы, у которых пространство имен равно null и попытка установить его с помощью setNamespace приведет к ошибке. 

пятница, 28 декабря 2012 г.

WSO2 ESB: быстрый trace содержимого сообщения в консоль

Конечно, для трэйса можно использовать log-медиатор, но если нужно всего лишь вывалить содержимое envelope`а в консоль, можно воспользоваться script-медиатором:
<script language="js"><![CDATA[
print(mc.getEnvelope());
]]></script>

четверг, 13 декабря 2012 г.

Доступ к объекту org.apache.axis2.context.MessageContext из script-mediator

В коде пользовательского Java-медиатора можно получить доступ к axis2-контексту, прикастовав контекст сообщения Axis2MessageContext и вызвав getAxis2MessageContext() (это может понадобится, например, для получения параметров прокси-сервиса). В script-медиаторе, к сожалению, метода getAxis2MessageContext() нет, при попытке сделать mc.getAxis2MessageContext() валится:
com.sun.phobos.script.util.ExtendedScriptException: org.mozilla.javascript.EcmaError: TypeError: Cannot find function ge
tAxis2MessageContext. (<Unknown Source>#2) in <Unknown Source> at line number 2
        at com.sun.phobos.script.javascript.RhinoCompiledScript.eval(RhinoCompiledScript.java:68)
        at javax.script.CompiledScript.eval(CompiledScript.java:92)
Дело в том, что переменная mc в скрипт-медиаторах является объектом класса org.apache.synapse.mediators.bsf.ScriptMessageContext (а не org.apache.synapse.core.axis2.Axis2MessageContext, как в случае с Java-медиатором), в котором действительно нет метода getAxis2MessageContext(). Поэтому, к сожалению, функционал, который можно реализовать с помощью script-медиатора, несколько уже, чем таковой для Java-медиаторов.