use of com.linkedin.pinot.common.segment.fetcher.SegmentFetcher in project pinot by linkedin.
the class PinotSegmentUploadRestletResource method post.
@Override
@Post
public Representation post(Representation entity) {
Representation rep = null;
File tmpSegmentDir = null;
File dataFile = null;
try {
// 0/ Get upload type, if it's uri, then download it, otherwise, get the tar from the request.
Series headers = (Series) getRequestAttributes().get(RESTLET_HTTP_HEADERS);
String uploadTypeStr = headers.getFirstValue(FileUploadUtils.UPLOAD_TYPE);
FileUploadType uploadType = null;
try {
uploadType = (uploadTypeStr == null) ? FileUploadType.getDefaultUploadType() : FileUploadType.valueOf(uploadTypeStr);
} catch (Exception e) {
uploadType = FileUploadType.getDefaultUploadType();
}
String downloadURI = null;
boolean found = false;
switch(uploadType) {
case URI:
case JSON:
// Download segment from the given Uri
try {
downloadURI = getDownloadUri(uploadType, headers, entity);
} catch (Exception e) {
String errorMsg = String.format("Failed to get download Uri for upload file type: %s, with error %s", uploadType, e.getMessage());
LOGGER.warn(errorMsg);
JSONObject errorMsgInJson = getErrorMsgInJson(errorMsg);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
return new StringRepresentation(errorMsgInJson.toJSONString(), MediaType.APPLICATION_JSON);
}
SegmentFetcher segmentFetcher = null;
// Get segmentFetcher based on uri parsed from download uri
try {
segmentFetcher = SegmentFetcherFactory.getSegmentFetcherBasedOnURI(downloadURI);
} catch (Exception e) {
String errorMsg = String.format("Failed to get SegmentFetcher from download Uri: %s", downloadURI);
LOGGER.warn(errorMsg);
JSONObject errorMsgInJson = getErrorMsgInJson(errorMsg);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.SERVER_ERROR_INTERNAL);
return new StringRepresentation(errorMsgInJson.toJSONString(), MediaType.APPLICATION_JSON);
}
// Download segment tar to local.
dataFile = new File(tempDir, "tmp-" + System.nanoTime());
try {
segmentFetcher.fetchSegmentToLocal(downloadURI, dataFile);
} catch (Exception e) {
String errorMsg = String.format("Failed to fetch segment tar from download Uri: %s to %s", downloadURI, dataFile.toString());
LOGGER.warn(errorMsg);
JSONObject errorMsgInJson = getErrorMsgInJson(errorMsg);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.SERVER_ERROR_INTERNAL);
return new StringRepresentation(errorMsgInJson.toJSONString(), MediaType.APPLICATION_JSON);
}
if (dataFile.exists() && dataFile.length() > 0) {
found = true;
}
break;
case TAR:
default:
// 1/ Create a factory for disk-based file items
final DiskFileItemFactory factory = new DiskFileItemFactory();
// 2/ Create a new file upload handler based on the Restlet
// FileUpload extension that will parse Restlet requests and
// generates FileItems.
final RestletFileUpload upload = new RestletFileUpload(factory);
final List<FileItem> items;
// 3/ Request is parsed by the handler which generates a
// list of FileItems
items = upload.parseRequest(getRequest());
for (FileItem fileItem : items) {
if (!found) {
if (fileItem.getFieldName() != null) {
found = true;
dataFile = new File(tempDir, fileItem.getFieldName());
fileItem.write(dataFile);
}
} else {
LOGGER.warn("Got extra file item while pushing segments: " + fileItem.getFieldName());
}
// TODO: remove the try-catch after verifying it will not throw any exception
try {
// Remove the temp file
// When the file is copied to instead of renamed to the new file, the temp file might be left in the dir
fileItem.delete();
} catch (Exception e) {
LOGGER.error("Caught exception while deleting the temp file, should not reach here", e);
}
}
}
// back to the client.
if (found) {
// Create a new representation based on disk file.
// The content is arbitrarily sent as plain text.
rep = new StringRepresentation(dataFile + " sucessfully uploaded", MediaType.TEXT_PLAIN);
tmpSegmentDir = new File(tempUntarredPath, dataFile.getName() + "-" + _controllerConf.getControllerHost() + "_" + _controllerConf.getControllerPort() + "-" + System.currentTimeMillis());
LOGGER.info("Untar segment to temp dir: " + tmpSegmentDir);
if (tmpSegmentDir.exists()) {
FileUtils.deleteDirectory(tmpSegmentDir);
}
if (!tmpSegmentDir.exists()) {
tmpSegmentDir.mkdirs();
}
// While there is TarGzCompressionUtils.unTarOneFile, we use unTar here to unpack all files
// in the segment in order to ensure the segment is not corrupted
TarGzCompressionUtils.unTar(dataFile, tmpSegmentDir);
File segmentFile = tmpSegmentDir.listFiles()[0];
String clientIpAddress = getClientInfo().getAddress();
String clientAddress = InetAddress.getByName(clientIpAddress).getHostName();
LOGGER.info("Processing upload request for segment '{}' from client '{}'", segmentFile.getName(), clientAddress);
return uploadSegment(segmentFile, dataFile, downloadURI);
} else {
// Some problem occurs, sent back a simple line of text.
String errorMsg = "No file was uploaded";
LOGGER.warn(errorMsg);
JSONObject errorMsgInJson = getErrorMsgInJson(errorMsg);
rep = new StringRepresentation(errorMsgInJson.toJSONString(), MediaType.APPLICATION_JSON);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.SERVER_ERROR_INTERNAL);
}
} catch (final Exception e) {
rep = exceptionToStringRepresentation(e);
LOGGER.error("Caught exception in file upload", e);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.SERVER_ERROR_INTERNAL);
} finally {
if ((tmpSegmentDir != null) && tmpSegmentDir.exists()) {
try {
FileUtils.deleteDirectory(tmpSegmentDir);
} catch (final IOException e) {
LOGGER.error("Caught exception in file upload", e);
ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR, 1L);
setStatus(Status.SERVER_ERROR_INTERNAL);
}
}
if ((dataFile != null) && dataFile.exists()) {
FileUtils.deleteQuietly(dataFile);
}
}
return rep;
}
Aggregations