package org.openslx.bwlp.sat.fileserv; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.openslx.bwlp.sat.util.Constants; import org.openslx.bwlp.sat.util.Formatter; import org.openslx.bwlp.thrift.iface.ImageDetailsRead; import org.openslx.bwlp.thrift.iface.TTransferRejectedException; import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.filetransfer.Downloader; import org.openslx.filetransfer.IncomingEvent; import org.openslx.filetransfer.Listener; import org.openslx.filetransfer.Uploader; public class FileServer implements IncomingEvent { private static final Logger LOGGER = Logger.getLogger(FileServer.class); /** * Listener for incoming unencrypted connections */ private final Listener plainListener = new Listener(this, null, 9092, Constants.TRANSFER_TIMEOUT); // TODO: Config private final ThreadPoolExecutor transferPool = new ThreadPoolExecutor(2, Constants.MAX_UPLOADS + Constants.MAX_DOWNLOADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue(1)); /** * All currently running uploads, indexed by token */ private final Map uploads = new ConcurrentHashMap<>(); private static final FileServer globalInstance = new FileServer(); private FileServer() { } public static FileServer instance() { return globalInstance; } public boolean start() { boolean ret = plainListener.start(); // TODO: Start SSL listener too return ret; } @Override public void incomingDownloadRequest(Uploader uploader) throws IOException { // TODO Auto-generated method stub } @Override public void incomingUploadRequest(Downloader downloader) throws IOException { String token = downloader.getToken(); LOGGER.info("Incoming filetransfer with token " + token); ActiveUpload upload = uploads.get(token); if (upload == null) { LOGGER.warn("Unknown token " + token); downloader.cancel(); return; } upload.addConnection(downloader, transferPool); } /** * Get an upload instance by given token. * * @param uploadToken * @return */ public ActiveUpload getUploadByToken(String uploadToken) { return uploads.get(uploadToken); } public String createNewUserUpload(UserInfo owner, ImageDetailsRead image, long fileSize, List sha1Sums) throws TTransferRejectedException { Iterator it = uploads.values().iterator(); int activeUploads = 0; while (it.hasNext()) { ActiveUpload upload = it.next(); if (upload.isComplete()) { // TODO: Check age (short timeout) and remove continue; } else { // Check age (long timeout) and remove } activeUploads++; } if (activeUploads > Constants.MAX_UPLOADS) throw new TTransferRejectedException("Server busy. Too many running uploads."); File destinationFile = null; do { destinationFile = Formatter.getTempImageName(); } while (destinationFile.exists()); destinationFile.getParentFile().mkdirs(); String key = UUID.randomUUID().toString(); ActiveUpload upload; try { upload = new ActiveUpload(key, owner, image, destinationFile, fileSize, sha1Sums); } catch (FileNotFoundException e) { LOGGER.error("Could not open destination file for writing", e); throw new TTransferRejectedException("Destination file not writable!"); } uploads.put(key, upload); return key; } public int getPlainPort() { return plainListener.getPort(); } public int getSslPort() { return 0; // TODO } }