MimeMultipart mp = new MimeMultipart(ds);
for(int i = 0; i < mp.getCount(); i++) {
// Get an individual part. This contains all the versioned
// values for a particular key referenced by content-location
MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(i);
// Get the key
String contentLocation = part.getHeader("Content-Location")[0];
String base64Key = contentLocation.split("/")[2];
ByteArray key = new ByteArray(RestUtils.decodeVoldemortKey(base64Key));
if(logger.isDebugEnabled()) {
logger.debug("Content-Location : " + contentLocation);
logger.debug("Base 64 key : " + base64Key);
}
// Create an array list for holding all the (versioned values)
List<Versioned<byte[]>> valueResultList = new ArrayList<Versioned<byte[]>>();
/*
* Get the nested Multi-part object. This contains one part for each unique versioned value.
*
* GetContent method can corrupt the embedded data, for example 0x8c be converted to 0xc2, 0x8c,
* hence use getInputStream.
*
* This thread tracks this question
* http://stackoverflow.com/questions/23023583/mimebodypart-getcontent-corrupts-binary-data
*
* getInputStream() : Return a decoded input stream for this Message's "content.
*
* getRawInputStream() : Return an InputStream to the raw data with any Content-Transfer-Encoding
* intact. This method is useful if the "Content-Transfer-Encoding" header is incorrect or corrupt,
* which would prevent the getInputStream method from returning the correct data. In such a case
* the application may use this method and attempt to decode the raw data itself.
*
*/
ByteArrayDataSource nestedDS = new ByteArrayDataSource(part.getInputStream(),
"multipart/mixed");
MimeMultipart valueParts = new MimeMultipart(nestedDS);
for(int valueId = 0; valueId < valueParts.getCount(); valueId++) {
MimeBodyPart valuePart = (MimeBodyPart) valueParts.getBodyPart(valueId);
String serializedVC = valuePart.getHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK)[0];
int contentLength = Integer.parseInt(valuePart.getHeader(RestMessageHeaders.CONTENT_LENGTH)[0]);
if(logger.isDebugEnabled()) {
logger.debug("Received serialized Vector Clock : " + serializedVC);
}
VectorClockWrapper vcWrapper = mapper.readValue(serializedVC,
VectorClockWrapper.class);
// get the value bytes
InputStream input = valuePart.getInputStream();
byte[] bodyPartBytes = new byte[contentLength];
input.read(bodyPartBytes);
VectorClock clock = new VectorClock(vcWrapper.getVersions(),
vcWrapper.getTimestamp());