cancel
Showing results for 
Search instead for 
Did you mean: 

Send zip file and form data through CPI and HTTP Adapter to Ariba

joao_miguel_17
Explorer
0 Kudos

Hello everyone,

I'm running into an issue regarding HTTP Adapter in CPI. The scenario is to pick up a file in a SFTP Server, create form data with the zip file attached and send it through HTTP Adapter to Ariba.

The problem is I keep running into error status code 411: Content-Length is required.

I've tried to define this header manually, but with no success. Sending the message to another host confirms that this header is created automatically when the message is sent by CPI, so it must be another thing unknown to me.

Exploring the blogs I've found another post talking about this exact same issue. The link is down below:

https://blogs.sap.com/2019/11/14/what-is-form-data-and-how-to-send-it-from-sap-cloud-platform-integr...

Nick Yang proposed a solution that revolves around opening a conection to the destination directly into the script, discarding the necessity of using HTTP Adapter. But I tried to replicate it, but keep getting the error:

java.lang.NoSuchMethodException: No signature of method: sun.net.www.http.PosterOutputStream.write() is applicable for argument types: (org.apache.camel.converter.stream.InputStreamCache) values: [org.apache.camel.converter.stream.InputStreamCache@144c18fd] Possible solutions: write([B), write(int), write(int), write(int), wait(), wait(long)

I assume this is because I'm creating the form data before in another script, but I don't convert the body of the message to byte array afterwards.

Can someone help me on this?

This is my current script:

def Message postZipContentToAriba(Message message){
    def messageLog = messageLogFactory.getMessageLog(message)
    def propertiesMap = message.getProperties()
    def headersMap = message.getHeaders()
    // POST
    def post = new URL("Ariba-Network-URL").openConnection();
    def zipContent = message.getBody()
    
    post.setRequestMethod("POST")
    post.setDoOutput(true)
    post.setRequestProperty("Content-Type", headersMap.get("Content-Type") as String)
    post.getOutputStream().write(zipContent);
    
    def postRC = post.getResponseCode();
    if(postRC.equals(200)) {
        messageLog.addAttachmentAsString("Post result:", post.getInputStream().getText() as String, "text/plain")
    }else{
        def exceptionMsg = "HTTP" + postRC.toString() + ", " + post.getInputStream().getText()
        throw new Exception(exceptionMsg as String)
    }
    
    return message
}


Message processData(Message message) {


    return postZipContentToAriba(message)
}

The script used before this one is to create multi-part form-data:

Message processData(Message message) {
    
    // Set multipart into body
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
    
    try{
    
        byte[] bytes = message.getBody(byte[])
        //  Construct Multipart
        MimeBodyPart bodyPartHead1 = new MimeBodyPart()
        bodyPartHead1.setText('true')
        bodyPartHead1.setDisposition('form-data; name="fullload"')
        
        MimeBodyPart bodyPartHead2 = new MimeBodyPart()
        bodyPartHead2.setText('Import External System Master Data')
        bodyPartHead2.setDisposition('form-data; name="event"')
        
        MimeBodyPart bodyPartHead3 = new MimeBodyPart()
        bodyPartHead3.setText(secret)
        bodyPartHead3.setDisposition('form-data; name="sharedsecret"')
        
        MimeBodyPart bodyPartHead4 = new MimeBodyPart()
        bodyPartHead4.setText(systemId)
        bodyPartHead4.setDisposition('form-data; name="systemId"')
        
        MimeBodyPart bodyPartHead5 = new MimeBodyPart()
        bodyPartHead5.setText('Load And Delete')
        bodyPartHead5.setDisposition('form-data; name="Operation"')
        
        MimeBodyPart bodyPartHead6 = new MimeBodyPart()
        bodyPartHead6.setText('Cloud')
        bodyPartHead6.setDisposition('form-data; name="clienttype"')
        
        MimeBodyPart bodyPartHead7 = new MimeBodyPart()
        bodyPartHead7.setText('CPI')
        bodyPartHead7.setDisposition('form-data; name="clientinfo"')
        
        MimeBodyPart bodyPartHead8 = new MimeBodyPart()
        bodyPartHead8.setText('1.0.0')
        bodyPartHead8.setDisposition('form-data; name="clientversion"')
        
        
        MimeBodyPart bodyPart = new MimeBodyPart()
        ByteArrayDataSource dataSource = new ByteArrayDataSource(bytes, 'application/zip')
        DataHandler byteDataHandler = new DataHandler(dataSource)
        bodyPart.setDataHandler(byteDataHandler)
        bodyPart.setFileName('content.zip')
        bodyPart.setDisposition('form-data; name="content"')
    
        MimeMultipart multipart = new MimeMultipart()
        multipart.addBodyPart(bodyPartHead1)
        multipart.addBodyPart(bodyPartHead2)
        multipart.addBodyPart(bodyPartHead3)
        multipart.addBodyPart(bodyPartHead4)
        multipart.addBodyPart(bodyPartHead5)
        multipart.addBodyPart(bodyPartHead6)
        multipart.addBodyPart(bodyPartHead7)
        multipart.addBodyPart(bodyPartHead8)
        multipart.addBodyPart(bodyPart)
        
        multipart.updateHeaders()
        
        multipart.writeTo(outputStream)
        message.setBody(outputStream)
    
        // Set Content type with boundary
        String boundary = (new ContentType(multipart.contentType)).getParameter('boundary');
        message.setHeader('Content-Type', "multipart/form-data; boundary=\"${boundary}\"")
        
        // Calculate message size
        //message.setHeader('content-length', message.getBodySize())
    
    }catch(Exception e){
        
    }finally{
        outputStream.close()
    }


    return message
}

Thank you and kind regards,

João Gomes

0 Kudos

Hi joao_miguel_17,

I see you are trying to post master data to Ariba using ITK based approach ( uploading zip file containing csv file). I am also trying this to do from SAP CPI. For me data gets to CPI in XML. Is it possible for you to provide the code where you are building the csv files and zipping them.

former_member71230
Discoverer
0 Kudos

Hi joao_miguel_17,

We have a similar requirement where we need to send data to Ariba. First, we need to pick up a CSV file from SFTP, ZIP it and send it in form of multipart form data. We have followed your blog and we are getting "Throwable caught: Illegal filename: ID-vsa10692304-1668261292152-120-2 || No stack available."

Can you please help us to troubleshoot this error?

Thanks,

Jeevitha

View Entire Topic
saidanturti34
Discoverer
0 Kudos

@joao_miguel_17 Please refer to the approach detailed in below blog. This has less custom coding and works like a charm for uploading zipped content to Ariba.

https://community.sap.com/t5/technology-blogs-by-members/sap-ariba-integration-using-sap-cloud-integ...