Статьи

Приложения SOAP & REST в Муле

[Эта статья была написана Альбином Кьеллином .]

Недавно я работал над проектом, в котором мы должны были обрабатывать вложения SOAP . Работа с вложениями SOAP — это то, над чем вы работаете каждые 3-5 лет, а затем, через 10 секунд после того, как вы закончите, вы забудете о них все. Вся необходимая информация доступна в наших документах, но все же будет полезно иметь полный пример из конца в конец в качестве справочного материала. Блог Эстебана Роблеса Луны (бывший коллега по MuleSoft) « Работа с вложениями SOAP с использованием модуля CXF Mule» с 2011 года был наиболее полезным.

Работая над этим проектом, я также хотел посмотреть, как это можно реализовать, используя сервисы RAML и REST вместо SOAP. При изучении темы кажется, что нет полного консенсуса относительно того, как это сделать, но я нашел это обсуждение — Как мне загрузить файл с метаданными, используя веб-сервис REST? — довольно интересно.

Вариант использования очень прост: отправка и получение файла PDF в виде вложения SOAP и вложения REST . Приложение имеет четыре разных потока:

  • Прочитайте PDF-файл с диска, а затем добавьте его как SOAP-приложение к запросу.
  • Предоставьте сервис SOAP, способный получать запрос SOAP с вложением.
  • Прочитайте файл PDF с диска и добавьте его в качестве вложения в вызов REST.
  • Предоставьте сервис REST, используя APIkit и RAML, который может обрабатывать запрос с вложением.

1. SOAP Attachment — Клиент

Это, вероятно, самый сложный поток, поскольку для создания вложения требуется около 4 строк кода, а для настройки клиентской части используется модуль CXF. Запустите поток, скопировав файл src / test / resources / esb .pdf в папку src / test / resources / soap / attachment / in . Файл конфигурации можно найти здесь:

<flow name="file2soap" doc:description="Reads a file and sends that as a SOAP attachment to a SOAP service.">
<file:inbound-endpoint path="src/test/resources/soap/attachment/in" responseTimeout="10000" doc:name="Read File" />
<processor-chain doc:name="Processor Chain">
<scripting:transformer doc:name="Create SOAP Attachement">
<scripting:script engine="Groovy"><![CDATA[def attachment = new org.apache.cxf.attachment.AttachmentImpl(originalFilename)
def source = new org.apache.axiom.attachments.ByteArrayDataSource(payload.getBytes(),'application/pdf');
attachment.setDataHandler(new org.apache.axiom.attachments.ConfigurableDataHandler(source));
message.setInvocationProperty('cxf_attachments',[attachment])
return payload
]]></scripting:script>
</scripting:transformer>

<set-payload value="#[['FirstName', 'LastName', '123'].toArray()]" doc:name="Create Payload Map" />
<cxf:jaxws-client operation="contact" serviceClass="org.mule.demo.soap.Contact" doc:name="SOAP Client">
<cxf:outInterceptors>
<spring:bean class="org.mule.module.cxf.support.CopyAttachmentOutInterceptor" />
</cxf:outInterceptors>
</cxf:jaxws-client>
<http:request config-ref="SOAP-Service" path="contacts" method="POST" doc:name="Call SOAP Service" />
</processor-chain>
</flow>

2. SOAP Attachment — Сервер

Этот поток предоставляет веб-службу SOAP, извлекает вложение SOAP из запроса и записывает его на диск. Служба запускается при запуске клиента, если вы хотите проверить его по отдельности, просто используйте интерфейс SOAP и укажите его на конечную точку (http: // localhost: 8883 / contacts) . Файл конфигурации для этого веб-сервиса можно найти здесь:

<http:listener-config name="SOAP-in" host="0.0.0.0" port="8883" doc:name="HTTP Listener Configuration" />

<flow name="soap2file">
<http:listener config-ref="SOAP-in" path="/contacts" doc:name="Receive SOAP Request" parseRequest="false" />
<cxf:jaxws-service serviceClass="org.mule.demo.soap.Contact" doc:name="Parse SOAP Request">
<cxf:inInterceptors>
<spring:bean class="org.mule.module.cxf.support.CopyAttachmentInInterceptor" />
</cxf:inInterceptors>
</cxf:jaxws-service>
<choice doc:name="Choice">
<when expression="#[flowVars.containsKey('cxf_attachments')]">
<set-payload value="#[cxf_attachments.iterator().next().getDataHandler().getContent()]" doc:name="Retrive Attachment" />
<file:outbound-endpoint path="src/test/resources/soap/attachment/out" outputPattern="#[server.dateTime.toString()].pdf" responseTimeout="10000" doc:name="Write File to Disc" />
</when>
<otherwise>
<logger message="********************** No SOAP Attachement Found! **********************" level="INFO" doc:name="Log Missing Attachment" />
</otherwise>
</choice>

<set-payload value="Success" doc:name="Generate Response" />
</flow>

3. REST Attachment — Клиент

Эта реализация очень проста, просто используйте процессор сообщений вложения и исходящий HTTP-вызов, чтобы сделать вызов. Вы можете запустить поток, скопировав файл src / test / resources / esb.pdf в папку src / test / resources / rest / attachment / in . Файл конфигурации для этого можно найти здесь:

<http:request-config name="HTTP_Request_Configuration" host="localhost" basePath="api" port="8884" doc:name="HTTP Request Configuration"/>
<flow name="file2rest" doc:description="Reads a file from your desktop and sends that to a rest service.">
<file:inbound-endpoint path="src/test/resources/rest/attachment/in" responseTimeout="10000" doc:name="File"/>
<file:file-to-byte-array-transformer doc:name="File to Byte Array"/>
<set-attachment attachmentName="#[originalFilename]" value="#[payload]" contentType="multipart/form-data" doc:name="Attachment"/>
<http:request config-ref="HTTP_Request_Configuration" path="contact/abc/datasheet" method="POST" doc:name="HTTP" parseResponse="false"/>
</flow>

4. REST Attachment — сервер

Прием службы REST автоматически генерируется с использованием файла RAML, который можно найти здесь . В API есть несколько дополнительных методов, которые не используются в этом примере. Пример может быть запущен клиентом, описанным в шаге 3, путем копирования файла в нужную папку или любой консоли REST, которая может принять вложение, отправив сообщение по этому адресу: http: // localhost: 8884 / api / contact / abc / таблица данных . Конфигурация для этого API может быть найдена здесь:

<flow name="main">
<http:inbound-endpoint address="http://localhost:8884/api" doc:name="HTTP" exchange-pattern="request-response" />
<apikit:router config-ref="apiConfig" doc:name="APIkit Router" />
</flow>

<flow name="post:/contact/{contactId}/datasheet:apiConfig">
<set-payload value="#[message.inboundAttachments]" doc:name="Retrieve Attachments"/>
<foreach doc:name="For Each">
<set-payload value="#[payload.getInputStream() ]" doc:name="Get Inputstream from Payload"/>
<file:outbound-endpoint path="src/test/resources/rest/attachment/out" responseTimeout="10000" doc:name="File" outputPattern="#[server.dateTime.toString()].pdf"/>
        </foreach>
<set-payload value="{"status":"success"}" doc:name="Generate JSON Response" />
</flow>

Полный проект доступен в github:
https://github.com/albinkjellin/soap-rest-attachments