* Create subInputStream from the OutputStream we will pass to the
* HttpEntity for writing content.
*/
final PipedInputStream contentInStream = new PipedInputStream(64 * 1024);
final PipedOutputStream contentOutStream = new PipedOutputStream(contentInStream);
SubInputStream segmentStream = new SubInputStream(contentInStream, actualSegmentSize, false);
/*
* Fork the call to entity.writeTo() that allows us to grab any exceptions raised
*/
final HttpEntity e = entity;
final Callable<Boolean> writer = new Callable<Boolean>() {
public Boolean call() throws Exception {
e.writeTo(contentOutStream);
return Boolean.TRUE;
}
};
ExecutorService writeExecutor = Executors.newSingleThreadExecutor();
final Future<Boolean> future = writeExecutor.submit(writer);
/*
* Check the future for exceptions after we've finished uploading segments
*/
Map<String, List<StorageObject>> newSegmentsAdded = new HashMap<String, List<StorageObject>>();
List<StorageObject> newSegments = new LinkedList<StorageObject>();
JsonArray manifestSLO = new JsonArray();
boolean finished = false;
/*
* Upload each segment of the file by reading sections of the content input stream
* until the entire underlying stream is complete
*/
while(!finished) {
String segmentName = String.format("%s/%08d", segmentBase, segmentNumber);
String etag;
try {
etag = storeObject(region, segmentContainer, segmentStream, "application/octet-stream", segmentName, new HashMap<String, String>());
}
catch(IOException ex) {
// Finished storing the object
ex.printStackTrace();
throw ex;
}
String segmentPath = segmentContainer + "/" + segmentName;
long bytesUploaded = segmentStream.getBytesProduced();
/*
* Create the appropriate manifest structure if we're making a static large
* object.
*
* ETAG returned by the simple upload
* total size of segment uploaded
* path of segment
*/
if(!dynamicLargeObject) {
JsonObject segmentJSON = new JsonObject();
segmentJSON.addProperty("path", segmentPath);
segmentJSON.addProperty("etag", etag);
segmentJSON.addProperty("size_bytes", bytesUploaded);
manifestSLO.add(segmentJSON);
newSegments.add(new StorageObject(segmentName));
}
segmentNumber++;
if(!finished) {
finished = segmentStream.endSourceReached();
}
newSegmentsAdded.put(segmentContainer, newSegments);
segmentStream.readMoreBytes(actualSegmentSize);
}
/*
* Attempts to retrieve the return value from the write operation
* Any exceptions raised can then be handled appropriately