| TaskServer |
/*--
This file is a part of ZetaGrid, a simple and secure Grid Computing
kernel.
Copyright (c) 2001-2004 Sebastian Wedeniwski. All rights reserved.
Use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. The source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you plan to
use this software in a product, please contact the author.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software. The author
must be informed about these changes.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Version 1.9.0, February 8, 2004
This program is based on the work of:
S. Wedeniwski
W. Westje
--*/
package zeta;
import java.io.IOException;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpUtils;
import zeta.crypto.Decrypter;
import zeta.crypto.KeyManager;
import zeta.processor.TaskRequestWorkUnitProcessor;
import zeta.processor.TaskResultProcessor;
import zeta.util.Base64;
import zeta.util.DatabaseUtils;
/**
* Defines the task at the server side.
**/
public class TaskServer {
/**
* The method <code>getTask</code> must be used.
* @param id ID of the task
* @param name name of the task
* @param parameters parameters of the HttpRequest
**/
private TaskServer(int id, String name, Map parameter) {
this.id = id;
this.name = name;
this.parameter = parameter;
}
private TaskServer(TaskServer taskServer, ZetaServlet servlet, Map parameter) {
id = taskServer.id;
name = taskServer.name;
encryptionClass = taskServer.encryptionClass;
encryptionSignature = taskServer.encryptionSignature;
decryptionNumber = taskServer.decryptionNumber;
if (taskServer.requestProcessor != null) {
requestProcessor = getRequestProcessor(servlet, null, taskServer.requestProcessor.getClass().getName(), parameter); // ToDo: set Statement
}
if (taskServer.resultProcessor != null) {
resultProcessor = getResultProcessor(servlet, null, taskServer.resultProcessor.getClass().getName(), parameter); // ToDo: set Statement
}
this.parameter = parameter;
}
/**
* Returns the task object of a specified task name.
* @param servlet surrounding servlet
* @param parameters parameters of the HttpRequest; the parameters must contains the task name at the key 'task'
* @return the task object of a specified task ID if it is defined, otherwise <code>null</code>.
* @exception SQLException if a database access error occurs.
**/
public static TaskServer getTask(ZetaServlet servlet, Map parameter) throws ServletException, SQLException {
if (parameter == null) {
throw new IllegalArgumentException("The parameters of the HttpRequest must be specified!");
}
// check if URL is encrypted
String[] values = (String[])parameter.get("param");
if (values != null && values.length > 0 && values[0] != null && values[0].length() > 0) {
try {
Decrypter decrypter = new Decrypter(KeyManager.getEncryptorKey(null));
String s = decrypter.decryptURLFile(values[0], getDefaultDecryptionNumber(servlet));
if (s != null) {
parameter = HttpUtils.parseQueryString(s);
}
} catch (IOException ioe) {
}
}
values = (String[])parameter.get("task");
if (values == null || values.length == 0) {
throw new IllegalArgumentException("No task is defined in the HttpRequest");
}
String taskName = values[0];
if (taskName == null || taskName.length() == 0) {
throw new IllegalArgumentException("No valid task is defined in the HttpRequest");
}
synchronized (mapTask) {
TaskServer task = (TaskServer)mapTask.get(taskName);
if (task == null) {
Connection con = null;
Statement stmt = null;
try {
con = servlet.getConnection();
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id,encryption_class,encryption_signature,decryption_number,request_processor,result_processor FROM zeta.task WHERE name='" + taskName + '\'');
if (rs.next()) {
task = new TaskServer(rs.getInt(1), taskName, parameter);
task.encryptionClass = Base64.decode(rs.getString(2));
task.encryptionSignature = rs.getString(3);
task.decryptionNumber = new BigInteger(rs.getString(4), 32);
String requestProcessorName = rs.getString(5);
String resultProcessorName = rs.getString(6);
rs.close();
task.requestProcessor = getRequestProcessor(servlet, stmt, requestProcessorName, parameter);
task.resultProcessor = getResultProcessor(servlet, stmt, resultProcessorName, parameter);
mapTask.put(taskName, task);
} else {
rs.close();
}
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(con);
}
} else {
task = new TaskServer(task, servlet, parameter);
}
return task;
}
}
/**
* Returns the ID of the task.
* @return the ID of the task.
**/
public int getId() {
return id;
}
/**
* Returns the unique name of the task.
* @return the unique name of the task.
**/
public String getName() {
return name;
}
/**
* Returns the bytes that make up the class data which contains the key to encrypt the results of this task.
* @return the bytes that make up the class data which contains the key to encrypt the results of this task.
**/
public byte[] getEncryptionClass() {
return encryptionClass;
}
/**
* Returns the digital signature (big integer radix 32) of the class name which contains the key to encrypt the results of this task.
* @return the digital signature (big integer radix 32) of the class name which contains the key to encrypt the results of this task.
**/
public String getEncryptionSignature() {
return encryptionSignature;
}
/**
* Returns the decryption number for the Decryptor (half-certified Diffie-Hellman protocol).
* @return the decryption number for the Decryptor (half-certified Diffie-Hellman protocol).
**/
public BigInteger getDecryptionNumber() {
return decryptionNumber;
}
/**
* Returns an object which processes the request for work units of the task.
* @return an object which processes the request for work units of the task or <code>null</null> if it is not defined.
**/
public TaskRequestWorkUnitProcessor getRequestWorkUnitProcessor() {
return requestProcessor;
}
/**
* Returns an object which processes the task results.
* @return an object which processes the task results or <code>null</null> if it is not defined.
**/
public TaskResultProcessor getResultProcessor() {
return resultProcessor;
}
/**
* Returns the decrypted parameters of the HttpRequest.
* @return the decrypted parameters of the HttpRequest.
**/
public Map getParameter() {
return parameter;
}
/**
* Returns a value for a key from the specified map with parameters.
* @param key key
* @return value for a key from the specified map with parameters; <code>null</code> if no value was found.
**/
public String getParameter(String key) {
String[] values = (String[])parameter.get(key);
return (values == null || values.length == 0)? null : values[0];
}
/**
* Returns an object for the specified class name which processes the request for work units of the task.
* @param servlet surrounding servlet
* @param stmt statement object's database
* @param requestProcessorName class name which processes the request for work units of the task
* @param parameters parameters of the HttpRequest
* @return an object for the specified class name which processes the request for work units of the task or <code>null</null> if the class is not defined.
**/
private static TaskRequestWorkUnitProcessor getRequestProcessor(ZetaServlet servlet, Statement stmt, String requestProcessorName, Map parameter) {
TaskRequestWorkUnitProcessor processor = null;
if (requestProcessorName != null) {
try {
Class requestProcessorClass = Class.forName(requestProcessorName);
processor = (TaskRequestWorkUnitProcessor)requestProcessorClass.newInstance();
processor.init(servlet, stmt, parameter);
} catch (Exception e) {
}
}
return processor;
}
/**
* Returns an object for the specified class name which processes the task results.
* @param servlet surrounding servlet
* @param stmt statement object's database
* @param resultProcessorName class name which processes the task results
* @param parameters parameters of the HttpRequest
* @return an object for the specified class name which processes the task results or <code>null</null> if the class is not defined.
**/
private static TaskResultProcessor getResultProcessor(ZetaServlet servlet, Statement stmt, String resultProcessorName, Map parameter) {
TaskResultProcessor processor = null;
if (resultProcessorName != null) {
try {
Class resultProcessorClass = Class.forName(resultProcessorName);
processor = (TaskResultProcessor)resultProcessorClass.newInstance();
processor.init(servlet, stmt, parameter);
} catch (Exception e) {
}
}
return processor;
}
/**
* Returns the default decryption number for the half-certified Diffie-Hellman protocol.
* @param servlet surrounding servlet
* @return the default decryption number for the half-certified Diffie-Hellman protocol.
* @exception SQLException if a database access error occurs.
**/
private static BigInteger getDefaultDecryptionNumber(ZetaServlet servlet) throws ServletException, SQLException {
if (defaultDecryptionNumber == null) {
Connection con = null;
Statement stmt = null;
try {
con = servlet.getConnection();
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT decryption_number FROM zeta.task WHERE id=0");
if (rs.next()) {
defaultDecryptionNumber = new BigInteger(rs.getString(1), 32);
}
rs.close();
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(con);
}
}
return defaultDecryptionNumber;
}
/**
* ID of the task.
**/
private int id;
/**
* The unique name of the task.
**/
private String name;
/**
* The bytes that make up the class data which contains the key to encrypt the results of this task.
**/
private byte[] encryptionClass;
/**
* Digital signature of the class name which contains the key to encrypt the results of this task.
* A big integer radix 32.
**/
private String encryptionSignature;
/**
* Decryption number for the Decryptor (half-certified Diffie-Hellman protocol).
**/
private BigInteger decryptionNumber;
/**
* An object which processes the request for work units of the task.
**/
private TaskRequestWorkUnitProcessor requestProcessor;
/**
* An object for the specified class name which processes the task results.
**/
private TaskResultProcessor resultProcessor;
/**
* Parameters of the HttpRequest.
**/
private Map parameter;
/**
* Maps a task name on a task.
**/
private static Map mapTask = new HashMap();
/**
* The default decryption number for the half-certified Diffie-Hellman protocol.
**/
private static BigInteger defaultDecryptionNumber = null;
}
| TaskServer |