Для отправки multipart / form-data из ESB в APIM - PullRequest
0 голосов
/ 07 ноября 2019

Я использую WSO2 ESB 6.4.0 и APIM 2.6.0

Я работаю над добавлением сертификата на APIM-сервер, используя API остальных приложения APIM. В запросе на добавление нового сертификата почтовый запрос должен быть form-data.

Итак, для автоматизации процесса я использую ESB-сервер. Я написал прокси, который выберет файл сертификата и обработает его. Ниже мой прокси-код

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="ClientSslCertificateAdd-APIM" startOnLoad="true" transports="http https vfs" xmlns="http://ws.apache.org/ns/synapse">
    <target>
        <inSequence>
            <!--   <enrich>
            <source clone="true" type="body"/>
            <target property="originalBody" type="property" />
        </enrich>
        <property expression="get-property('originalBody')"
                name="payloadposttexttransformation"
                scope="default"
                type="STRING"/> -->
            <property expression="$body/*" name="payload" scope="default" type="STRING"/>
            <property expression="get-property('payload')" name="xml form certificate captured  ===" scope="default" type="STRING"/>
            <xslt description="" key="xmltotext"/>
            <property expression="$body/*" name="payloadpostmapping" scope="default" type="STRING"/>
            <property name="filename" scope="default" type="STRING" value="filename_certifiate"/>
            <property name="alias" scope="default" type="STRING" value="alias_certifiate"/>
            <property name="endpoint" scope="default" type="STRING" value="endpoint_certifiate"/>
            <property name="uri.var.host" scope="default" type="STRING" value="http://apimserver.com/"/>
            <property name="uri.var.context" scope="default" type="STRING" value="certificates"/>
            <property expression="get-property('alias')" name="uri.var.resourcepath" scope="default" type="STRING"/>
            <property name="Authorization" scope="transport" type="STRING" value="Bearer token"/>
            <call>
                <endpoint>
                    <http method="get" uri-template="{uri.var.host}/{uri.var.context}/{uri.var.resourcepath}"/>
                </endpoint>
            </call>
            <property expression="json-eval($.status)" name="currentstatusoftobeaddedalias" scope="default" type="STRING"/>
            <filter regex="Expired" source="get-property('currentstatusoftobeaddedalias')">
                <then>
                    <property expression="get-property('alias')" name="alias" scope="default" type="STRING"/>
                    <property expression="get-property('endpoint')" name="endpoint" scope="default" type="STRING"/>
                    <property name="Authorization" scope="transport" type="STRING" value="Bearer token"/>
                    <property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
                    <payloadFactory media-type="xml">
                        <format>
                            <root xmlns="">
                                <certificate charset="UTF-8" contentType="text/plain" xmlns="http://org.apache.axis2/xsd/form-data">$3</certificate>
                                <alias xmlns="http://org.apache.axis2/xsd/form-data">$1</alias>
                                <endpoint xmlns="http://org.apache.axis2/xsd/form-data">$2</endpoint>
                            </root>
                        </format>
                        <args>
                            <arg evaluator="xml" expression="$ctx:alias"/>
                            <arg evaluator="xml" expression="$ctx:endpoint"/>
                            <arg evaluator="xml" expression="$ctx:payloadpostmapping"/>
                        </args>
                    </payloadFactory>
                    <property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
                    <!-- <property name="ContentType" scope="axis2" value="multipart/form-data" type="STRING"/> -->
                    <property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
                    <!-- <call>
                        <endpoint>
                            <http format="rest" method="post" uri-template="http://apimserver.com"/>
                        </endpoint>
                    </call> -->
                    <send>
            <endpoint>
            <http method="POST" format="rest"
                    uri-template="http://apimserver.com"/>
            </endpoint>
            </send>
                </then>
                <else>
                    <log>
                        <property name="alreadypresent" value="with entered alias name, certificate is active"/>
                    </log>
                </else>
            </filter>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </target>
    <parameter name="transport.PollInterval">5</parameter>
    <parameter name="transport.vfs.FileURI">file:///opt/new/esb/clientSSLcertificate_repo/</parameter>
    <parameter name="transport.vfs.ContentType">application/xml;charset=UTF-8</parameter>
    <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
    <parameter name="transport.vfs.MoveAfterFailure">file:///opt/new/esb/clientSSLcertificate_repo/failed_clientSSLcertificate</parameter>
    <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
    <parameter name="transport.vfs.FileNamePattern">.*.xml</parameter>
    <parameter name="transport.vfs.MoveAfterProcess">file:///opt/new/esb/clientSSLcertificate_repo/updated_clientSSLcertificate</parameter>
</proxy>

Сначала я проверяю статус псевдонима, присутствующего на сервере APIM, если срок его действия истек, он должен добавить сертификат.

также явыбрать файл из локального каталога ESB в форме xml и преобразовать его в текстовый / обычный формат, чтобы удалить все остатки и убедиться, что я отправляю правильное сообщение на сервер APIM.

Как только запрос будет обработан в APIMсервер, я получаю ниже ошибка в ESB-сервере

DEBUG - wire HTTP-Sender I/O dispatcher-2 >> "{"code":500,"message":"Internal server error","description":"The server encountered an internal error. Please contact administrator.","moreInfo":"","error":[]}[\r][\n]"
DEBUG - wire HTTP-Sender I/O dispatcher-2 >> "0[\r][\n]"
DEBUG - wire HTTP-Sender I/O dispatcher-2 >> "[\r][\n]"
DEBUG - headers http-outgoing-6 << HTTP/1.1 500 Internal Server Error
DEBUG - headers http-outgoing-6 << Server: nginx/1.16.1
DEBUG - headers http-outgoing-6 << Date: Wed, 06 Nov 2019 22:06:41 GMT
DEBUG - headers http-outgoing-6 << Content-Type: application/json
DEBUG - headers http-outgoing-6 << Transfer-Encoding: chunked
DEBUG - headers http-outgoing-6 << Connection: keep-alive

и ошибка от APIM-сервера

ERROR - GlobalThrowableMapper An Unknown exception has been captured by global exception mapper.
org.apache.cxf.interceptor.Fault: Couldn't find MIME boundary: --MIMEBoundary_4a754414be212aae0a86dd7fe9ddbf07662811acf9d618ec
        at org.apache.cxf.interceptor.AttachmentInInterceptor.handleMessage(AttachmentInInterceptor.java:60)
        at org.apache.cxf.jaxrs.ext.MessageContextImpl.createAttachments(MessageContextImpl.java:284)
        at org.apache.cxf.jaxrs.ext.MessageContextImpl.get(MessageContextImpl.java:79)
        at org.apache.cxf.jaxrs.impl.tl.ThreadLocalMessageContext.get(ThreadLocalMessageContext.java:42)
        at org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils.getMultipartBody(AttachmentUtils.java:143)
        at org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils.getAttachments(AttachmentUtils.java:155)
        at org.apache.cxf.jaxrs.provider.MultipartProvider.readFrom(MultipartProvider.java:149)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1355)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1307)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:836)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:795)
        at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:214)
        at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:78)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:191)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:80)
        at org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:91)
        at org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:65)
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
        at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke(CarbonTomcatValve.java:47)
        at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:57)
        at org.wso2.carbon.event.receiver.core.internal.tenantmgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:48)
        at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:47)
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
        at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
        at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1775)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1734)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Couldn't find MIME boundary: --MIMEBoundary_4a754414be212aae0a86dd7fe9ddbf07662811acf9d618ec
        at org.apache.cxf.attachment.AttachmentDeserializer.initializeRootMessage(AttachmentDeserializer.java:140)
        at org.apache.cxf.attachment.AttachmentDeserializer.initializeAttachments(AttachmentDeserializer.java:109)
        at org.apache.cxf.interceptor.AttachmentInInterceptor.handleMessage(AttachmentInInterceptor.java:58)
        ... 54 more

Из журнала ошибок кажется, что APIM-сервер не может получить прикрепленные файлыот ESB, и именно поэтому он не может обработать запрос.

Поддерживает ли APIM 2.6.0 multipart / form-data

Спасибо

1 Ответ

0 голосов
/ 07 ноября 2019

У нас была похожая проблема, и нам пришлось обновить messageFormatters и messageBuilders в файле axis2 / axis2.xml (как в ESB, так и в APIM):

обновить messageFormatters:

<!-- <messageFormatter contentType="multipart/form-data" 
  class="org.apache.axis2.transport.http.MultipartFormDataFormatter"/ -->
<messageFormatter contentType="multipart/form-data" 
  class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>

обновить messageBuilders

<!-- messageBuilder contentType="multipart/form-data"
  class="org.apache.axis2.builder.MultipartFormDataBuilder"/ -->
 <messageBuilder contentType="multipart/form-data"
  class="org.wso2.carbon.relay.BinaryRelayBuilder"/>

Эти обновления должны изменить транспорт для потоковой передачи полезной нагрузки, не анализируя и не перестраивая ее

...