Skip to Content

Unable to unzip Concur REST calll zipped SAE file

Dear experts,

I'm referring concept from these 2 blogs to do Concur BPM and zipped SAE file processing.

Concur - PO: Integration centric process for Standard Accounting Extract (SAE) posting

Java Mapping: Unzip file and create additional attachments

Here my progress so far:

1) Start

2) REST call to initiated SAE job

3) Loop REST call until job status completed

4) REST call get response zipped file with 2 text files.

4.1) Convert response zipped file to base64 string and wrap in message using Java mapping directly in ESR. Main coding:

InputStream inputstream = transformationInput.getInputPayload().getInputStream();

OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();

byte[] content =getInputStreamBytes(inputstream);

String base64Encoded = DatatypeConverter.printBase64Binary(content);

String sOutContent = "";

sOutContent = sOutContent + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

sOutContent = sOutContent + "<ns0:CONCUR_Extract_File_Response xmlns:ns0=\"urn:my.company.namespace\">";

sOutContent = sOutContent + "<content>";

sOutContent = sOutContent + base64Encoded;

sOutContent = sOutContent + "</content>";

sOutContent = sOutContent + "</ns0:CONCUR_Extract_File_Response>";

outputstream.write(sOutContent.getBytes());

public byte[] getInputStreamBytes(InputStream inStream) throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] buffer = new byte[DEF_BUFFER_SIZE];

int read = 0;

while ((read = inStream.read(buffer, 0, buffer.length)) != -1) {

baos.write(buffer, 0, read);

}

baos.flush();

return baos.toByteArray();

}

4.2) Store the base64Encoded content field in string field in BPM context data

5 Unwrap using regex to get base64Encoded string, decoded to zipped file byte[], create ZipInputStream and loop ZipEntry and get SAE file outputstream.

InputStream inputstream = transformationInput.getInputPayload().getInputStream();

OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();

byte[] bXML = getInputStreamBytes(inputstream);

String sXML = new String(bXML);

Pattern pattern = Pattern.compile("<content>(?s)(.+?)</content>");

Matcher matcher = pattern.matcher(sXML);

matcher.find();

String base64Encoded = matcher.group(1);

byte[] base64Decoded =DatatypeConverter.parseBase64Binary(base64Encoded);

ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(base64Decoded));

ZipEntry ze = null;

// Loop through all entries in the zip file

while((ze = zis.getNextEntry()) != null) {

byte[] zipContent = getInputStreamBytes(zis);

String name = ze.getName();

if(name.toUpperCase().contains("SAE")){

outputstream.write(zipContent);

}

zis.closeEntry();

}

zis.close();

Problem:

The zip file not able to unzip, failed at zis.getNextEntry() with error "java.io.EOFException".

Other observation:
If i manually create own zip file locally, then load in OM/MM for step 4.1 and 5, is working fine able to unzip.

If i make call to Concur using SOAPUI, then use SOAPUI dump file feature get the zip file, is working fine able to unzip as well.

Look like problem only if I using PO to make REST call to Concur to get zipped file, will have problem.

Please help if you have any idea what might be the reason? Is my REST adapter configuration correct? Anything related to REST Charset and HTTP Header?

Zipped payload from Step 4:

Based64 Encoded from step 4.1:

PO REST adapter setting:

SOAPUI that is working fine, dump file zipped file able to open using WinZip/7Zip, load into OM step 4.1 and 5 is working fine as well.

THANKS!

Add comment
10|10000 characters needed characters exceeded

  • Follow
  • Get RSS Feed

2 Answers

  • Best Answer
    Apr 01, 2016 at 04:10 AM

    I take a look at source rest bean.

    this method processResult:

    The response payload will be created as XMLPayload or TextPayload and have If/Else for XML or JSON only, not binary data. Then inevitable will run String.getBytes("UTF-8") changed to UTF-8 charset.

    My doubt: Isn't Charset only applied to text only, no binary data like zip file?

    Guess this cause zip file become corrupted and not able open in winzip/7zip.

    Desperate to find a workable solution in PI, for now. I manually write java HTTP call to Concur to do prove-of-concept, and it work!. I used apache httpClient jar. Now the output zip file from below code can run properly in step 4.1(base64 encode) and step 5(based64 decode and unzip get SAE file only).

    The coding:

    However, mostly the Client will not accept this quick dirty solution. Will check with SAP on this REST adapter.

    Mark as solved for now.

    Rgds,

    Yee Loon


    Add comment
    10|10000 characters needed characters exceeded

    • Thanks for the update Yee Loon. Glad to know your issue has been resolved, but looks like we will have to depend on someone else in the future to raise this up with SAP - handling non-text response is not an uncommon scenario after all.

  • Mar 31, 2016 at 05:52 AM

    Hi Yee Loon

    Having fun with Concur, yah? 😉

    As this is a very complex interface, I'd suggest you to break down the analysis into different parts to identify which one is causing the issue.

    First of all, I'd suggest that you use MessageLoggerBean in step 4 to log the zipped response from the Get Extract File job. Then for Step 5, comment out the unzipping code and just output the decoded Base64 bytes as the output. This should give you the original zip file.

    Then you can compare the response zipped file in step 4 and the output zipped file in step 5 to see if the encoding and decoding works correctly.

    At this point of the development, there's no real point testing with own zip file or SOAP UI because it will not mirror the exact end-to-end behavior.

    From your EOFException currently, it looks like the zip file might not be correct. Once you confirm that the base64 encoding/decoding works fine, and passes through the BPM context fine too, then only you should concentrate of the unzipping part.

    I'd suggest then that you use the following approach to test your Base64 decoding and unzipping logic. Debugging in Eclipse/NWDS is much better than using trace in ESR.

    Standalone Testing of SAP PI/PO Java Mapping Programs: Decoupling Mapping Test Caller from Mapping Logic Implementation

    Try this out and let me know if you need any further pointers.

    Regards

    Eng Swee

    Add comment
    10|10000 characters needed characters exceeded