src-main.org.awakefw.file.api2.client.AwakeFileSessionNew Maven / Gradle / Ivy
Show all versions of awake-file Show documentation
/*
* This file is part of Awake FILE.
* Awake FILE: Easy file upload & download over HTTP with Java.
* Copyright (C) 2014, KawanSoft SAS
* (http://www.kawansoft.com). All rights reserved.
*
* Awake FILE is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Awake FILE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Any modifications to this file must keep this entire header
* intact.
*/
package org.awakefw.file.api2.client;
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Vector;
import org.apache.http.message.BasicNameValuePair;
import org.awakefw.commons.api.client.HttpProtocolParameters;
import org.awakefw.commons.api.client.HttpProxy;
import org.awakefw.commons.api.client.InvalidLoginException;
import org.awakefw.commons.api.client.RemoteException;
import org.awakefw.commons.server.util.AwakeServerLogger;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.http.HttpTransfer;
import org.awakefw.file.http.HttpTransferOne;
import org.awakefw.file.json.ListOfStringTransport;
import org.awakefw.file.util.StringUtil;
import org.awakefw.file.util.Tag;
import org.awakefw.file.util.parms.Action;
import org.awakefw.file.util.parms.Parameter;
import org.awakefw.file.util.parms.ReturnCode;
import org.awakefw.file.version.AwakeFileVersion;
/**
* Main class for executing from a Client all sorts of operations on remote files or
* remote classes through a Http or Https session.
*
* Package includes:
*
* - Get remote files size.
* - Delete remote files.
* - Get a remote directory list.
* - Upload files.
* - Download files.
* - Call remote Java methods.
*
* Example:
*
*
* // Create an AwakeFileSession instance and username on the remote server
* // using the URL of the path to the AwakeFileManager Servlet
*
* AwakeFileSession awakeFileSession = new AwakeFileSession(
* "https://www.acme.org/AwakeFileManager");
* boolean loginOk = awakeFileSession.login("myUsername",
* "myPassword".toCharArray());
*
* if (loginOk) {
* // OK: upload a file
* awakeFileSession.uploadFile(new File("c:\\myFile.txt"), "myFile.txt");
* } else {
* System.out.println("username or password is invalid!");
* }
*
*
*
*
* Communication via an (authenticating) proxy server is done using a
* {@link org.awakefw.commons.api.client.HttpProxy} instance:
*
*
*
* HttpProxy httpProxy = new HttpProxy("myproxyhost", 8080);
*
* AwakeFileSession awakeFileSession = new AwakeFileSession(
* "https://www.acme.org/AwakeFileManager", httpProxy);
* boolean loginOk = awakeFileSession.login("myUsername",
* "myPassword".toCharArray());
* // Etc.
*
*
*
*
* All long operations that need to be run on a separated thread may be followed
* in Swing using a Java Progress Bar or Progress Monitor: just implement the
* {@link org.awakefw.commons.api.client.AwakeProgressManager} interface.
*
*
* @see org.awakefw.commons.api.client.HttpProxy
* @see org.awakefw.commons.api.client.AwakeProgressManager
*
* @since 1.0
*
*/
public class AwakeFileSessionNew {
/** For debug info */
private static boolean DEBUG = AwakeDebug.isSet(AwakeFileSessionNew.class);
/** The url to use to connectet to the Awake FILE Server */
private String url = null;
/**
* The username is stored in static memory to be passed to upload file
* servlet
*/
private String username = null;
/**
* Token is stored in static to be available during all session and contains
* SHA-1(userId + ServerClientLogin.SECRET_FOR_LOGIN) computed by server.
* Token is re-send and checked at each send or recv command to be sure user
* is authenticated.
*/
private String authenticationToken = null;
/** The Http Proxy instance */
private HttpProxy httpProxy = null;
/** The Http Parameters instance */
private HttpProtocolParameters httpProtocolParameters = null;
/** The http transfer instance */
private HttpTransfer httpTransfer = null;
/*
* Login to the Awake FILE Server.
The Web Behavior of the username
* operations is as follow:
- The method will launch the remote
* username through HttpsTransferLogin.
- If successful, remote
* username will respond with a token that will contain SHA-1(userId +
* secret value).
The token will be stored in instance memory and
* resent with each API method and rechecked by the Awake FILE Server.
*/
/**
* Constructor.
*
*
* @param url
* the URL of the path to the AwakeFileManager Servlet
* @param username
* the username for authentication on the Awake Server
* @param password
* the user password for authentication on the Awake Server
*
* @throws MalformedURLException
* if the url is malformed
* @throws IllegalArgumentException
* if username or password is null
* @throws UnknownHostException
* if Host url (http://www.acme.org) does not exists or no
* Internet Connection..
* @throws ConnectException
* if the Host is correct but the AwakeFileManager Servlet is
* not reachable (http://www.acme.org/AwakeFileManager) and
* access failed with a status != OK (200). (If the host is
* incorrect, or is impossible to connect to - Tomcat down - the
* ConnectException will be the sub exception
* HttpHostConnectException.)
* @throws RemoteException
* an exception has been thrown on the server side
* @throws SecurityException
* the url is not secured with https (SSL)
* @throws IOException
* For all other IO / Network / System Error
*/
public AwakeFileSessionNew(String url, String username, char[] password)
throws IllegalArgumentException, MalformedURLException,
UnknownHostException, ConnectException, InvalidLoginException, RemoteException,
IOException {
if (url == null) {
throw new IllegalArgumentException("url can not be null!");
}
@SuppressWarnings("unused")
URL asUrl = new URL(url); // Try to raise a MalformedURLException;
if (username == null) {
throw new IllegalArgumentException("username can not be null!");
}
if (password == null) {
throw new IllegalArgumentException("password can not be null!");
}
this.username = username;
this.url = url;
String passwordStr = new String(password);
// Launch the Servlet
httpTransfer = new HttpTransferOne(url, httpProxy,
httpProtocolParameters, null);
// Prepare the request parameters
List requestParams = new Vector();
requestParams.add(new BasicNameValuePair(Parameter.ACTION,
Action.LOGIN_ACTION));
requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username));
requestParams.add(new BasicNameValuePair(Parameter.PASSWORD,
passwordStr));
httpTransfer.send(requestParams);
// If everything is OK, we have in our protocol a response that
// 1) starts with "OK". 2) Is followed by the Authentication Token
// else: response starts with "INVALID_LOGIN_OR_PASSWORD".
String receive = httpTransfer.recv();
if (receive.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) {
throw new InvalidLoginException();
} else if (receive.startsWith(ReturnCode.OK)) {
// OK! We are logged in & and correctly authenticated
// Keep in static memory the Authentication Token for next api
// commands
authenticationToken = receive.substring(ReturnCode.OK.length() + 1);
} else {
this.username = null;
// Should never happen
throw new InvalidLoginException();
}
}
/**
* Constructor that allows to define a proxy
*
*
* @param url
* the URL of the path to the AwakeFileManager Servlet can be
* null only if we call downloadUrl(URL url, File file)
* @param username
* the username for authentication on the Awake Server
* @param password
* the user password for authentication on the Awake Server
* @param httpProxy
* the proxy to use (null if none)
*
* @throws MalformedURLException
* if the url is null or malformed
* @throws IllegalArgumentException
* if username or password is null
* @throws UnknownHostException
* if Host url (http://www.acme.org) does not exists or no
* Internet Connection..
* @throws ConnectException
* if the Host is correct but the AwakeFileManager Servlet is
* not reachable (http://www.acme.org/AwakeFileManager) and
* access failed with a status != OK (200). (If the host is
* incorrect, or is impossible to connect to - Tomcat down - the
* ConnectException will be the sub exception
* HttpHostConnectException.)
* @throws RemoteException
* an exception has been thrown on the server side
* @throws SecurityException
* the url is not secured with https (SSL)
* @throws IOException
* For all other IO / Network / System Error
*/
public AwakeFileSessionNew(String url, String username, char[] password,
HttpProxy httpProxy) throws IllegalArgumentException,
MalformedURLException, UnknownHostException, ConnectException,
InvalidLoginException, RemoteException, IOException {
this(url, username, password);
this.httpProxy = httpProxy;
}
/**
* Constructor that allows to define a proxy and protocol parameters
*
*
* @param url
* the URL of the path to the AwakeFileManager Servlet can be
* null only if we call downloadUrl(URL url, File file)
* @param username
* the username for authentication on the Awake Server
* @param password
* the user password for authentication on the Awake Server
* @param httpProxy
* the proxy to use (null if none)
* @param httpProtocolParameters
* the http protocol parameters to set
*
* @throws MalformedURLException
* if the url is null or malformed
* @throws IllegalArgumentException
* if username or password is null
* @throws UnknownHostException
* if Host url (http://www.acme.org) does not exists or no
* Internet Connection..
* @throws ConnectException
* if the Host is correct but the AwakeFileManager Servlet is
* not reachable (http://www.acme.org/AwakeFileManager) and
* access failed with a status != OK (200). (If the host is
* incorrect, or is impossible to connect to - Tomcat down - the
* ConnectException will be the sub exception
* HttpHostConnectException.)
* @throws RemoteException
* an exception has been thrown on the server side
* @throws SecurityException
* the url is not secured with https (SSL)
* @throws IOException
* For all other IO / Network / System Error
*/
public AwakeFileSessionNew(String url, String username, char[] password,
HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters)
throws IllegalArgumentException, MalformedURLException,
UnknownHostException, ConnectException, InvalidLoginException,
RemoteException,
IOException {
this(url, username, password, httpProxy);
this.httpProtocolParameters = httpProtocolParameters;
}
/**
* @return the username
*/
String getUsername() {
return this.username;
}
/**
* Returns the HttpProtocolParameters instance in use for the Awake FILE
* session.
*
* @return the HttpProtocolParameters instance in use for the Awake FILE
* session
*/
HttpProtocolParameters getHttpProtocolParameters() {
return this.httpProtocolParameters;
}
/**
* Returns the URL of the path to the AwakeFileManager Servlet (or
* AwakeSqlManager Servlet if session has been initiated by an
* AwakeConnection).
*
* @return the URL of the path to the AwakeFileManager Servlet
*/
String getUrl() {
return url;
}
/**
* Returns the HttpProxy instance in use for this Awake session.
*
* @return the HttpProxy instance in use for this Awake session
*/
HttpProxy getHttpProxy() {
return this.httpProxy;
}
/**
* Returns the http status code of the last executed verb
*
* @return the http status code of the last executed verb
*/
public int getStatusCode() {
if (httpTransfer != null) {
return httpTransfer.getHttpStatusCode();
} else {
return 0;
}
}
/**
* Returns the Authentication Token. This method is used by other Awake
* products (Awake SQL, ...)
*
* @return the Authentication Token
*/
public String getAuthenticationToken() {
return this.authenticationToken;
}
/**
* Logs off from the remote host. This will purge the authentication
* values necessary for method calls.
*
* Method should be called at the closure of the Client application.
*/
public void logoff() {
username = null;
authenticationToken = null;
httpProxy = null;
httpProtocolParameters = null;
//awakeProgressManager = null;
if (httpTransfer != null) {
httpTransfer.close();
}
}
/**
* Calls a remote Java class.method and (eventually) pass some parameters to
* it.
*
* @param methodName
* the full method name to call in the format
* org.acme.config.package.MyClass.myMethod
* @param params
* the array of parameters passed to the method
* @return the result of the Java call as string
*
* @throws IllegalArgumentException
* if methodName is null
* @throws InvalidLoginException
* if the username is refused by the remote host
*
* @throws UnknownHostException
* if Host url (http://www.acme.org) does not exists or no
* Internet Connection.
* @throws ConnectException
* if the Host is correct but the AwakeFileManager Servlet is
* not reachable (http://www.acme.org/AwakeFileManager) and
* access failed with a status != OK (200). (If the host is
* incorrect, or is impossible to connect to - Tomcat down - the
* ConnectException will be the sub exception
* HttpHostConnectException.)
* @throws RemoteException
* an exception has been thrown on the server side
* @throws SecurityException
* the url is not secured with https (SSL)
* @throws IOException
* For all other IO / Network / System Error
*
*/
public String call(String methodName, Object... params)
throws IllegalArgumentException, InvalidLoginException,
UnknownHostException, ConnectException, RemoteException,
IOException {
// Class and method name can not be null
if (methodName == null) {
throw new IllegalArgumentException("methodName can not be null!");
}
// username & Authentication Token may be null
// because some methods can be called freely
if (username == null) {
username = "null";
}
if (authenticationToken == null) {
authenticationToken = "null";
}
// Build the params types
List paramsTypes = new Vector();
// Build the params values
List paramsValues = new Vector();
debug("");
for (int i = 0; i < params.length; i++) {
String classType = params[i].getClass().getName();
paramsTypes.add(classType);
String value = params[i].toString();
debug("");
debug("classType: " + classType);
debug("value : " + value);
paramsValues.add(value);
}
// ListHolder listHolderTypes = new ListHolder();
// listHolderTypes.setList(paramsTypes);
String jsonParamTypes = ListOfStringTransport.toJson(paramsTypes);
// ListHolder listHolderValues = new ListHolder();
// listHolderValues.setList(paramsValues);
String jsonParamValues = ListOfStringTransport.toJson(paramsValues);
debug("methodName : " + methodName);
debug("jsonParamTypes : " + jsonParamTypes);
debug("jsonParamValues: " + jsonParamValues);
// httpTransfer = new HttpTransferOne(url, httpProxy,
// httpProtocolParameters, null);
// Prepare the request parameters
List requestParams = new Vector();
requestParams.add(new BasicNameValuePair(Parameter.ACTION,
Action.CALL_ACTION));
requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username));
requestParams.add(new BasicNameValuePair(Parameter.TOKEN,
authenticationToken));
requestParams.add(new BasicNameValuePair(Parameter.METHOD_NAME,
methodName));
requestParams.add(new BasicNameValuePair(Parameter.PARAMS_TYPES, jsonParamTypes));
requestParams.add(new BasicNameValuePair(Parameter.PARAMS_VALUES, jsonParamValues));
httpTransfer.send(requestParams);
// Return the answer
String response = httpTransfer.recv();
debug("response: " + response);
// Possible values retured by awake Server
// public static final String ClassNotFoundException =
// "ClassNotFoundException";
// public static final String InstantiationException =
// "InstantiationException";
// public static final String NoSuchMethodException =
// "NoSuchMethodException";
// public static final String InvocationTargetException=
// "InvocationTargetException";
// public static final String AwakeSecurityException =
// "AwakeSecurityException";
// public static final String IllegalArgumentException =
// "IllegalArgumentException";
// The response is in Base 64
try {
if (!response.isEmpty()) {
response = StringUtil.fromBase64(response);
}
} catch (Exception e) {
// May happen till new Awake FILE is not deployed on Server
throw new IOException(Tag.AWAKE_PRODUCT_FAIL
+ "Response must be and is not base64!", e);
}
return response;
}
/**
* Returns the Awake FILE Version.
*
* @return the Awake FILE Version
*/
public String getVersion() {
return AwakeFileVersion.getVersion();
}
/**
* debug tool
*/
private void debug(String s) {
if (DEBUG) {
AwakeServerLogger.log(s);
}
}
}
// End