blob: 14bf6fe1b746a9e9ddb8058d29f64e06c31bfa06 [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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class FtpTemplateUploader implements TemplateUploader {
protected Logger logger = LogManager.getLogger(getClass());
public TemplateUploader.Status status = TemplateUploader.Status.NOT_STARTED;
public String errorString = "";
public long totalBytes = 0;
public long entitySizeinBytes;
private String sourcePath;
private String ftpUrl;
private UploadCompleteCallback completionCallback;
private BufferedInputStream inputStream = null;
private BufferedOutputStream outputStream = null;
private static final int CHUNK_SIZE = 1024 * 1024; //1M
public FtpTemplateUploader(String sourcePath, String url, UploadCompleteCallback callback, long entitySizeinBytes) {
this.sourcePath = sourcePath;
ftpUrl = url;
completionCallback = callback;
this.entitySizeinBytes = entitySizeinBytes;
}
@Override
public long upload(UploadCompleteCallback callback) {
switch (status) {
case ABORTED:
case UNRECOVERABLE_ERROR:
case UPLOAD_FINISHED:
return 0;
default:
}
new Date();
StringBuffer sb = new StringBuffer(ftpUrl);
// check for authentication else assume its anonymous access.
/* if (user != null && password != null)
{
sb.append( user );
sb.append( ':' );
sb.append( password );
sb.append( '@' );
}*/
/*
* type ==> a=ASCII mode, i=image (binary) mode, d= file directory
* listing
*/
sb.append(";type=i");
try {
URL url = new URL(sb.toString());
URLConnection urlc = url.openConnection();
File sourceFile = new File(sourcePath);
entitySizeinBytes = sourceFile.length();
outputStream = new BufferedOutputStream(urlc.getOutputStream());
inputStream = new BufferedInputStream(new FileInputStream(sourceFile));
status = TemplateUploader.Status.IN_PROGRESS;
int bytes = 0;
byte[] block = new byte[CHUNK_SIZE];
boolean done = false;
while (!done && status != Status.ABORTED) {
if ((bytes = inputStream.read(block, 0, CHUNK_SIZE)) > -1) {
outputStream.write(block, 0, bytes);
totalBytes += bytes;
} else {
done = true;
}
}
status = TemplateUploader.Status.UPLOAD_FINISHED;
return totalBytes;
} catch (MalformedURLException e) {
status = TemplateUploader.Status.UNRECOVERABLE_ERROR;
errorString = e.getMessage();
logger.error(errorString);
} catch (IOException e) {
status = TemplateUploader.Status.UNRECOVERABLE_ERROR;
errorString = e.getMessage();
logger.error(errorString);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ioe) {
logger.error(" Caught exception while closing the resources");
}
if (callback != null) {
callback.uploadComplete(status);
}
}
return 0;
}
@Override
public void run() {
try {
upload(completionCallback);
} catch (Throwable t) {
logger.warn("Caught exception during upload " + t.getMessage(), t);
errorString = "Failed to install: " + t.getMessage();
status = TemplateUploader.Status.UNRECOVERABLE_ERROR;
}
}
@Override
public Status getStatus() {
return status;
}
@Override
public String getUploadError() {
return errorString;
}
@Override
public String getUploadLocalPath() {
return sourcePath;
}
@Override
public int getUploadPercent() {
if (entitySizeinBytes == 0) {
return 0;
}
return (int)(100.0 * totalBytes / entitySizeinBytes);
}
@Override
public long getUploadTime() {
// TODO
return 0;
}
@Override
public long getUploadedBytes() {
return totalBytes;
}
@Override
public void setResume(boolean resume) {
}
@Override
public void setStatus(Status status) {
this.status = status;
}
@Override
public void setUploadError(String string) {
errorString = string;
}
@Override
public boolean stopUpload() {
switch (getStatus()) {
case IN_PROGRESS:
try {
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
logger.error(" Caught exception while closing the resources");
}
status = TemplateUploader.Status.ABORTED;
return true;
case UNKNOWN:
case NOT_STARTED:
case RECOVERABLE_ERROR:
case UNRECOVERABLE_ERROR:
case ABORTED:
status = TemplateUploader.Status.ABORTED;
case UPLOAD_FINISHED:
return true;
default:
return true;
}
}
}