cancel
Showing results for 
Search instead for 
Did you mean: 

REST Receiver Adapter (sync) binary response. How to handle

JaySchwendemann
Active Contributor
0 Kudos
5,556

Dear all,

I'm on PO 7.50 SP13 and have a following scenario

  • ERP (ABAP Proxy sync) --> PI --> REST Service (sync). I use GET on REST side.
  • The rest service provides a binary file (if one would open it in the browser, the file would download to the client).
  • I'm trying to make use of the "data format --> Response Format --> Data Format --> Binary" option.

My problem is, no matter if I chose "Main Payload of XI Message" or "Attachment to XI Message" it hit a roadblock.

  • Main Payload of XI Message --> The payload is binary (an EML email file). Response Mapping does not like this
  • Attachment to XI Message --> Payload is empty. I get "Premature end of file" error either in graphical Mapping or XSLT mapping.

I read https://launchpad.support.sap.com/#/notes/2435422 and https://launchpad.support.sap.com/#/notes/1883809 but to no avail

My questions

  1. Does anybody have a running sync ABAP Proxy --> PI --> REST scenario where rest service delivers binary files. If so how did you set up?
  2. If opting for "Attachment to XI Message", how to deal with the empty payload?
  3. If opting for "Main Payload of XI Message", how to bypass that / get it through response message mapping?

Please note I'm no big fan of java mapping. Any solution that does not involve Java mapping would be highly appriciated, however, I'll swallow that bitter pill if must be.

Many thanks and kind regards

Jens

    Accepted Solutions (1)

    Accepted Solutions (1)

    adam_kiwon3
    Active Participant

    Hi Jens,

    You should go for the attachment and create a dummy XML payload for the ABAP Proxy Response.

    I would do this via Message Mapping as you can use the Java Mapping feature. Simply select any source/target message in the "Definition" Tab (Message Type/External Definition/XML) and then implement the Java Mapping in Tab "Functions" using simple code, such as creating a <DummyPayload/> here:

    public void transform(TransformationInput in, TransformationOutput out)	
    throws StreamTransformationException{
    try{
    String result = "<?xml version=\"1.0\" encoding=\"" + "UTF-8" + "\"?><DummyPayload/>"; out.getOutputPayload().getOutputStream().write(result.getBytes("UTF-8")); }
    catch(Exception e){
    throw new StreamTransformationException("Error");
    }
    }

    Best regards, Adam

    JaySchwendemann
    Active Contributor
    0 Kudos

    I'll be damned. This really works ! Thanks a ton!

    Sidenote: I had to change the content-type to "application/xml", too, so SXMB_MONI sucessfully shows the XML instead of trying to download it.

    Cheers

    Jens

    former_member378619
    Discoverer
    0 Kudos
    Hi Adam, in my case, there is a sync scenario ERP (ABAP Proxy sync) --> PI --> REST Service (sync) and I used POST request. Receiver system shall give me non-200 status in a text/plain so I have to create error handling in PI and hardcode response to enter message mapping. Could you please enlighten me how to read such error handling response in PI? Thanks in advance.

    Best regards,

    Beibei

    0 Kudos

    Hello,

    it is possible to have the complete configuration done in java, and the code used for the java mapping.

    Thanks

    Umberto

    Answers (3)

    Answers (3)

    JaySchwendemann
    Active Contributor

    Thanks both of you, but now...

    <rant>

    It is really sad that both solutions are a bit of a hack, especially the "Error handling" one. It often amuses me that the straightforward way a guy of simple tastes...

    would go (like chosing "binary" and "Attachment") will then need to work around Message Mapping and inject a Java mapping instead of PI just creating that frickin' empty message for you. I mean...

    They even do this on the FTP adapter alright without causing this...

    ...to happen, right?

    </rant>

    Anywas, I'll better bookmark this thread for future reference.

    Thanks both, Raffael and Adam.

    Cheers

    Jens

    r_herrmann
    Active Contributor

    I've got nothing to add. 😉

    rrwilcox5
    Discoverer
    0 Kudos

    Hello Jens,

    First, I am on PO 7.50 SP14. I have a scenario that is almost identical to yours. The scenario is Rest Sender (sync) -> PI -> Rest Receiver (sync). The Rest receiver service returns a zip file in the response.

    I set the response data format in the Rest Receiver to be "Binary" and selected the option "Attachment to XI message (No main payload). I also have a message mapping for the request and the response. The response mapping contains the JAVA mapping that Adam provided that creates a dummy payload.

    The error I am receiving when I run my scenario is:

    Transmitting the message using connection REST_http://sap.com/xi/XI/System failed, due to: com.sap.engine.interfaces.messaging.api.exception.MessagingException: Logging message failed, due to Failed to log msg a7702130-07d7-11eb-a6db-00002a23c556(OUTBOUND). Reason: java.lang.NullPointerException

    PI is failing due to an empty response even though I have the response message mapping with the JAVA mapping. Also, there is no attachment. It's looks to be behaving as if the response message mapping is not being used.

    If you have any advice, I would be very grateful.

    (BTW, I also have "Support attachments (multipart/mixed)" selected in both Rest Sender and Rest Receiver.)

    Thank you so much,

    Rhonda

    JaySchwendemann
    Active Contributor
    1. Hmm hard to tell from remote but I would guess it to be a java mapping error rather than a configuration error. Are you able to execute the response java mapping from ESB (NWDS) as a test without error? If yes I would advice taking a deeper look using XPI Inspector (Example 50 with sender and receiver rest channels selected)
    2. Where did you select the "Support attachments (multipart/mixed)" in the rest receiver channel? It's (not so early) morning, so I might need to grab another coffee, if I just overlooked it.
    rrwilcox5
    Discoverer
    0 Kudos

    Hello Jens!

    Thank you so much for the response. I was able to get the dummy payload response from the mapping to work, but the message contained no attachments. I ended up changing the Java mapping to do everything... unzip the payload and create the attachments. It works great, but I wish the option for "Attachments to XI message" in the Rest Receiver also worked.

    I have "Support attachments" selected in both the sender and the receiver.

    Thanks again!

    Rhonda

    peter_wallner2
    Active Contributor

    +1 for this funny post

    JaySchwendemann
    Active Contributor
    0 Kudos

    Hi Rhonda,

    you said "but the message contained no attachments". Does this mean...

    1. You were not able to see the attachment within PI Monitoring or SXMB_MONI?
    2. You were not able to get a handle to the message using the attachment protocol of the ABAP proxy?
    DATA(attachment_protocol) = CAST if_wsprotocol_attachments( proxy->if_proxy_basis~get_protocol( if_wsprotocol=>attachments ) ).
    DATA(attachments) = attachment_protocol->get_attachments( ).

    Cheers

    Jens

    JaySchwendemann
    Active Contributor
    0 Kudos

    BTW I had some crunch time lately and figured there may be a side effekt on whether "Attachment to XI message" works. I (as of now) could not get it to work if my iFlow contains more than one operation. The other operation (which just returns an JSON) works fine but as soon as I added that, the attachment operation went awry with error "Premature end of file".

    Maybe this helps someone out there. Guts feeling is that it might have to do with response determination. However, that might be difficult with a REST service providing a binary.

    Cheers

    Jens

    r_herrmann
    Active Contributor

    Another option (especially if you want to handle the binary data in the response mapping) would be to use the "Error handling" functions of the REST receiver channel:

    Activate custom error handling

    • Source: HTTP Status Code
    • Status Codes: 200 (or whatever code your service throws, when providing the download)
    • Action: Custom Result Message Content: <as shown below>

    As message content you can set an XML which matched the message type used in your interface and mapping. Then use {http_result} to let the adapter place the response of the rest service inside the XML message.

    <?xml version="1.0" encoding="UTF-8" ?>
    <MT_MyPayload>    
    <Data><![CDATA[ {http_result} ]]></Data> </MT_MyPayload>

    Note: This method may only work if your downloaded data is text-based. (But .eml-files, as stated in your question, are text-based.)

    JaySchwendemann
    Active Contributor
    0 Kudos

    Ha! This being the solution to my third question (having the "Main Payload of XI Message" option).

    schneidermarc
    Explorer
    0 Kudos

    Hi Raffael,

    I have a similar issue. Backend -> SOAP Sender -> REST Receiver. Request and responses are correctly processed. In case of an error the error handling takes place. But as the server does not send a JSON response, it sends text/plain, the conversation to XML fails. But as it detected the error it should take the custom result and place the server error message.

    So I have tried your code. But I think the channel does not take the error route as it still wants to convert the payload to xml. The exception is rised before a mapping, wether response or error, can take place.

    r_herrmann
    Active Contributor
    0 Kudos

    Hi schneidermarc ,

    to be honest, I never saw such constellation, thus I can only guess. But for me it looks like, it's running into the error handler and then fails again when doing the error handling. The question is, does it fail because the response of the service isn't a json or does it fail because the JSON you build in the error handling is invalid? (I'm, again, not sure if the JSON to XML conversion will also try to convert the message you set up in the error handling, but can you try to setup a minimal but valid JSON in your error handler?)

    schneidermarc
    Explorer
    0 Kudos

    r_herrmann thx for the fast response.

    If I test the faluty request in the browser, the message is correctly displayed:

    Invalid request: Unable to parse parameter 'state'. Details: No enum constant xxxxxxxxxxx

    Invalid request: Unable to parse parameter 'state'. Details: No enum constant chxxxxxxxxxxxxxx.log.LogStatus.DELIVERE

    I have tried a minimalistic JSON response but I am not sure if it's written correctly. I just added the { } around the http_result, pretending it to be a JSON result.

    <?xml version="1.0" encoding="UTF-8" ?>

    <MT__Error>

    <Data><{ {http_result} }</Data>

    </MT_Error>

    I also have tried the new modules already, but they do not solve the problem. I think because it does not arrive at this stage yet.

    0 Kudos

    Hi Jens,

    How it going? I think I am in the same trouble.

    JaySchwendemann
    Active Contributor
    0 Kudos

    Hi,

    could you please be more specific on where you strugle? Bottom line (as of now) is: Try to avoid RESTful services that provide binary answer. If not, go for Java Mapping (I prefered that) or misuse error handling.

    Cheers

    Jens