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:
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