blob: e4044412c52116a0c8fae65064c999b77b14bb34 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.storage.template;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import com.cloud.storage.StorageLayer;
public class LocalTemplateDownloader extends TemplateDownloaderBase implements TemplateDownloader {
public LocalTemplateDownloader(StorageLayer storageLayer, String downloadUrl, String toDir, long maxTemplateSizeInBytes, DownloadCompleteCallback callback) {
super(storageLayer, downloadUrl, toDir, maxTemplateSizeInBytes, callback);
String filename = new File(downloadUrl).getName();
_toFile = toDir.endsWith(File.separator) ? (toDir + filename) : (toDir + File.separator + filename);
}
@Override
public long download(boolean resume, DownloadCompleteCallback callback) {
if (_status == Status.ABORTED || _status == Status.UNRECOVERABLE_ERROR || _status == Status.DOWNLOAD_FINISHED) {
return 0;
}
_start = System.currentTimeMillis();
_resume = resume;
File src;
try {
src = new File(new URI(_downloadUrl));
} catch (URISyntaxException e1) {
logger.warn("Invalid URI " + _downloadUrl);
_status = Status.UNRECOVERABLE_ERROR;
return 0;
}
File dst = new File(_toFile);
FileChannel fic = null;
FileChannel foc = null;
FileInputStream fis = null;
FileOutputStream fos = null;
try {
if (_storage != null) {
dst.createNewFile();
_storage.setWorldReadableAndWriteable(dst);
}
ByteBuffer buffer = ByteBuffer.allocate(1024 * 512);
try {
fis = new FileInputStream(src);
} catch (FileNotFoundException e) {
logger.warn("Unable to find " + _downloadUrl);
_errorString = "Unable to find " + _downloadUrl;
return -1;
}
fic = fis.getChannel();
try {
fos = new FileOutputStream(dst);
} catch (FileNotFoundException e) {
logger.warn("Unable to find " + _toFile);
return -1;
}
foc = fos.getChannel();
_remoteSize = src.length();
_totalBytes = 0;
_status = TemplateDownloader.Status.IN_PROGRESS;
try {
while (_status != Status.ABORTED && fic.read(buffer) != -1) {
buffer.flip();
int count = foc.write(buffer);
_totalBytes += count;
buffer.clear();
}
} catch (IOException e) {
logger.warn("Unable to download", e);
}
String downloaded = "(incomplete download)";
if (_totalBytes == _remoteSize) {
_status = TemplateDownloader.Status.DOWNLOAD_FINISHED;
downloaded = "(download complete)";
}
_errorString = "Downloaded " + _remoteSize + " bytes " + downloaded;
_downloadTime += System.currentTimeMillis() - _start;
return _totalBytes;
} catch (Exception e) {
_status = TemplateDownloader.Status.UNRECOVERABLE_ERROR;
_errorString = e.getMessage();
return 0;
} finally {
if (fic != null) {
try {
fic.close();
} catch (IOException e) {
logger.info("[ignore] error while closing file input channel.");
}
}
if (foc != null) {
try {
foc.close();
} catch (IOException e) {
logger.info("[ignore] error while closing file output channel.");
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
logger.info("[ignore] error while closing file input stream.");
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
logger.info("[ignore] error while closing file output stream.");
}
}
if (_status == Status.UNRECOVERABLE_ERROR && dst.exists()) {
dst.delete();
}
if (callback != null) {
callback.downloadComplete(_status);
}
}
}
}