package zeta.handler;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpUtils;
import zeta.TaskServer;
import zeta.WorkUnit;
import zeta.ZetaServlet;
import zeta.processor.TaskRequestWorkUnitProcessor;
import zeta.util.Base64;
import zeta.util.CachedQueries;
import zeta.util.DatabaseUtils;
import zeta.util.Parameter;
public class RequestWorkUnitHandler implements GetHandler {
public RequestWorkUnitHandler(ZetaServlet servlet) {
this.servlet = servlet;
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, SQLException, IOException {
TaskServer task = TaskServer.getTask(servlet, HttpUtils.parseQueryString(req.getQueryString()));
if (task == null) {
servlet.log("no valid task is defined.");
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
return;
}
String user = DatabaseUtils.encodeName(task.getParameter("user"));
if (user == null) { resp.setContentType("text/plain");
resp.setContentLength(0);
resp.getOutputStream().print("");
return;
}
user = user.trim();
if (user.length() == 0) { resp.setContentType("text/plain");
resp.setContentLength(0);
resp.getOutputStream().print("");
return;
}
if (user.equalsIgnoreCase("anonymous")) {
user = "anonymous";
}
String eMail = task.getParameter("email");
if (eMail == null) {
eMail = "";
}
eMail = eMail.toLowerCase();
String receiveMessages = task.getParameter("messages");
if (receiveMessages != null) {
receiveMessages = receiveMessages.equals("true")? "Y" : "N";
}
String team = task.getParameter("team");
String hostname = task.getParameter("hostname");
if (hostname == null) {
resp.setContentType("text/plain");
resp.setContentLength(0);
resp.getOutputStream().print("");
return;
}
hostname = hostname.toLowerCase();
String hostaddr = task.getParameter("hostaddr");
String key = task.getParameter("key");
if (key != null && key.length() > 0) {
key = new String(Base64.decode(key), "UTF-8");
if (key.length() > 200) {
key = key.substring(0, 200);
}
key = key.toLowerCase();
}
String taskName = task.getParameter("task");
String sizeOfWorkUnit = task.getParameter("size");
String version = task.getParameter("version");
String osName = task.getParameter("os_name");
if (osName == null) {
osName = "";
}
String osVersion = task.getParameter("os_version");
if (osVersion == null) {
osVersion = "";
}
String osArch = task.getParameter("os_arch");
if (osArch == null) {
osArch = "";
}
int processors = 1;
try {
processors = Integer.parseInt(task.getParameter("processors"));
} catch (Exception e) {
processors = 1;
}
int numberOfWorkUnits = 1;
try {
numberOfWorkUnits = Integer.parseInt(task.getParameter("work_units"));
} catch (Exception e) {
numberOfWorkUnits = 1;
}
Connection con = null;
Statement stmt = null;
try {
con = servlet.getConnection();
stmt = con.createStatement();
int taskId = task.getId();
int serverId = servlet.getServerId();
int userId = 0;
int fail = 0;
int trust = 0;
String teamName = null;
String emailValid = receiveMessages;
List searchKey = new ArrayList(3);
searchKey.add(new Integer(serverId));
searchKey.add(user);
searchKey.add(eMail);
boolean valueCached = true;
Object[] value = (Object[])userMap.get(searchKey);
if (value == null) {
ResultSet rs = stmt.executeQuery("SELECT id,fail,trust,email_valid_YN,team_name FROM zeta.user WHERE server_id=" + serverId + " AND name='" + user + "' AND email='" + eMail + '\'');
if (rs.next()) {
valueCached = false;
userId = rs.getInt(1);
fail = rs.getInt(2);
trust = rs.getInt(3);
emailValid = rs.getString(4);
teamName = rs.getString(5);
rs.close();
} else {
rs.close();
teamName = team;
synchronized (RequestWorkUnitHandler.class) {
rs = stmt.executeQuery("SELECT MAX(id) FROM zeta.user WHERE server_id=" + serverId);
userId = (rs.next())? rs.getInt(1)+1 : 1;
rs.close();
if (team != null) {
DatabaseUtils.executeAndLogUpdate(servlet,
"INSERT INTO zeta.user (id,server_id,name,email,email_valid_YN,team_name,join_in_team) VALUES ("
+ userId + ',' + serverId + ",'" + user + "','" + eMail + "','" + ((receiveMessages == null || receiveMessages.equals("Y"))? 'Y' : 'N') + "','"
+ team + "',CURRENT TIMESTAMP)");
} else {
DatabaseUtils.executeAndLogUpdate(servlet,
"INSERT INTO zeta.user (id,server_id,name,email,email_valid_YN) VALUES ("
+ userId + ',' + serverId + ",'" + user + "','" + eMail + "','" + ((receiveMessages == null || receiveMessages.equals("Y"))? 'Y' : 'N') + "')");
}
}
}
userMap.put(searchKey, new Object[] { new Integer(userId), new Integer(fail), new Integer(trust), emailValid, teamName });
} else {
userId = ((Integer)value[0]).intValue();
fail = ((Integer)value[1]).intValue();
trust = ((Integer)value[2]).intValue();
emailValid = (String)value[3];
teamName = (String)value[4];
}
numberOfWorkUnits = Math.max(numberOfWorkUnits, 1);
if (trust >= 2 && numberOfWorkUnits > MAX_WORK_UNITS_TRUST2) {
numberOfWorkUnits = MAX_WORK_UNITS_TRUST2;
} else if (trust == 1 && numberOfWorkUnits > MAX_WORK_UNITS_TRUST1) {
numberOfWorkUnits = MAX_WORK_UNITS_TRUST1;
} else if (trust == 0 && numberOfWorkUnits > MAX_WORK_UNITS_TRUST0) {
numberOfWorkUnits = MAX_WORK_UNITS_TRUST0;
}
int originNumberOfWorkUnits = numberOfWorkUnits;
int workstationId = 0;
if (key != null && key.length() > 0) {
ResultSet rs = stmt.executeQuery("SELECT id,processors_approved FROM zeta.workstation WHERE server_id=" + serverId + " AND key='" + key + '\'');
if (rs.next()) {
workstationId = rs.getInt(1);
int processorsApproved = rs.getInt(2);
if (processorsApproved > numberOfWorkUnits) {
numberOfWorkUnits = processorsApproved;
}
}
rs.close();
}
if (workstationId == 0) {
searchKey.clear();
searchKey.add(new Integer(serverId));
searchKey.add(new Integer(userId));
List workstationList = (List)workstationMap.get(searchKey);
if (workstationList == null) {
workstationList = new ArrayList(3);
ResultSet rs = stmt.executeQuery("SELECT DISTINCT workstation_id FROM zeta.computation WHERE server_id=" + serverId + " AND user_id=" + userId);
while (rs.next()) {
workstationList.add(new Integer(rs.getInt(1)));
}
rs.close();
workstationMap.put(searchKey, workstationList);
}
int l = workstationList.size();
if (l > 0) {
StringBuffer buffer = new StringBuffer(1000);
buffer.append("SELECT id,processors_approved,key FROM zeta.workstation WHERE server_id=");
buffer.append(serverId);
buffer.append(" AND hostname='");
buffer.append(hostname);
buffer.append("' AND id IN (");
for (int i = 0; i < l; ++i) {
if (i > 0) {
buffer.append(',');
}
buffer.append(workstationList.get(i));
}
buffer.append(')');
int idx = buffer.length();
buffer.append(" AND hostaddress='");
buffer.append(hostaddr);
buffer.append('\'');
ResultSet rs = stmt.executeQuery(buffer.toString());
if (rs.next()) {
workstationId = rs.getInt(1);
int processorsApproved = rs.getInt(2);
String workstationKey = rs.getString(3);
rs.close();
if (processorsApproved > numberOfWorkUnits) {
numberOfWorkUnits = processorsApproved;
}
if (key != null && !key.equals(workstationKey)) {
stmt.executeUpdate("UPDATE zeta.workstation SET key='" + key + "' WHERE server_id=" + serverId + " AND id=" + workstationId);
}
} else {
rs.close();
buffer.delete(idx, buffer.length());
rs = stmt.executeQuery(buffer.toString());
if (rs.next()) { workstationId = rs.getInt(1);
int processorsApproved = rs.getInt(2);
String workstationKey = rs.getString(3);
rs.close();
if (processorsApproved > numberOfWorkUnits) {
numberOfWorkUnits = processorsApproved;
}
if (key != null && !key.equals(workstationKey)) {
stmt.executeUpdate("UPDATE zeta.workstation SET (key,hostaddress)=('" + key + "','" + hostaddr + "') WHERE server_id=" + serverId + " AND id=" + workstationId);
} else {
stmt.executeUpdate("UPDATE zeta.workstation SET hostaddress='" + hostaddr + "' WHERE server_id=" + serverId + " AND id=" + workstationId);
}
} else {
rs.close();
l = 0;
}
}
}
if (l == 0) { synchronized (RequestWorkUnitHandler.class) {
ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM zeta.workstation WHERE server_id=" + serverId);
workstationId = (rs.next())? rs.getInt(1) : 0;
workstationList.add(new Integer(++workstationId));
rs.close();
if (key != null) {
long lastUpdate = GetClientHandler.getKeyTimestamp(key);
if (lastUpdate > 0) {
DatabaseUtils.executeAndLogUpdate(servlet,
"INSERT INTO zeta.workstation (id,server_id,key,hostname,hostaddress,os_name,os_version,os_arch,processors,last_update) VALUES ("
+ workstationId + ',' + serverId + ",'" + key + "','" + hostname + "','" + hostaddr
+ "','" + osName + "','" + osVersion + "','" + osArch + "'," + processors + ",'" + (new Timestamp(lastUpdate)) + "')");
} else {
DatabaseUtils.executeAndLogUpdate(servlet,
"INSERT INTO zeta.workstation (id,server_id,key,hostname,hostaddress,os_name,os_version,os_arch,processors) VALUES ("
+ workstationId + ',' + serverId + ",'" + key + "','" + hostname + "','" + hostaddr
+ "','" + osName + "','" + osVersion + "','" + osArch + "'," + processors + ')');
}
} else {
DatabaseUtils.executeAndLogUpdate(servlet,
"INSERT INTO zeta.workstation (id,server_id,hostname,hostaddress,os_name,os_version,os_arch,processors) VALUES ("
+ workstationId + ',' + serverId + ",'" + hostname + "','" + hostaddr
+ "','" + osName + "','" + osVersion + "','" + osArch + "'," + processors + ')');
}
}
}
}
TaskRequestWorkUnitProcessor processor = task.getRequestWorkUnitProcessor();
if (processor == null) {
servlet.log("could not resolve request work unit processor for task ID: " + taskId + ").");
throw new ServletException("Could not resolve request work unit processor for task ID: " + taskId + ").");
}
long workUnitIdComplete = Parameter.getValue(stmt, "work_unit_id_complete", taskId, 0, 3600000);
final long workUnitIdOverlap = Parameter.getValue(stmt, "work_unit_id_overlap", taskId, 0, 3600000);
Set activeWorkUnits = new TreeSet();
ResultSet rs = stmt.executeQuery("SELECT work_unit_id FROM zeta.computation WHERE task_id=" + taskId
+ " AND work_unit_id>=" + (workUnitIdComplete-2*workUnitIdOverlap)
+ " AND server_id=" + serverId
+ " AND workstation_id=" + workstationId);
while (rs.next()) {
activeWorkUnits.add(new Long(rs.getLong(1)));
}
rs.close();
int sz;
Iterator iter;
do {
sz = activeWorkUnits.size();
iter = activeWorkUnits.iterator();
StringBuffer buffer = new StringBuffer(4000);
buffer.append("SELECT work_unit_id FROM zeta.result WHERE task_id=");
buffer.append(taskId);
buffer.append(" AND work_unit_id IN (");
if (iter.hasNext()) {
buffer.append(iter.next());
for (int j = 0; j < 250 && iter.hasNext(); ++j) {
buffer.append(',');
buffer.append(iter.next());
}
buffer.append(')');
rs = stmt.executeQuery(buffer.toString());
while (rs.next()) {
activeWorkUnits.remove(new Long(rs.getLong(1)));
}
rs.close();
}
} while (iter.hasNext() && activeWorkUnits.size() > 0 && sz > activeWorkUnits.size());
WorkUnit[] workUnits = null;
WorkUnit[] workUnitsAll = null;
if (numberOfWorkUnits > 0) {
workUnits = new WorkUnit[numberOfWorkUnits];
workUnitsAll = new WorkUnit[numberOfWorkUnits];
}
if (numberOfWorkUnits > 0 && activeWorkUnits.size() > 0) {
StringBuffer buffer = new StringBuffer(2000);
buffer.append("SELECT work_unit_id,range FROM zeta.computation WHERE task_id=");
buffer.append(taskId);
buffer.append(" AND work_unit_id IN (");
iter = activeWorkUnits.iterator();
buffer.append(iter.next());
while (iter.hasNext()) {
buffer.append(',');
buffer.append(iter.next());
}
buffer.append(") ORDER BY start,work_unit_id"); rs = stmt.executeQuery(buffer.toString());
while (numberOfWorkUnits > 0 && rs.next()) {
--numberOfWorkUnits;
workUnitsAll[numberOfWorkUnits] = processor.getWorkUnit(taskId, rs.getLong(1), rs.getInt(2));
}
rs.close();
}
if (numberOfWorkUnits > 0) {
synchronized (RequestWorkUnitHandler.class) {
rs = stmt.executeQuery("SELECT work_unit_id,range FROM zeta.recomputation WHERE task_id=" + taskId
+ " AND server_id=" + serverId
+ " AND (start IS NULL AND (workstation_id IS NULL OR workstation_id=" + workstationId + ") AND " + userId
+ " IN (" + CachedQueries.getUsersForRecomputation(stmt, serverId)
+ " ) OR stop IS NULL AND user_id=" + userId
+ " AND workstation_id=" + workstationId + ") ORDER BY start,work_unit_id"); int size = DEFAULT_WORK_UNIT_SIZE;
long workUnitId = 0;
if (rs.next()) {
StringBuffer where = new StringBuffer(100);
do {
--numberOfWorkUnits;
workUnitId = rs.getLong(1);
size = rs.getInt(2);
workUnitsAll[numberOfWorkUnits] = processor.getWorkUnit(taskId, workUnitId, size);
if (where.length() > 0) {
where.append(',');
}
where.append(workUnitId);
} while (numberOfWorkUnits > 0 && rs.next());
rs.close();
DatabaseUtils.executeAndLogUpdate(servlet,
"UPDATE zeta.recomputation SET (version,workstation_id,user_id,start)=('" + version
+ "'," + workstationId + ',' + userId + ",CURRENT TIMESTAMP) WHERE task_id=" + taskId
+ " AND server_id=" + serverId + " AND work_unit_id IN (" + where.toString() + ')');
} else rs.close();
if (fail > 0) {
numberOfWorkUnits = (originNumberOfWorkUnits == numberOfWorkUnits)? 1 : 0;
}
if (numberOfWorkUnits == 1) { String minFillGaps = Parameter.getValue(stmt, "min_fill_gaps", taskId, "", 3600000);
if (minFillGaps.length() > 0) {
String maxFillGaps = Parameter.getValue(stmt, "max_fill_gaps", taskId, "", 3600000);
Statement stmt2 = null;
try {
stmt2 = con.createStatement();
rs = stmt.executeQuery("SELECT work_unit_id,range FROM zeta.server_range WHERE server_id=" + serverId
+ " AND task_id=" + taskId + " AND work_unit_id between " + minFillGaps + " and " + maxFillGaps
+ " ORDER BY work_unit_id");
while (rs.next()) {
long serverMaxWorkUnitId = rs.getLong(1);
long serverMaxWorkUnitIdEnd = serverMaxWorkUnitId+rs.getLong(2);
ResultSet rs2 = stmt2.executeQuery("SELECT MAX(work_unit_id)"
+ " FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id>=" + serverMaxWorkUnitId
+ " AND work_unit_id<" + (serverMaxWorkUnitIdEnd-workUnitIdOverlap));
if (rs2.next()) {
long max = rs2.getLong(1);
rs2.close();
rs2 = stmt2.executeQuery("SELECT range FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id=" + max);
if (rs2.next()) {
max += rs2.getInt(1);
if (max < serverMaxWorkUnitIdEnd) {
workUnitId = (max > serverMaxWorkUnitId)? max-workUnitIdOverlap : max;
size = getWorkUnitSize(taskId, sizeOfWorkUnit, workUnitId, stmt);
int size2 = (serverMaxWorkUnitIdEnd < workUnitId+size)? ((int)(serverMaxWorkUnitIdEnd-workUnitId+workUnitIdOverlap)) : size;
--numberOfWorkUnits;
workUnitsAll[numberOfWorkUnits] = workUnits[numberOfWorkUnits] = processor.getWorkUnit(taskId, workUnitId, size2);
break;
}
}
}
rs2.close();
}
rs.close();
} finally {
DatabaseUtils.close(stmt2);
}
}
}
if (numberOfWorkUnits > 0) {
long[] serverMaxWorkUnitId = null;
while (true) {
serverMaxWorkUnitId = Parameter.getServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
rs = stmt.executeQuery("SELECT MAX(work_unit_id+range-" + workUnitIdOverlap
+ ") FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id+range>=" + serverMaxWorkUnitId[0]
+ " AND work_unit_id+range<=" + (serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1]));
if (rs.next()) {
workUnitId = rs.getLong(1);
if (workUnitId == 0 && rs.wasNull()) {
rs.close();
workUnitId = Parameter.newServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
if (workUnitId > 0) {
break;
}
} else if (workUnitId+size >= serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1]) {
rs.close();
rs = stmt.executeQuery("SELECT MAX(work_unit_id) FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id+range>=" + serverMaxWorkUnitId[0]
+ " AND work_unit_id<" + (serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1]-workUnitIdOverlap));
if (rs.next() && rs.getLong(1) == workUnitId) {
rs.close();
workUnitId = Parameter.newServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
if (workUnitId > 0) {
break;
}
} else {
rs.close();
break;
}
} else {
rs.close();
break;
}
} else {
rs.close();
workUnitId = Parameter.newServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
if (workUnitId > 0) {
break;
}
}
}
size = getWorkUnitSize(taskId, sizeOfWorkUnit, workUnitId, stmt);
do {
if (serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1] <= workUnitId) {
Parameter.newServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
serverMaxWorkUnitId = Parameter.getServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
}
int size2 = size;
if (serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1] < workUnitId+size) {
size2 = (int)(serverMaxWorkUnitId[0]+serverMaxWorkUnitId[1]-workUnitId+workUnitIdOverlap);
Parameter.newServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
serverMaxWorkUnitId = Parameter.getServerMaxWorkUnitId(servlet, stmt, serverId, taskId);
}
workUnitsAll[numberOfWorkUnits-1] = workUnits[numberOfWorkUnits-1] = processor.getWorkUnit(taskId, workUnitId, size2);
int r = processor.activateWorkUnit(stmt, workUnits[numberOfWorkUnits-1]);
if (r < 0) {
resp.setContentType("text/plain");
resp.setContentLength(0);
resp.getOutputStream().print("");
return;
} else if (r == 0) {
numberOfWorkUnits = 1;
}
workUnitId += (size == size2)? size-workUnitIdOverlap : size2;
} while (--numberOfWorkUnits > 0);
}
}
}
if (workUnits != null && workUnitsAll != null) {
insertWorkUnitsIntoDatabase(workUnits, processor, taskId, serverId, workstationId, version, userId);
StringBuffer response = new StringBuffer(85*workUnits.length);
for (int i = workUnitsAll.length-1; i >= 0; --i) {
if (workUnitsAll[i] != null && workUnitsAll[i].isValid()) {
response.append(workUnitsAll[i].writeObject());
}
}
resp.setContentType("text/plain");
resp.setContentLength(response.length());
resp.getOutputStream().print(response.toString());
} else {
resp.setContentType("text/plain");
resp.setContentLength(0);
resp.getOutputStream().print("");
}
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(con);
}
}
private void insertWorkUnitsIntoDatabase(WorkUnit[] workUnits, TaskRequestWorkUnitProcessor processor, int taskId, int serverId,int workstationId, String version, int userId) throws ServletException, SQLException {
StringBuffer sql = new StringBuffer(150*workUnits.length+120);
for (int i = workUnits.length-1; i >= 0; --i) {
if (workUnits[i] != null && workUnits[i].isValid()) {
if (sql.length() == 0) {
sql.append("INSERT INTO zeta.computation (task_id,work_unit_id,range,server_id,workstation_id,user_id,version,start,parameters) VALUES (");
} else {
sql.append(",(");
}
sql.append(taskId);
sql.append(',');
sql.append(workUnits[i].getWorkUnitId());
sql.append(',');
sql.append(workUnits[i].getSize());
sql.append(',');
sql.append(serverId);
sql.append(',');
sql.append(workstationId);
sql.append(',');
sql.append(userId);
sql.append(",'");
sql.append(version);
sql.append("',CURRENT_TIMESTAMP,");
String parameters = processor.getParameters(workUnits[i]);
if (parameters == null) {
sql.append("NULL");
} else {
sql.append('\'');
sql.append(DatabaseUtils.encodeName(parameters));
sql.append('\'');
}
sql.append(')');
}
}
if (sql.length() > 0) {
DatabaseUtils.executeAndLogUpdate(servlet, sql.toString());
}
}
private int getWorkUnitSize(int taskId, String sizeOfWorkUnit, long workUnitId, Statement stmt) throws SQLException {
String search = Integer.toString(taskId) + ':' + sizeOfWorkUnit;
List sizes = (List)workUnitSize.get(search);
if (sizes != null) {
final int l = sizes.size()-1;
for (int i = 0; i < l; i += 2) {
if (((Long)sizes.get(i)).longValue() <= workUnitId) {
return ((Long)sizes.get(i+1)).intValue();
}
}
}
ResultSet rs = stmt.executeQuery("SELECT work_unit_id,range FROM zeta.work_unit_size WHERE task_id=" + taskId + " AND size='" + sizeOfWorkUnit + "' ORDER BY work_unit_id DESC");
if (rs.next()) {
sizes = new ArrayList(20);
sizes.add(new Long(rs.getLong(1)));
Long size = new Long(rs.getInt(2));
sizes.add(size);
while (rs.next()) {
sizes.add(new Long(rs.getLong(1)));
sizes.add(new Long(rs.getInt(2)));
}
workUnitSize.put(search, sizes);
return size.intValue();
} else {
servlet.log("not found: SELECT work_unit_id,range FROM zeta.work_unit_size WHERE task_id=" + taskId + " AND size='" + sizeOfWorkUnit + "' ORDER BY work_unit_id DESC");
}
sizes = new ArrayList(2);
sizes.add(new Long(0));
sizes.add(new Long(DEFAULT_WORK_UNIT_SIZE));
workUnitSize.put(search, sizes);
return DEFAULT_WORK_UNIT_SIZE;
}
private static final int DEFAULT_WORK_UNIT_SIZE = 500000;
private static final int MAX_WORK_UNITS_TRUST0 = 5;
private static final int MAX_WORK_UNITS_TRUST1 = 10;
private static final int MAX_WORK_UNITS_TRUST2 = 25;
private Map workUnitSize = new HashMap();
private Map userMap = new HashMap();
private Map workstationMap = new HashMap();
private ZetaServlet servlet;
}