All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.unicore.client.data.UFTPFileTransferClient Maven / Gradle / Ivy

The newest version!
package eu.unicore.client.data;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.Logger;
import org.json.JSONObject;

import eu.unicore.client.Endpoint;
import eu.unicore.client.utils.Configurable;
import eu.unicore.services.rest.client.IAuthCallback;
import eu.unicore.uas.fts.FiletransferOptions;
import eu.unicore.uas.fts.ProgressListener;
import eu.unicore.uas.json.JSONUtil;
import eu.unicore.uftp.client.AbstractUFTPClient;
import eu.unicore.uftp.client.UFTPProgressListener;
import eu.unicore.uftp.client.UFTPSessionClient;
import eu.unicore.uftp.dpc.AuthorizationFailureException;
import eu.unicore.uftp.dpc.Utils;
import eu.unicore.util.Log;
import eu.unicore.util.configuration.ConfigurationException;
import eu.unicore.util.httpclient.IClientConfiguration;

/**
 * UFTP file transfer client. It connects to an UFTP file transfer instance and 
 * is used to download or upload data. Uses the session mode of UFTP, if possible.
 *
 * @author schuller
 */
public class UFTPFileTransferClient extends FiletransferClient 
 implements Configurable, FiletransferOptions.IMonitorable, FiletransferOptions.IAppendable,
 			FiletransferOptions.Read, FiletransferOptions.SupportsPartialRead,  
 			FiletransferOptions.Write,
			UFTPConstants, UFTPProgressListener 
{

	private static final Logger logger = Log.getLogger(Log.CLIENT, UFTPFileTransferClient.class);

	private String secret;

	private InetAddress[] serverHosts;
	private final int serverPort;
	private final int streams;
	private final byte[] key;
	private final boolean compress;
	
	private ProgressListenerlistener;
	
	private String remoteFile;

	private boolean append;
	
	public UFTPFileTransferClient(Endpoint endpoint, JSONObject initialProperties, IClientConfiguration security, IAuthCallback auth) throws Exception {
		super(endpoint, initialProperties, security, auth);

		Mapparams=JSONUtil.asMap(initialProperties);
		updateServerHost(params.get(PARAM_SERVER_HOST));
		serverPort=Integer.parseInt(params.get(PARAM_SERVER_PORT));
		streams=Integer.parseInt(params.get(PARAM_STREAMS));
		String keySpec=params.get(PARAM_ENCRYPTION_KEY);
		key = keySpec!=null ? Utils.decodeBase64(keySpec) : null;
		compress=Boolean.parseBoolean(params.get(PARAM_ENABLE_COMPRESSION));
		remoteFile = params.get("fileName");
	}

	@Override
	public void configure(Mapparams){
		String secret=params.get(UFTPConstants.PARAM_SECRET);
		if(secret!=null)setSecret(secret);
		String overrideHost = params.get(PARAM_SERVER_HOST);
		if(overrideHost!=null){
			updateServerHost(overrideHost);
		}
	}
	
	protected void updateServerHost(String hostSpec){
		serverHosts = asHosts(hostSpec);
		if(serverHosts.length==0){
			throw new ConfigurationException("No usable UFTP server host could be determined from <"+hostSpec+">");
		}
	}
	
	public void setSecret(String secret){
		this.secret=secret;
	}

	@Override
	public void readAllData(OutputStream target) throws Exception {
		try(UFTPSessionClient c=new UFTPSessionClient(serverHosts, serverPort)){
			configureClient(c);
			c.connect();
			c.get("./"+remoteFile, target);
		}
	}

	@Override
	public long readPartial(long offset, long length, OutputStream target) throws IOException {
		try(UFTPSessionClient c=new UFTPSessionClient(serverHosts, serverPort)){
			configureClient(c);
			c.connect();
			return c.get("./"+remoteFile, offset, length, target);
		}
		catch(AuthorizationFailureException e){
			throw new IOException(e);
		}
	}

	@Override
	public void writeAllData(InputStream source) throws Exception {	
		writeAllData(source, -1);
	}

	@Override
	public void writeAllData(InputStream source, long numBytes) throws Exception {	
		try(UFTPSessionClient c=new UFTPSessionClient(serverHosts,serverPort)){
			configureClient(c);
			c.connect();
			if(append){
				c.append("./"+remoteFile, numBytes, source);
			}
			else{
				c.put("./"+remoteFile, numBytes, source);
			}
		}
	}

	private void configureClient(AbstractUFTPClient c){
		c.setNumConnections(streams);
		c.setSecret(secret);
		c.setCompress(compress);
		c.setKey(key);
		if(listener!=null)c.setProgressListener(this);
	}

	
	@Override
	public void setProgressListener(ProgressListener listener) {
		this.listener=listener;
	}
	
	public InetAddress[] getServerHosts() {
		return serverHosts;
	}

	public int getServerPort() {
		return serverPort;
	}

	public int getStreams() {
		return streams;
	}

	public boolean isCompressionEnabled() {
		return compress;
	}

	/**
	 * the base64 encoded encryption key, or null if no encryption
	 */
	public String getEncryptionKey() {
		return key!=null? Utils.encodeBase64(key) : null;
	}
	
	@Override
	public void setAppend() {
		append = true;
	}
	
	private long lastTotal=0;
	
	@Override
	public void notifyTotalBytesTransferred(long totalBytesTransferred) {
		if(listener!=null){
			//need to calculate difference to last call
			listener.notifyProgress(totalBytesTransferred-lastTotal);
			lastTotal=totalBytesTransferred;
		}
	}

	public InetAddress[]asHosts(String hostsProperty){
		ListhostList=new ArrayList();
		String[] hosts=hostsProperty.split("[ ,]+");
		for(String h: hosts){
			try{
				hostList.add(InetAddress.getByName(h));
			}catch(IOException io){
				logger.trace("Un-usable UFTP host address <"+h+"> : "+io);
			}
		}
		return hostList.toArray(new InetAddress[hostList.size()]);
	}
	
	public String asString(InetAddress[] ips){
		StringBuilder sb=new StringBuilder();
		for(InetAddress ip: ips){
			if(sb.length()>0)sb.append(',');
			sb.append(ip.getHostName());
		}
		return sb.toString();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy