volume upload: added md5 checksum validation also fixed the issue wherein the successful uploads where also moving to error state as the channelinactive is called after the end of successful upload as well. added a fileuploaded boolean to check when the channel is inactive.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d5dffb5d Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d5dffb5d Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d5dffb5d Branch: refs/heads/master Commit: d5dffb5dc9ba43b0595bad08e096526050b9e1a7 Parents: 6b8b4b9 Author: Rajani Karuturi <rajanikarut...@gmail.com> Authored: Wed Mar 18 12:17:15 2015 +0530 Committer: Rajani Karuturi <rajanikarut...@gmail.com> Committed: Wed Mar 18 12:20:51 2015 +0530 ---------------------------------------------------------------------- .../com/cloud/storage/VolumeApiServiceImpl.java | 2 +- .../resource/HttpUploadServerHandler.java | 38 ++++++++++++-------- .../resource/NfsSecondaryStorageResource.java | 15 ++++---- 3 files changed, 32 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/server/src/com/cloud/storage/VolumeApiServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index d2c1c69..567a742 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -333,7 +333,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic * encoded metadata using the post upload config key */ TemplateOrVolumePostUploadCommand command = - new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), volumeStore.getChecksum(), vol.getType().toString(), + new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(), vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString()); command.setLocalPath(volumeStore.getLocalDownloadPath()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java ---------------------------------------------------------------------- diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java index 0caee32..44a2b60 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java @@ -75,6 +75,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj private String uuid; + private boolean fileReceived = false; + private static final String HEADER_SIGNATURE = "X-signature"; private static final String HEADER_METADATA = "X-metadata"; @@ -92,13 +94,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj if (decoder != null) { decoder.cleanFiles(); } + fileReceived = false; } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - String message = "file receive failed or connection closed prematurely."; - logger.error(message); - storageResource.updateStateMapWithError(uuid, message); + if (!fileReceived) { + String message = "file receive failed or connection closed prematurely."; + logger.error(message); + storageResource.updateStateMapWithError(uuid, message); + } } @Override @@ -198,15 +203,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj return; } if (chunk instanceof LastHttpContent) { - try { - readFileUploadData(); - writeResponse(ctx.channel(), HttpResponseStatus.OK); - reset(); - } catch (InvalidParameterValueException e) { - logger.error("error during the file install.", e); - responseContent.append("\n").append(e.getMessage()); - writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR); - } + writeResponse(ctx.channel(), readFileUploadData()); + reset(); } } } @@ -220,7 +218,7 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj decoder = null; } - private void readFileUploadData() throws IOException { + private HttpResponseStatus readFileUploadData() throws IOException { while (decoder.hasNext()) { InterfaceHttpData data = decoder.next(); if (data != null) { @@ -229,8 +227,16 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj if (data.getHttpDataType() == HttpDataType.FileUpload) { FileUpload fileUpload = (FileUpload) data; if (fileUpload.isCompleted()) { - responseContent.append("upload successful."); - storageResource.postUpload(uuid, fileUpload.getFile().getName()); + fileReceived = true; + String status = storageResource.postUpload(uuid, fileUpload.getFile().getName()); + if (status != null) { + responseContent.append(status); + storageResource.updateStateMapWithError(uuid, status); + return HttpResponseStatus.INTERNAL_SERVER_ERROR; + } else { + responseContent.append("upload successful."); + return HttpResponseStatus.OK; + } } } } finally { @@ -238,6 +244,8 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler<HttpObj } } } + responseContent.append("received entity is not a file"); + return HttpResponseStatus.UNPROCESSABLE_ENTITY; } private void writeResponse(Channel channel, HttpResponseStatus statusCode) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d5dffb5d/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java ---------------------------------------------------------------------- diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 1bce4a0..f67015c 100755 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -2662,16 +2662,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S UploadEntity.ResourceType resourceType = uploadEntity.getResourceType(); String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename; - //String checkSum = computeCheckSum(originalTemplate); - //if (checkSum == null) { - // s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!"); - //} - //dnld.setCheckSum(checkSum); int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation)); int maxSize = uploadEntity.getMaxSizeInGB(); if(imgSizeGigs > maxSize) { - throw new InvalidParameterValueException("Maximum file upload size exceeded. Physical file size: "+imgSizeGigs+"GB. Maximum allowed size: "+maxSize+"GB."); + String errorMessage = "Maximum file upload size exceeded. Physical file size: " + imgSizeGigs + "GB. Maximum allowed size: " + maxSize + "GB."; + s_logger.error(errorMessage); + return errorMessage; } imgSizeGigs++; // add one just in case long timeout = (long)imgSizeGigs * installTimeoutPerGig; @@ -2684,6 +2681,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (uploadEntity.isHvm()) { scr.add("-h"); } + String checkSum = uploadEntity.getChksum(); + if (StringUtils.isNotBlank(checkSum)) { + scr.add("-c", checkSum); + } // add options common to ISO and template String extension = uploadEntity.getFormat().getFileExtension(); @@ -2734,7 +2735,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } catch (IOException e) { s_logger.warn("Something is wrong with template location " + resourcePath, e); loc.purge(); - return "Unable to download due to " + e.getMessage(); + return "Unable to upload due to " + e.getMessage(); } Map<String, Processor> processors = _dlMgr.getProcessors();