Как лучше всего выполнить итерацию внутри WSO2 EI?


После прочтения WSO2 EI References я все еще не понимаю, как использовать итераторы внутри последовательности EI. В моем случае у меня такая полезная нагрузка....

   {
...
   "array": [
    {"cpf": "12345678911"},
    {"cnpj":"12345678912346"}
   ]
}

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

введите здесь описание изображения

Код, реализующий это изображение, следующий:

 <iterate description="" expression="//jsonObject/array" id="myid">
                        <target>
                            <sequence>
                                <property expression="json-eval($.array.cpf)" name="tipoCPF" scope="default" type="STRING"/>
                                <filter description="" xpath="boolean(get-property('tipoCPF'))">
                                    <then>
                                        <property expression="json-eval($.array.cpf)" name="uri.var.cpf" scope="default" type="STRING"/>

                                        <call>
                                            <endpoint>
                                                <http method="get" uri-template="http://endpoint/service/{uri.var.cpf}"/>
                                            </endpoint>
                                        </call>
                                        <filter regex="200" source="get-property('axis2','HTTP_SC')">
                                            <then/>
                                            <else>
                                                <payloadFactory description="" media-type="json">
                                                    <format>{&#xd;
"code":"400",&#xd;
"error":"CPF inexistente"&#xd;
}</format>
                                                    <args/>
                                                </payloadFactory>
                                                <property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
                                                <respond/>
                                            </else>
                                        </filter>
                                    </then>
                                    <else>
                                        <property expression="json-eval($.array.cnpj)" name="tipoCNPJ" scope="default" type="STRING"/>
                                        <filter xpath="boolean(get-property('tipoCNPJ'))">
                                            <then>
                                                <property expression="json-eval($.array.cnpj)" name="uri.var.cnpj" scope="default" type="STRING"/>
                                                <header name="Authorization" scope="transport" value="Basic Y29yZS5jb25zdWx0aW5nOm8xNXRyZWI="/>
                                                <call>
                                                    <endpoint>
                                                        <http method="get" uri-template="http://endpoint/service/cnpj/{uri.var.cnpj}"/>
                                                    </endpoint>
                                                </call>
                                                <filter regex="200" source="get-property('axis2','HTTP_SC')">
                                                    <then/>
                                                    <else>
                                                        <payloadFactory media-type="json">
                                                            <format>{&#xd;
        "code":"400",&#xd;
        "error":"CNPJ inexistente"&#xd;
        }</format>
                                                            <args/>
                                                        </payloadFactory>
                                                        <property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
                                                        <respond/>
                                                    </else>
                                                </filter>
                                            </then>
                                            <else>
                                                <call>
                                                    <endpoint>
                                                        <http method="get" uri-template="http://endpoint/service/info"/>
                                                    </endpoint>
                                                </call>
                                            </else>
                                        </filter>
                                    </else>
                                </filter>
                            </sequence>
                        </target>
                    </iterate>

Этот итератор работает как часть «непоследовательности». «Непоследовательность» позволяет вставлять информацию о новых контрактах в базу данных.

Проблема: после добавления этого итератора служба начинает дублировать вставки в базу данных. Похоже, что итерация не заканчивается на краю тегов «итератор». Это похоже на то, что итерация продолжается до остальной части непоследовательности. Попробуйте. Чтобы решить эту проблему, я пытаюсь добавить агрегатор-посредник после итератора. Но или не имеет никакого эффекта, чтобы дублированная вставка сохранялась, или я получаю сообщение об ошибке.

Итак, как правильно проводить эти итерации внутри WSO2 EI?


person ChelloFera    schedule 23.01.2020    source источник


Ответы (3)


Как вы упомянули, итерация будет происходить даже за пределами тега итерации, пока не будет использован посредник Aggregate. Чтобы решить эту проблему, вам нужно добавить агрегатный посредник внутри итерируемого посредника. Это остановит итерацию внутри самого тега итератора.

В вашем случае может потребоваться установить continueParent="true" в IterateMediator, чтобы посредничество продолжалось после итерации посредника для операции вставки в базу данных.

person Arunan Sugunakumar    schedule 24.01.2020

Спасибо за помощь Арунану!

После вашего ответа я пытаюсь добавить агрегатор следующим образом
Добавление посредника агрегатора

Конфигурация агрегатора следующая:

...
 <aggregate id="NIRO">
                                    <completeCondition>
                                        <messageCount max="-1" min="-1"/>
                                    </completeCondition>
                                    <onComplete expression="//jsonObject">
                                        <log description="" level="full" separator=";">
                                            <property expression="json-eval($.)" name="jsonObject"/>
                                        </log>
                                    </onComplete>
                                </aggregate>
                            </sequence>
                        </target>
                    </iterate>

Как вам грустно, я меняю свойство итератора 'Continue Parent' на 'true'. Но проблема осталась....

person ChelloFera    schedule 24.01.2020
comment
Вы все еще получаете дубликаты записей? - person Arunan Sugunakumar; 25.01.2020
comment
Да! Проблема сохраняется! - person ChelloFera; 27.01.2020
comment
Можете ли вы поделиться полной конфигурацией синапса (с удаленной конфиденциальной информацией)? - person Arunan Sugunakumar; 28.01.2020
comment
Где найти эту конфигурацию? - person ChelloFera; 03.02.2020
comment
Исходное представление потока агрегатора показано выше на диаграмме. - person Arunan Sugunakumar; 03.02.2020

Как было предложено в другом ответе, вам нужно

  • используйте посредник Aggregate, чтобы закрыть итерацию
  • Если и только если для Итератора установлено значение continueParent="true"

Однако я не уверен, что размещение внутри <iterate> сработает. Вот рабочее решение с использованием посредника Aggregate сразу после вашего Iterator.

<sequence>
    <iterate continueParent="true" description="" expression="//jsonObject/array" id="myid">
        <target>
            <your_sequence />
        </target>
    </iterate>
    <aggregate>
        <completeCondition>
            <messageCount max="-1" min="-1" />
        </completeCondition>
        <onComplete enclosingElementProperty="//jsonObject/array" expression="/whatever/you/want"/>
    </aggregate>
</sequence>

Обратите внимание, что expression="//jsonObject/array" вы использовали в своей итерации, вам нужно будет использовать его в enclosingElementProperty агрегатора. Вот как ваш EI узнает, из какого итератора он должен агрегировать (не уверен на 100% в этом вопросе, скорее эмпирическое соображение).

person zar3bski    schedule 14.12.2020