Image in PDF returns black when I try to make a response in assign message

I'm trying to get a PDF file of a ERP endpoint, when I make the call directly, work's perfectly, but if I make the same call with apigee in service callout and assign message, the content work's fine, but returns a black image on the place of original image. Any idea what's happening in my case?

Solved Solved
1 1 403
1 ACCEPTED SOLUTION

You mentioned PDF and Image.  Is the image embedded in the PDF?  Is "the image" the same thing as the PDF? 

Can you reproduce this with any other endpoint?  Do you have a mock endpoint that can return a static PDF?

Can you show your ServiceCallout and AssignMessage? 

When you say "Returns a black image",  I suppose there's an app or system or webpage that is displaying the image.  Have you compared the byte stream for the success case and the failure case?  ie with a hex-editor or something.  Have you Looked At the byte stream?   

I don't know what's happening, partly because I cannot see your configuration.  But, I have seen similar issues when people design their proxies assuming that the payloads are all text.  For some context for you, often the way Apigee policies work, is to handle text data.  If you have a byte stream, moving stuff around with AssignMessage may cause a conversion to a text string using UTF-8 encoding. That won't work well, if the original byte stream is not really a string.  A PDF or PNG is not a string, and this is one of those cases where "it won't work well." 

If this explanation doesn't make sense to you, then maybe an illustration will help?  If you have a terminal, you can "display" the byte stream of a PDF or PNG using cat on macos or linux, or type on windows. You'll see a mess of strange characters.  If you then copy-paste that output into a file, and name the file with a .pdf extension, the pdf won't be valid and won't display properly. The encoding conversion loses data. 

That is what I suspect is happening with your situation. 

You might not care about any of this. Maybe you're just thinking "ok, whatever, how do I fix it? How do I get the image I want?" 

The easiest way may be to simply use a normal Apigee target to connect with your ERP endpoint. 

Why are you using a ServiceCallout to retrieve the PDF?  Why are you not simply using an HTTP Target?  If you use a normal Apigee HTTP Target, there's no need to use AssignMessage to get the output of the target into the response. Apigee won't do the equivalent of "copy paste" and as a result you don't have the loss of data due to encoding and decoding.  

If using a normal Apigee target is not possible for some reason, then ... another thing you can try is this syntax with AssignMessage: 

  <AssignVariable>
    <Name>response.content</Name>
    <Ref>serviceCalloutResponse.content</Ref>
  </AssignVariable>
...

This works because it does not do the equivalent of "copy paste".  It does not coerce the content of the serviceCalloutResponse variable into a text string. 

If that does not work for you, you may need to use a Java callout to do the assignment, rather than AssignMessage.  Python might also work. 

View solution in original post

1 REPLY 1

You mentioned PDF and Image.  Is the image embedded in the PDF?  Is "the image" the same thing as the PDF? 

Can you reproduce this with any other endpoint?  Do you have a mock endpoint that can return a static PDF?

Can you show your ServiceCallout and AssignMessage? 

When you say "Returns a black image",  I suppose there's an app or system or webpage that is displaying the image.  Have you compared the byte stream for the success case and the failure case?  ie with a hex-editor or something.  Have you Looked At the byte stream?   

I don't know what's happening, partly because I cannot see your configuration.  But, I have seen similar issues when people design their proxies assuming that the payloads are all text.  For some context for you, often the way Apigee policies work, is to handle text data.  If you have a byte stream, moving stuff around with AssignMessage may cause a conversion to a text string using UTF-8 encoding. That won't work well, if the original byte stream is not really a string.  A PDF or PNG is not a string, and this is one of those cases where "it won't work well." 

If this explanation doesn't make sense to you, then maybe an illustration will help?  If you have a terminal, you can "display" the byte stream of a PDF or PNG using cat on macos or linux, or type on windows. You'll see a mess of strange characters.  If you then copy-paste that output into a file, and name the file with a .pdf extension, the pdf won't be valid and won't display properly. The encoding conversion loses data. 

That is what I suspect is happening with your situation. 

You might not care about any of this. Maybe you're just thinking "ok, whatever, how do I fix it? How do I get the image I want?" 

The easiest way may be to simply use a normal Apigee target to connect with your ERP endpoint. 

Why are you using a ServiceCallout to retrieve the PDF?  Why are you not simply using an HTTP Target?  If you use a normal Apigee HTTP Target, there's no need to use AssignMessage to get the output of the target into the response. Apigee won't do the equivalent of "copy paste" and as a result you don't have the loss of data due to encoding and decoding.  

If using a normal Apigee target is not possible for some reason, then ... another thing you can try is this syntax with AssignMessage: 

  <AssignVariable>
    <Name>response.content</Name>
    <Ref>serviceCalloutResponse.content</Ref>
  </AssignVariable>
...

This works because it does not do the equivalent of "copy paste".  It does not coerce the content of the serviceCalloutResponse variable into a text string. 

If that does not work for you, you may need to use a Java callout to do the assignment, rather than AssignMessage.  Python might also work.