1

One of my requirement is to send SOAP request, and receive response from Oracle UCM Cloud. I am using Java transformation to do the same. In one of the response, we receive a zip file as attachment, I am not able to capture and download the attachment.

Is there anyway to download the attachment and save to server. The code below captures the whole response into a file, but i want to capture the attachment only.

In Java, I send the below payload

payload = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:typ=\"http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/types/\">"+
            "<soapenv:Header/>\n"+
                "<soapenv:Body>\n"+
                    "<typ:downloadESSJobExecutionDetails>\n"+
                        "<typ:requestId>"+i_jobid+"</typ:requestId>\n"+
                    "<typ:fileType>log</typ:fileType>\n"+
                "</typ:downloadESSJobExecutionDetails>\n"+
            "</soapenv:Body>\n"+
        "</soapenv:Envelope>";
        System.out.println(payload);
        returnstring=httpPost("https://<<localhost>>.oraclecloud.com/fscmService/ErpIntegrationService?invoke=",payload, "<<credentials>>");

Then i capture the response as :

InputStream in = conn.getInputStream();
InputStreamReader iReader = new InputStreamReader( in );
BufferedReader bReader = new BufferedReader(iReader);

String line;
String response = "";
String fresponse = "";

int lcount = 0;
while ((line = bReader.readLine()) != null) 
{
 lcount++;
 response += line;
}

Then I cut out the xml response part and use only the attachment portion to perform the below tasks Convert it into bytes and then try and save as zip

byte buf[] = response.getBytes();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry("abclog.zip");
entry.setSize(buf.length);
zos.putNextEntry(entry);
zos.write(buf);
zos.closeEntry();
zos.close();
java.io.FileOutputStream out_zip_file = new java.io.FileOutputStream("abclogfin.zip");
out_zip_file.write(baos.toByteArray());

The raw response is:

------=_Part_2737_547225473.1557335354007Content-Type: application/xop+xml;charset=UTF-8;
type="text/xml"Content-Transfer-Encoding: 8bitContent-ID: <3196f51c-0526-4921-bde2-d8f8453a255a>
<?xml version="1.0" encoding="UTF-8" ?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header><wsa:Action>http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService//
ErpIntegrationService/downloadESSJobExecutionDetailsResponse</wsa:Action><wsa:MessageID>urn:uuid:db614b6f-cee2-4218-9921-177fa5b71c32</wsa:MessageID>
</env:Header><env:Body><ns0:downloadESSJobExecutionDetailsResponse xmlns:ns0="http://xmlns.oracle.com/apps/financials/commonModules/shared/model/
erpIntegrationService/types/"><ns2:result xmlns:ns2="http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/types/" 
xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns0="http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:DocumentDetails"><ns0:Content><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" 
href="cid:8a49811c-492b-4a51-aab2-16abdaf21ad3"/></ns0:Content><ns0:FileName xsi:nil="true"/><ns0:ContentType>zip</ns0:ContentType><ns0:DocumentTitle>ESS_L_13077
</ns0:DocumentTitle><ns0:DocumentAuthor>*****</ns0:DocumentAuthor><ns0:DocumentSecurityGroup>Attachments</ns0:DocumentSecurityGroup><ns0:DocumentAccount xsi:nil="true"/>
<ns0:DocumentName>13077.zip</ns0:DocumentName><ns0:DocumentId xsi:nil="true"/></ns2:result></ns0:downloadESSJobExecutionDetailsResponse></env:Body></env:Envelope>
------=_Part_2737_547225473.1557335354007Content-Transfer-Encoding: binaryContent-ID: <8a49811c-492b-4a51-aab2-16abdaf21ad3>PK

As per my understanding, the values after

 <8a49811c-492b-4a51-aab2-16abdaf21ad3>PK

is the attachment, But I am not able to download it. After doing the above process, i get a zip file of 5KB but no contents inside the file.

1 Answers1

0

Ok, SO i got the solution, after a lot of searching around. Posting it here.

Reference: https://www.programcreek.com/java-api-examples/index.php?api=javax.xml.soap.AttachmentPart

SOlution Code:

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Base64;
import java.util.Iterator;

import javax.xml.soap.*;

public class SOAPClientSAAJ 
{

    // SAAJ - SOAP Client Testing
    public static void main(String args[]) 
    {
        String soapEndpointUrl = "https://<<localhost>>.oraclecloud.com/fscmService/ErpIntegrationService";
       //This action url will change as per the function you are calling
        String soapAction = "http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/downloadESSJobExecutionDetails";
        String jobid = "13077";
        String optype = "log";
        String line;
        String response = "";
        String reqresponse = callSoapWebService(soapEndpointUrl, soapAction, jobid, optype);
        if(reqresponse.indexOf("Error")==-1)
        {
            Reader inputString = new StringReader(reqresponse);
            BufferedReader bReader = new BufferedReader(inputString);
            int lcount = 0;
            try 
            {
                while ((line = bReader.readLine()) != null) 
                {
                    lcount++;
                    if(lcount == 6 || lcount ==7)
                    {
                        response += line;
                    }
                }
            } 
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(response);
    }

    private static void createSoapEnvelope(SOAPMessage soapMessage, String jobid, String optype) throws SOAPException 
    {
        SOAPPart soapPart = soapMessage.getSOAPPart();
        //Create this based on the SOAP request XML, you can use SOAP UI to get the XML as you like
        String myNamespace = "typ";
        String myNamespaceURI = "http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/types/";

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("downloadESSJobExecutionDetails", myNamespace);

        SOAPElement requestId = soapBodyElem.addChildElement("requestId", myNamespace);
        requestId.addTextNode(jobid);

        SOAPElement fileType = soapBodyElem.addChildElement("fileType", myNamespace);
        fileType.addTextNode(optype);        

      

    }

    private static String callSoapWebService(String soapEndpointUrl, String soapAction, String jobid,String optype) 
    {
        String returnvalue="";
        try 
        {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server
            SOAPMessage soapRequest = createSOAPRequest(soapAction, jobid, optype);
            SOAPMessage soapResponse = soapConnection.call(soapRequest, soapEndpointUrl);

            // Print the SOAP Response
            //System.out.println("Response SOAP Message:");
            //soapResponse.writeTo(System.out);
            //System.out.println();
            
            
            /******extract zip****/
            
            try 
            {
                int numOfAttachments = soapResponse.countAttachments();
                Iterator<?> attachments = soapResponse.getAttachments();

                StringBuilder buf = new StringBuilder("Number of attachments: ");
                buf.append(numOfAttachments);
                int count = 1;
                while (attachments.hasNext()) 
                {
                    AttachmentPart attachment = (AttachmentPart) attachments.next();
                    buf.append(" | #").append(count);
                    buf.append(" | Content Location: ").append(attachment.getContentLocation());
                    buf.append(" | Content Id: ").append(attachment.getContentId());
                    buf.append(" | Content Size: ").append(attachment.getSize());
                    buf.append(" | Content Type: ").append(attachment.getContentType());
                    buf.append(" | Content String: ").append(attachment.toString());
                    count++;
                    
                    //getting the file to particular Driver Name(C drive ,D drive)
                    
                    //OutputStream fos = new FileOutputStream(new File("D:\\tmp\\fresponse_2048.zip"));
                    java.io.FileOutputStream out_file = new java.io.FileOutputStream("D:\\tmp\\"+jobid+".zip");
                    out_file.write(attachment.getRawContentBytes());
                    out_file.close();

                }
                //System.out.println(buf.toString());
            } 
            catch (SOAPException e) 
            {
                System.out.println(e.getMessage());
            }
            
            /****extract zip*****/

            soapConnection.close();
            
            /**write to a variable**/
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            soapResponse.writeTo(stream);
            returnvalue = new String(stream.toByteArray(), "utf-8");
            
        } 
        catch (Exception e) 
        {
            returnvalue="Error occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!";
        }
        return returnvalue;
    }

    private static SOAPMessage createSOAPRequest(String soapAction, String jobid, String optype) throws Exception 
    {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();

        createSoapEnvelope(soapMessage, jobid, optype);
        
        String authstr = "<<userid>>:<<password>>";
        byte[] authBytes = authstr.getBytes("UTF-8");
        String auth = Base64.getEncoder().encodeToString(authBytes);

        //String authorization = new sun.misc.BASE64Encoder().encode((username+":"+password).getBytes());
        //MimeHeaders hd = message.getMimeHeaders();
        //hd.addHeader("Authorization", "Basic " + authorization);

        MimeHeaders headers = soapMessage.getMimeHeaders();
        headers.addHeader("Authorization", "Basic " + auth);
        headers.addHeader("SOAPAction", soapAction);

        soapMessage.saveChanges();

        /* Print the request message, just for debugging purposes */
        //System.out.println("Request SOAP Message:");
        //soapMessage.writeTo(System.out);
        //System.out.println("\n");

        return soapMessage;
    }
}

Adding comments as requested by @Marco @Marco This is the endpoint url for oracle cloud : String soapEndpointUrl = "https://<>.oraclecloud.com/fscmService/ErpIntegrationService"; This is the job that will be executed within oracle cloud, this job lets us download the log files String soapAction = "http://xmlns.oracle.com/apps/financials/commonModules/shared/model/erpIntegrationService/downloadESSJobExecutionDetails"; This specifies which job's log file we are trying to download String optype="log" String jobid="123123"

Function createSOAPRequest: calls createSoapEnvelope function to create a SOAP request XML used to authenticate using userid/pwd and adding it to the header

Function callSoapWebService: calls the createSOAPRequest function then based on the response, tries to download the attachment

Uses javax.xml.soap.* especially the javax.xml.soap.SOAPFactory class to create the SOAP request (https://www.tutorialspoint.com/java/xml/javax_xml_soap_soapfactory.htm), Uses javax.xml.soap.SOAPConnectionFactor to create a SOAP Connection

SOAPMessage soapRequest = createSOAPRequest(soapAction, jobid, optype); --> creates the soap request

SOAPMessage soapResponse = soapConnection.call(soapRequest, soapEndpointUrl); --> the o/p of the createSOAPRequest call is passed to soapConnection along with the end point url --> the o/p of createSOAPRequest is basically the XML request one usually sends in SOAPUI