Changeset 2648
- Timestamp:
- Sep 19, 2006, 1:30:33 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 1 deleted
- 37 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/build.xml
r2643 r2648 174 174 > 175 175 </uptodate> 176 <condition property="hibernate.message" 177 value="up to date; skipping" 178 > 179 <istrue value="${nohibernate}" /> 180 </condition> 181 <condition property="hibernate.message" 182 value="not up to date; generating new" 183 > 184 <isfalse value="${nohibernate}" /> 185 </condition> 186 <echo>Hibernate mapping files are ${hibernate.message}</echo> 176 187 </target> 177 188 … … 695 706 description="Copy required documentation" 696 707 > 708 <copy todir="${dist}/doc/admin"> 709 <fileset dir="${doc}/admin" /> 710 </copy> 697 711 <copy todir="${dist}" file="${doc}/installation.html" /> 698 712 <copy todir="${dist}" file="base2.license.txt" /> -
trunk/src/base.config.in
r2306 r2648 99 99 #jobqueue.internal.medium.threadpriority = 3 100 100 101 # ========================== 102 # External job agent section 103 # ========================== 104 105 # Number of seconds to cache information from a job agent before it 106 # is reloaded. The default value is 60 seconds. 107 agent.maxage=60 108 109 # The timeout in milliseconds to use when connecting to job agents to 110 # get information. The default value is 1000 milliseconds. 111 agent.connection.timeout=1000 112 113 101 114 # ========================= 102 115 # Secondary storage section -
trunk/src/clients/jobagent/jobagent.properties.in
r2643 r2648 66 66 ## The class must implement the net.sf.basedb.clients.JobExecutor interface 67 67 68 ## Executor that executes the jobs in a separate process (recommended) 68 # ------------------------------------------------------------------- 69 # Executor that executes the jobs in a separate process (recommended) 70 # Options: 71 # java = Path to the java executable 72 # options = Extra command line options to pass to the java executable 73 # ------------------------------------------------------------------- 69 74 agent.executor.class=net.sf.basedb.clients.jobagent.executors.ProcessJobExecutor 75 agent.executor.process.java=java 76 agent.executor.process.options=-server 70 77 71 ## Executor that executes jobs in the same process as the job agent (not recommended) 78 # ------------------------------------------------------------------- 79 # Executor that executes jobs in the same process as the job agent (not recommended) 80 # ------------------------------------------------------------------- 72 81 # agent.executor.class=net.sf.basedb.clients.jobagent.executors.ThreadJobExecutor 73 82 74 ## Executor useful for debugging purposes 83 # ------------------------------------------------------------------- 84 # Executor useful for debugging purposes. It just marks the job as 85 # executed without really executing it. 86 # Options: 87 # wait = Number of seconds it takes to execute a job 88 # ------------------------------------------------------------------- 75 89 # agent.executor.class=net.sf.basedb.clients.jobagent.executors.DummyJobExecutor 90 # agent.executor.dummy.wait=120 76 91 77 ## Initialisation parameters to the job exector. This string will be passed78 ## unmodified to the JobExecutor.init() method79 agent.executor.init=80 92 81 93 ## Number of seconds between checks to the job queue -
trunk/src/clients/jobagent/jobagent.sh
r2643 r2648 30 30 31 31 # Execute JobAgent 32 java -server -Xmx50M -Xms50M -cp $CP net.sf.basedb.clients.jobagent.AgentController $* &32 java -server -Xmx50M -Xms50M -cp $CP net.sf.basedb.clients.jobagent.AgentController $* -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/Agent.java
r2643 r2648 43 43 import net.sf.basedb.core.Job; 44 44 import net.sf.basedb.core.JobAgent; 45 import net.sf.basedb.core.JobAgentSettings; 45 46 import net.sf.basedb.core.Project; 46 47 import net.sf.basedb.core.SessionControl; … … 230 231 org.apache.log4j.LogManager.getLogger("net.sf.basedb.clients.jobagent.JobAgentServerConnection"); 231 232 233 private final Properties properties; 234 232 235 // Base settings 233 236 private final String login; … … 247 250 private final long checkInterval; 248 251 private final Class<? extends JobExecutor> executorClass; 249 private final String executorInitParameters;250 252 251 253 private InetAddress serverAddress; … … 291 293 public Agent(Properties properties) 292 294 { 295 this.properties = properties; 296 293 297 if (log.isDebugEnabled()) 294 298 { … … 323 327 this.checkInterval = Values.getInt(properties.getProperty("agent.checkinterval"), DEFAULT_CHECK_INTERVAL); 324 328 this.executorClass = getJobExecutorClass(properties.getProperty("agent.executor.class")); 325 this.executorInitParameters = properties.getProperty("agent.executor.init");326 329 327 330 // Slots and priorities … … 350 353 351 354 /** 355 Get a configuration property. 356 @param key The key 357 @return The configured value or null if not found 358 */ 359 public String getProperty(String key) 360 { 361 return properties.getProperty(key); 362 } 363 364 /** 352 365 Get the <code>agent.id</code> configuration value. 353 366 @return The ID … … 359 372 360 373 /** 374 Get the <code>agent.user</code> configuration value. 375 @return The login 376 */ 377 public String getLogin() 378 { 379 return login; 380 } 381 382 /** 383 Get the <code>agent.password</code> configuration value. 384 @return The password 385 */ 386 public String getPassword() 387 { 388 return password; 389 } 390 391 /** 361 392 Get the <code>agent.name</code> configuration value. 362 393 @return The name or the ID if the name is null … … 383 414 { 384 415 return port; 416 } 417 418 /** 419 Get the thread priority to use for the specified execution time slot. 420 @param slot 421 @return 422 */ 423 public int getThreadPriority(Job.ExecutionTime slot) 424 { 425 return priorities.get(slot); 385 426 } 386 427 … … 448 489 } 449 490 } 450 catch ( ClassNotFoundException ex)491 catch (Throwable t) 451 492 { 452 493 log.warn("Class " + className + " not found, using " + DEFAULT_JOB_EXECUTOR.getName() + 453 " instead", ex);494 " instead", t); 454 495 } 455 496 return executor; … … 618 659 public Set<Integer> getRunningJobs() 619 660 { 661 if (log.isDebugEnabled()) log.debug("Active jobs: " + activeJobs); 620 662 return Collections.unmodifiableSet(activeJobs); 621 663 } … … 764 806 @return The assigned slot or null if no slot is available 765 807 */ 766 synchronized Job.ExecutionTime getSlot(Job.ExecutionTime requested) 767 { 768 log.debug("Requesting slot for job: " + requested); 808 synchronized Job.ExecutionTime getSlot(Job job) 809 { 810 log.debug("Requesting slot for job: " + job); 811 Job.ExecutionTime requested = job.getEstimatedExecutionTime(); 769 812 Job.ExecutionTime slotToUse = null; 770 813 Job.ExecutionTime[] slots = Job.ExecutionTime.values(); … … 778 821 slotToUse = slots[i]; 779 822 usedSlots.put(slotToUse, usedSlots.get(slotToUse) + 1); 823 activeJobs.add(job.getId()); 780 824 log.debug("Slot: " + slotToUse + "; used: " + usedSlots.get(slotToUse) + "; max: " + maxSlots.get(slotToUse)); 781 825 break; … … 795 839 @param job The job to start 796 840 */ 797 public void startJob(Job job )798 { 799 JobRunner runner = new JobRunner(this, job, jobExecutor);841 public void startJob(Job job, JobAgentSettings settings) 842 { 843 JobRunner runner = new JobRunner(this, job, settings, jobExecutor); 800 844 Thread t = new Thread(runnersGroup, runner); 801 845 t.setDaemon(false); … … 868 912 { 869 913 executor = executorClass.newInstance(); 870 executor.init( executorInitParameters);914 executor.init(this); 871 915 } 872 916 catch (Throwable t) -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/CmdLine.java
r2641 r2648 63 63 { 64 64 this.cmd = args[lastIndex]; 65 lastIndex--;66 65 } 67 66 else -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/JobExecutor.java
r2643 r2648 25 25 26 26 import net.sf.basedb.core.Job; 27 import net.sf.basedb.core.JobAgentSettings; 27 28 import net.sf.basedb.core.SessionControl; 28 29 … … 50 51 /** 51 52 Initialize the job executor. This method is called once immediately 52 after the object has been created. 53 @param parameters The parameters as specified by the 54 <code>agent.executor.init</code> configuration property 53 after the object has been created. 54 @param agent The agent 55 55 */ 56 public void init( String parameters);56 public void init(Agent agent); 57 57 58 58 /** … … 72 72 @param agent The agent that sent the request to execute the job 73 73 @param job The job to execute 74 @param settings The specific settings used for the plugin on this job agent 75 or null if no settings has been specified 74 76 @param usedSlot The slot that was used to execut the job 75 77 */ 76 public void executeJob(SessionControl sc, Agent agent, Job job, Job.ExecutionTime usedSlot); 78 public void executeJob(SessionControl sc, Agent agent, Job job, JobAgentSettings settings, 79 Job.ExecutionTime usedSlot); 77 80 78 81 /** -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/JobQueueChecker.java
r2641 r2648 31 31 import net.sf.basedb.core.Job; 32 32 import net.sf.basedb.core.JobAgent; 33 import net.sf.basedb.core.JobAgentSettings; 33 34 import net.sf.basedb.core.SessionControl; 34 35 … … 57 58 private final Agent agent; 58 59 60 /** 61 Cached query for waiting jobs. Reloaded only when the 62 job agent's version has changed. We cache the query since loading 63 all users that are allowed to use the job agent is an expensive operation. 64 */ 65 private ItemQuery<Job> jobQuery = null; 66 /** 67 The job agent's version when the query was cached. 68 */ 69 private int agentVersionForJobQuery = -1; 70 59 71 public JobQueueChecker(Agent agent) 60 72 { … … 69 81 { 70 82 log.info("Checking for jobs to execute"); 71 Job job = findJob(); 72 if (job != null) 73 { 74 agent.startJob(job); 75 } 83 checkForJobs(); 76 84 } 77 85 public boolean cancel() … … 82 90 // ------------------------------------------- 83 91 84 private Job findJob()92 private void checkForJobs() 85 93 { 86 94 DbControl dc = null; 87 Job job = null;88 95 try 89 96 { … … 92 99 JobAgent jobAgent = agent.getJobAgent(dc); 93 100 94 ItemQuery<Job> jobQuery = jobAgent.getWaitingJobs(); 95 jobQuery.setMaxResults(1); 101 // Do we need to create a new query for jobs or not? 102 // We create a new query only if none exists or if the cached 103 // version is different from the current version since that may 104 // be because permissions, etc have changed. 105 if (jobQuery == null || jobAgent.getVersion() != agentVersionForJobQuery) 106 { 107 jobQuery = jobAgent.getWaitingJobs(); 108 jobQuery.setMaxResults(1); 109 agentVersionForJobQuery = jobAgent.getVersion(); 110 } 96 111 97 112 List<Job> jobs = jobQuery.list(dc); … … 102 117 else 103 118 { 104 job = jobs.get(0); 119 Job job = jobs.get(0); 120 JobAgentSettings settings = jobAgent.getSettings(job); 121 agent.startJob(job, settings); 105 122 } 106 123 } … … 113 130 if (dc != null) dc.close(); 114 131 } 115 return job;116 132 } 117 133 -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/JobRunner.java
r2643 r2648 29 29 import net.sf.basedb.core.ItemModifiedException; 30 30 import net.sf.basedb.core.Job; 31 import net.sf.basedb.core.JobAgentSettings; 31 32 import net.sf.basedb.core.SessionControl; 32 33 … … 53 54 54 55 private final Job job; 56 private final JobAgentSettings settings; 55 57 private final JobExecutor jobExecutor; 56 58 private final Agent agent; … … 60 62 @param agent The agent that created this object 61 63 @param job The job to be executed 64 @param settings The settigns for the plugin that is executing the job 62 65 @param jobExecutor The job executor that should execute the job 63 66 */ 64 JobRunner(Agent agent, Job job, Job Executor jobExecutor)67 JobRunner(Agent agent, Job job, JobAgentSettings settings, JobExecutor jobExecutor) 65 68 { 66 69 this.agent = agent; 67 70 this.job = job; 71 this.settings = settings; 68 72 this.jobExecutor = jobExecutor; 69 73 } … … 79 83 public void run() 80 84 { 81 Job.ExecutionTime slotToUse = agent.getSlot(job .getEstimatedExecutionTime());85 Job.ExecutionTime slotToUse = agent.getSlot(job); 82 86 if (slotToUse == null) 83 87 { … … 116 120 try 117 121 { 118 jobExecutor.executeJob(sc, agent, j, s lotToUse);122 jobExecutor.executeJob(sc, agent, j, settings, slotToUse); 119 123 } 120 124 catch (Throwable t) -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/executors/DummyJobExecutor.java
r2643 r2648 28 28 import net.sf.basedb.core.DbControl; 29 29 import net.sf.basedb.core.Job; 30 import net.sf.basedb.core.JobAgentSettings; 30 31 import net.sf.basedb.core.SessionControl; 32 import net.sf.basedb.util.Values; 31 33 32 34 /** … … 34 36 of each job to {@link net.sf.basedb.core.Job.Status#DONE} without actually 35 37 executing the job. This class is usful for debugging the job agent application. 38 <p> 39 <table> 40 <tr> 41 <th>Configuration parameter</th> 42 <th>Default value</th> 43 <th>Description</th> 44 </tr> 45 46 <tr> 47 <td>agent.executor.dummy.wait</td> 48 <td></td> 49 <td> 50 Number of seconds it takes to execute a job. The implementation simly 51 waits the specified number of seconds. If not specified the execution will 52 return immediately. 53 </td> 54 </tr> 55 </table> 36 56 37 57 @author nicklas … … 50 70 51 71 72 private int wait; 73 52 74 public DummyJobExecutor() 53 75 {} … … 57 79 ------------------------------------------- 58 80 */ 59 public void init(String parameters) 60 {} 81 public void init(Agent agent) 82 { 83 wait = Values.getInt(agent.getProperty("agent.executor.wait"), -1); 84 } 61 85 62 public void executeJob(SessionControl sc, Agent agent, Job job, Job.ExecutionTime usedSlot) 86 public void executeJob(SessionControl sc, Agent agent, Job job, JobAgentSettings settings, 87 Job.ExecutionTime usedSlot) 63 88 { 64 89 log.info("Executing job: " + job); … … 69 94 job = Job.getById(dc, job.getId()); 70 95 job.start("Not really, but used for testing the job agent", agent.getServerName()); 96 if (wait > 0) 97 { 98 job.setProgress(50, "Halfway; waiting " + wait + " seconds"); 99 dc.commit(); 100 try 101 { 102 synchronized (Thread.currentThread()) 103 { 104 Thread.currentThread().wait(wait * 1000); 105 } 106 } 107 catch (Throwable t) 108 { 109 log.error(t.getMessage(), t); 110 } 111 dc = sc.newDbControl(); 112 dc.reattachItem(job); 113 } 71 114 job.doneOk("Not really, but used for testing job agent"); 72 115 dc.commit(); -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/executors/ProcessJobExecutor.java
r2643 r2648 26 26 import java.io.BufferedReader; 27 27 import java.io.IOException; 28 import java.io.InputStream;29 28 import java.io.InputStreamReader; 30 import java.io.OutputStream;31 29 import java.io.PrintWriter; 32 30 import java.io.Reader; … … 41 39 import net.sf.basedb.core.DbControl; 42 40 import net.sf.basedb.core.Job; 41 import net.sf.basedb.core.JobAgentSettings; 42 import net.sf.basedb.core.PluginDefinition; 43 43 import net.sf.basedb.core.SessionControl; 44 import net.sf.basedb.util.Values; 44 45 45 46 /** … … 55 56 The disadvantage is the overhead in time and memory of starting a new 56 57 process. 57 58 <p> 59 <table> 60 <tr> 61 <th>Configuration parameter</th> 62 <th>Default value</th> 63 <th>Description</th> 64 </tr> 65 66 <tr> 67 <td>agent.executor.process.java</td> 68 <td></td> 69 <td> 70 Path to the java executable to use. not specified the envoronment variable 71 <code>JAVA_HOME</code> is used if it exists. Otherwise we let the operating 72 system find the <code>java</code> command. 73 </td> 74 </tr> 75 76 <tr> 77 <td>agent.executor.process.options</td> 78 <td>-server</td> 79 <td> 80 Extra command line options to pass to the java executable: 81 <code>java <options> -cp ... className ...</code>. 82 </td> 83 </tr> 84 </table> 85 58 86 @author nicklas 59 87 @version 2.0 … … 71 99 72 100 101 private String javaBin; 102 private String options; 103 73 104 public ProcessJobExecutor() 74 105 {} … … 78 109 ------------------------------------------- 79 110 */ 80 public void init(String parameters) 81 {} 82 83 public void executeJob(SessionControl sc, Agent agent, Job job, Job.ExecutionTime usedSlot) 111 public void init(Agent agent) 112 { 113 javaBin = Values.getStringOrNull(agent.getProperty("agent.executor.process.java")); 114 if (javaBin == null) 115 { 116 javaBin = System.getenv("JAVA_HOME"); 117 char sep = java.io.File.separatorChar; 118 if (javaBin != null) javaBin += sep + "jre" + sep + "bin" + sep + "java"; 119 } 120 if (javaBin == null) javaBin = "java"; 121 options = Values.getString(agent.getProperty("agent.executor.process.options"), "-server"); 122 } 123 124 public void executeJob(SessionControl sc, Agent agent, Job job, JobAgentSettings settings, 125 Job.ExecutionTime usedSlot) 84 126 { 85 127 log.info("Executing job: " + job); 128 129 // Generate command for new process 130 List<String> cmd = new ArrayList<String>(10); 131 132 // Java executable 133 cmd.add(javaBin); 134 135 // Other java options 136 cmd.add(options); 137 138 // Max allowed memory 139 Long maxMemory = settings == null ? null : settings.getEffectiveMaxMemory(); 140 if (maxMemory != null) 141 { 142 maxMemory = maxMemory / 1024 / 1024; 143 if (maxMemory >= 1) cmd.add("-Xmx" + maxMemory + "M"); 144 } 145 146 // Class path 86 147 String classPath = System.getProperty("java.class.path"); 87 88 List<String> cmd = new ArrayList<String>(10);89 cmd.add("java");90 cmd.add("-server");91 148 cmd.add("-cp"); 92 149 cmd.add(classPath); 150 151 // ThreadJobExecutor will execute the job 93 152 cmd.add("net.sf.basedb.clients.jobagent.executors.ThreadJobExecutor"); 153 cmd.add("-j"); // Job id 94 154 cmd.add(Integer.toString(job.getId())); 95 96 log.debug("Using class path: " + classPath); 97 ProcessBuilder builder = new ProcessBuilder(cmd); 98 builder.redirectErrorStream(true); 155 cmd.add("-s"); // JobAgentSettings id 156 cmd.add(Integer.toString(settings.getId())); 157 cmd.add("-u"); // User login 158 cmd.add(agent.getLogin()); 159 cmd.add("-p"); // Password 160 cmd.add(agent.getPassword()); 161 cmd.add("-t"); // Thread priority 162 cmd.add(Integer.toString(agent.getThreadPriority(job.getEstimatedExecutionTime()))); 99 163 100 164 Process process = null; … … 102 166 try 103 167 { 168 // Update progress on job 169 dc = sc.newDbControl(); 170 job = Job.getById(dc, job.getId()); 171 job.setProgress(0, "Starting new process"); 172 dc.commit(); 173 174 if (log.isDebugEnabled()) 175 { 176 log.debug("Executing cmd: " + Values.getString(cmd, " ", true)); 177 } 178 ProcessBuilder builder = new ProcessBuilder(cmd); 179 builder.redirectErrorStream(true); 180 104 181 try 105 182 { … … 163 240 // ------------------------------------------- 164 241 165 242 /** 243 Used for redirecting standard output to a string. 244 */ 166 245 public static class StreamRedirector 167 246 implements Runnable -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/executors/ThreadJobExecutor.java
r2643 r2648 28 28 29 29 import net.sf.basedb.clients.jobagent.Agent; 30 import net.sf.basedb.clients.jobagent.CmdLine; 30 31 import net.sf.basedb.clients.jobagent.JobExecutor; 32 import net.sf.basedb.core.Application; 31 33 import net.sf.basedb.core.DbControl; 32 34 import net.sf.basedb.core.Job; 35 import net.sf.basedb.core.JobAgentSettings; 33 36 import net.sf.basedb.core.PluginExecutionRequest; 34 37 import net.sf.basedb.core.PluginResponse; 38 import net.sf.basedb.core.Project; 35 39 import net.sf.basedb.core.SessionControl; 36 40 import net.sf.basedb.core.plugin.Response; 41 import net.sf.basedb.util.SocketUtil; 42 import net.sf.basedb.util.Values; 37 43 38 44 /** … … 67 73 ------------------------------------------- 68 74 */ 69 public void init( String parameters)75 public void init(Agent agent) 70 76 {} 71 77 72 public void executeJob(SessionControl sc, Agent agent, Job job, Job.ExecutionTime usedSlot) 78 public void executeJob(SessionControl sc, Agent agent, Job job, JobAgentSettings settings, 79 Job.ExecutionTime usedSlot) 73 80 { 74 81 log.info("Executing job: " + job); … … 84 91 try 85 92 { 86 exec = job.execute(null, agent.getServerName());93 exec = job.execute(null, Application.getHostName(), settings); 87 94 } 88 95 catch (Throwable t) … … 125 132 public static void main(String[] args) 126 133 { 127 System.out.println("Running job with ID: " + args[0]); 128 System.exit(11); 134 int exitCode = 0; 135 CmdLine cmdLine = new CmdLine(args); 136 int jobId = Values.getInt(cmdLine.getOption("-j")); 137 int settingsId = Values.getInt(cmdLine.getOption("-s")); 138 String login = cmdLine.getOption("-u"); 139 String password = cmdLine.getOption("-p"); 140 int threadPriority = Values.getInt(cmdLine.getOption("-t"), Thread.NORM_PRIORITY); 141 142 String loginComment = "Job agent running on host " + 143 Application.getHostName() + " executing job with ID = " + jobId; 144 145 log.info("Running job with ID: " + jobId); 146 DbControl dc = null; 147 SessionControl sc = null; 148 SessionControl impersonated = null; 149 try 150 { 151 ThreadJobExecutor executor = new ThreadJobExecutor(); 152 153 sc = Application.newSessionControl("net.sf.basedb.clients.jobagent", 154 SocketUtil.getLocalHost().toString(), null); 155 sc.login(login, password, loginComment, false); 156 dc = sc.newDbControl(); 157 Job job = Job.getById(dc, jobId); 158 JobAgentSettings settings = JobAgentSettings.getById(dc, settingsId); 159 dc.close(); 160 161 impersonated = sc.impersonateLogin(job, "Running job: " + job.getName()); 162 if (job.getActiveProjectId() != 0) 163 { 164 dc = impersonated.newDbControl(); 165 Project activeProject = Project.getById(dc, job.getActiveProjectId()); 166 impersonated.setActiveProject(activeProject); 167 dc.close(); 168 } 169 170 Thread.currentThread().setPriority(threadPriority); 171 executor.executeJob(impersonated, null, job, settings, null); 172 } 173 catch (Throwable t) 174 { 175 log.error("Error executing job with ID: " + jobId); 176 exitCode = 1; 177 } 178 finally 179 { 180 if (dc != null) dc.close(); 181 if (impersonated != null && impersonated.isLoggedIn()) impersonated.logout(); 182 if (sc != null && sc.isLoggedIn()) sc.logout(); 183 } 184 System.exit(exitCode); 129 185 } 130 186 -
trunk/src/clients/jobagent/net/sf/basedb/clients/jobagent/handlers/InfoRequestHandler.java
r2641 r2648 59 59 { 60 60 Runtime runtime = Runtime.getRuntime(); 61 int cpu = (int)(Math.random()*100); 62 long totalMemory = runtime.maxMemory(); 63 long usedMemory = runtime.totalMemory() - runtime.freeMemory(); 64 JobAgentInfo info = new JobAgentInfo(!agent.isRunning(), cpu, totalMemory, usedMemory, agent.getRunningJobs()); 61 // TODO - Get this info when it can be done by the JVM or use external calls 62 // Useful link: http://builder.com.com/5100-6370_14-6067049.html 63 Integer cpu = null; // (int)(Math.random()*100); 64 Long totalMemory = null; // runtime.maxMemory(); 65 Long usedMemory = null; //runtime.totalMemory() - runtime.freeMemory(); 66 JobAgentInfo info = new JobAgentInfo(!agent.isRunning(), cpu, usedMemory, totalMemory, agent.getRunningJobs()); 65 67 answer = "OK\n"+info.toString(); 66 68 } -
trunk/src/core/common-queries.xml
r2646 r2648 135 135 </description> 136 136 </query> 137 138 <query id="GET_CHILDGROUPS_IDS_FOR_GROUPS" type="HQL"> 139 <sql> 140 SELECT DISTINCT gg.childId 141 FROM GroupGroups gg 142 WHERE gg.parentId IN (:groups) 143 AND gg.childId NOT IN (:groups) 144 </sql> 145 <description> 146 Load the ID of all groups that are children to at least one of 147 the given groups, excluding the given groups. 148 </description> 149 </query> 137 150 138 151 <query id="GET_PROJECT_IDS_FOR_OWNER" type="HQL"> -
trunk/src/core/net/sf/basedb/core/Group.java
r2572 r2648 29 29 import net.sf.basedb.core.query.Hql; 30 30 31 import java.util.HashSet; 31 32 import java.util.Set; 32 33 import java.util.Collections; … … 113 114 } 114 115 116 /** 117 Load all groups withing groups. 118 @param dc The DbControl to use for database access 119 @param groups The groups to start with 120 @return A set containing the starting groups, the groups that are members of the 121 start groups and the groups that are members following subgroups down as 122 far as possible 123 */ 124 public static Set<Integer> getGroupsRecursive(DbControl dc, Set<Integer> groups) 125 { 126 Set<Integer> allGroups = new HashSet<Integer>(groups); 127 if (allGroups.size() > 0) 128 { 129 130 org.hibernate.Query query = HibernateUtil.getPredefinedQuery(dc.getHibernateSession(), 131 "GET_CHILDGROUPS_IDS_FOR_GROUPS"); 132 /* 133 SELECT DISTINCT gg.childId 134 FROM GroupGroups gg 135 WHERE gg.parentId IN (:groups) 136 AND gg.childId NOT IN (:groups) 137 */ 138 do 139 { 140 query.setParameterList("groups", allGroups, org.hibernate.Hibernate.INTEGER); 141 } while (allGroups.addAll(HibernateUtil.loadList(Integer.class, query))); 142 } 143 return allGroups; 144 } 145 115 146 /** 116 147 Get a query configured to retrieve groups. -
trunk/src/core/net/sf/basedb/core/Job.java
r2643 r2648 525 525 526 526 /** 527 Set the progress of the job. The job must be in the {@link Status#EXECUTING} status. 527 Set the progress of the job. The job must be in the {@link Status#EXECUTING} or 528 {@link Status#PREPARED} status. 528 529 @param percentComplete The number of percent completed 529 530 @param statusMessage A message … … 537 538 { 538 539 checkPermission(Permission.WRITE); 539 if (getStatus() != Status.EXECUTING )540 if (getStatus() != Status.EXECUTING && getStatus() != Status.PREPARED) 540 541 { 541 542 throw new PermissionDeniedException("Cannot set progress for a job with status '"+getStatus()+"': "+toString()); … … 688 689 before calling {@link net.sf.basedb.core.PluginRequest#invoke()}. 689 690 See {@link net.sf.basedb.core.PluginRequest} for more information. 690 691 691 692 @param progress The {@link ProgressReporter} where the plugin can report its progress. If 692 693 <code>null</code> {@link net.sf.basedb.core.Job.ProgressReporterImpl} is used … … 701 702 throws PermissionDeniedException, InvalidDataException, BaseException 702 703 { 704 return execute(progress, server, null); 705 } 706 707 708 /** 709 Start the execution sequence for a job. Call {@link DbControl#commit()} 710 before calling {@link net.sf.basedb.core.PluginRequest#invoke()}. 711 See {@link net.sf.basedb.core.PluginRequest} for more information. 712 713 @param progress The {@link ProgressReporter} where the plugin can report its progress. If 714 <code>null</code> {@link net.sf.basedb.core.Job.ProgressReporterImpl} is used 715 @param server The name of the server executing the plugin 716 @param settings The job agent settings to use or null to use default settings 717 @return A <code>Plugin.Request</code> object 718 @throws PermissionDeniedException If the logged in user doesn't have 719 write permission or the job isn't in the {@link Status#WAITING} status 720 @throws InvalidDataException If the server name is too long 721 @throws BaseException If there is another error 722 */ 723 public PluginExecutionRequest execute(ProgressReporter progress, String server, JobAgentSettings settings) 724 throws PermissionDeniedException, InvalidDataException, BaseException 725 { 703 726 checkPermission(Permission.WRITE); 704 727 if (getJobType() != Type.RUN_PLUGIN) … … 717 740 PluginDefinition pd = getPluginDefinition(); 718 741 PluginConfiguration config = getPluginConfiguration(); 719 Plugin plugin = pd.newInstance( );742 Plugin plugin = pd.newInstance(settings == null ? null : settings.getJarPath()); 720 743 SessionControl sc = getSessionControl(); 721 744 ParameterValuesImpl parameters = new ParameterValuesImpl(this, true); -
trunk/src/core/net/sf/basedb/core/JobAgent.java
r2643 r2648 59 59 extends CommonItem<JobAgentData> 60 60 { 61 62 /** 63 Log events. 64 */ 65 private static final org.apache.log4j.Logger log = 66 org.apache.log4j.LogManager.getLogger("net.sf.basedb.core.JobAgent"); 67 61 68 /** 62 69 The type of item represented by this class. … … 238 245 } 239 246 247 /** 248 Get info about the running job agent. For performance reasons the 249 information is cached and only updated if older than 250 specified by the <code>agent.maxage</code> configuration setting. 251 @return A <code>JobAgentInfo</code> object 252 */ 240 253 public JobAgentInfo getInfo() 241 254 { 242 255 return getAgentInfo(this); 256 } 257 258 /** 259 Get a connection object for connecting to the job agent. It is only 260 possible to connect to job agents which has specified a server and port. 261 @param timeout The timeout for the connection, null will use the default 262 timeout as configued by the <code>agent.connection.timeout</code> setting 263 in the <code>base.config</code> file 264 @return The connection object or null if none could be created 265 @throws PermissionDeniedException If the logged in user doesn't have 266 WRITE permission on the job agent 267 */ 268 public JobAgentConnection getConnection(Integer timeout) 269 throws PermissionDeniedException 270 { 271 checkPermission(Permission.WRITE); 272 String server = getServer(); 273 Integer port = getPort(); 274 if (timeout == null) 275 { 276 timeout = Config.getInt("agent.connection.timeout", 1000); 277 } 278 JobAgentConnection conn = null; 279 if (port != null && server != null) 280 { 281 conn = new JobAgentConnection(server, port, timeout); 282 agentInfo.remove(getId()); 283 } 284 return conn; 243 285 } 244 286 … … 246 288 Get the current CPU usage in percent of the server where the job agent is running. 247 289 The CPU usage is not available unless a server name/IP and port has been specified. 248 For performance reasons the CPU usage is cached and only updated if older than one minute.249 (TODO - could be in base.config)290 For performance reasons the CPU usage is cached and only updated if older than 291 specified by the <code>agent.maxage</code> configuration setting. 250 292 @return The CPU usage of the job agent's server in percent, or null if not known 251 293 */ … … 258 300 is running. The memory usage is not available unless a server name/IP and port 259 301 has been specified. For performance reasons the memory usage is cached and only 260 updated if older than one minute. (TODO - could be in base.config)302 updated if older than specified by the <code>agent.maxage</code> configuration setting. 261 303 @return The memory usage on the job agent's server, or null if not known 262 304 */ … … 270 312 is running. The memory is not available unless a server name/IP and port 271 313 has been specified. For performance reasons the memory is cached and only 272 updated if older than one minute. (TODO - could be in base.config) 314 updated if older than specified by the <code>agent.maxage</code> configuration 315 setting. 273 316 @return The memory on the job agent's server, or null if not known 274 317 */ … … 299 342 settings = JobAgentSettings.getNew(dc, this, plugin); 300 343 } 344 return settings; 345 } 346 347 /** 348 Get the settings for the plugin that is used for the specified job. 349 @param job The job to get the settings for 350 @return A <code>JobAgentSettings</code> object or null if not 351 settings exist for the job 352 */ 353 public JobAgentSettings getSettings(Job job) 354 { 355 DbControl dc = getDbControl(); 356 JobAgentSettings settings = dc.getItem(JobAgentSettings.class, 357 getData().getPlugins().get(job.getData().getPluginDefinition())); 301 358 return settings; 302 359 } … … 346 403 ); 347 404 348 // Create restriction s forowner of the job405 // Create restriction for the owner of the job 349 406 query.include(Include.MINE, Include.OTHERS); 350 407 Restriction userRestriction = Restrictions.in( … … 352 409 Expressions.parameter("users") 353 410 ); 411 412 // Load all users that this job agent is shared to 354 413 Set<Integer> userIds = new HashSet<Integer>(); 355 414 userIds.add(getData().getOwner().getId()); … … 366 425 { 367 426 userIds.addAll(itemKey.getUserIds(Permission.USE)); 368 // TODO - load groups within groups and then all members of those groups 369 } 370 } 371 427 groupIds = Group.getGroupsRecursive(getDbControl(), groupIds); 428 userIds.addAll(User.getAllMembers(getDbControl(), groupIds)); 429 } 430 } 431 432 // Load all projects this job agent is shared to 372 433 Restriction projectRestriction = null; 373 434 Set<Integer> projectIds = new HashSet<Integer>(); … … 440 501 private static final Map<Integer, JobAgentInfo> agentInfo = new HashMap<Integer, JobAgentInfo>(); 441 502 503 /** 504 Get a <code>JobAgentInfo</code> for a job agent. If the job agent hasn't specified 505 a server and port or if there is an error while connecting to the job agent 506 an empty info object is returned. 507 508 @param agent The job agent to get the info for 509 @return A <code>JobAgentInfo</code> object 510 */ 442 511 private static JobAgentInfo getAgentInfo(JobAgent agent) 443 512 { 444 513 JobAgentInfo info = agentInfo.get(agent.getId()); 445 if (info == null || info.getAge() > 60000)514 if (info == null || info.getAge() > Config.getInt("agent.maxage", 60) * 1000) 446 515 { 447 516 String server = agent.getServer(); … … 451 520 try 452 521 { 453 JobAgentConnection conn = new JobAgentConnection(server, port, 1000); 522 JobAgentConnection conn = new JobAgentConnection(server, port, 523 Config.getInt("agent.connection.timeout", 1000)); 454 524 info = conn.getInfo(true); 455 525 } 456 526 catch (Throwable t) 457 527 { 458 // TODO459 t.printStackTrace();528 log.warn("Could not get info for job agent on server " + server + ":" + port, t); 529 info = new JobAgentInfo(); 460 530 } 461 531 } 462 if (info == null)532 else 463 533 { 464 534 info = new JobAgentInfo(); -
trunk/src/core/net/sf/basedb/core/JobAgentSettings.java
r2627 r2648 31 31 /** 32 32 This class contains a job agent's settings for a specific plugin. 33 The settings may override the default settings for TODO 33 The settings may override the default settings for the JAR path 34 where to plugin is located, maximum memory to use, and if the plugin 35 is trusted or not. 34 36 35 37 @author nicklas … … 63 65 settings.setPluginDefinition(plugin); 64 66 return settings; 67 } 68 69 /** 70 Get a <code>JobAgentSettings</code> item when you know the ID. 71 72 @param dc The <code>DbControl</code> which will be used for 73 permission checking and database access 74 @param id The ID of the item to load 75 @return The <code>JobAgentSettings</code> item 76 @throws ItemNotFoundException If an item with the specified ID is not found 77 @throws PermissionDeniedException If the logged in user doesn't have 78 read permission for the item 79 @throws BaseException If there is another error 80 */ 81 public static JobAgentSettings getById(DbControl dc, int id) 82 throws ItemNotFoundException, PermissionDeniedException, BaseException 83 { 84 JobAgentSettings jas = dc.loadItem(JobAgentSettings.class, id); 85 if (jas == null) throw new ItemNotFoundException("JobAgentSettings[id="+id+"]"); 86 return jas; 65 87 } 66 88 -
trunk/src/core/net/sf/basedb/core/Message.java
r2474 r2648 99 99 @param user The user to count the unread messages for, or null to 100 100 count the messages for the logged in user 101 @param cacheResult If the result should be cached or not 101 102 @return The number of unread messages 102 103 @throws BaseException If there is an error 103 104 */ 104 public static long countUnreadMessages(DbControl dc, User user )105 public static long countUnreadMessages(DbControl dc, User user, boolean cacheResult) 105 106 throws BaseException 106 107 { … … 113 114 */ 114 115 query.setInteger("user", user == null ? dc.getSessionControl().getLoggedInUserId() : user.getId()); 115 query.setCacheable( true);116 query.setCacheable(cacheResult); 116 117 return HibernateUtil.loadData(Long.class, query); 117 118 } -
trunk/src/core/net/sf/basedb/core/PluginDefinition.java
r2646 r2648 56 56 public class PluginDefinition 57 57 extends SharedItem<PluginDefinitionData> 58 implements Removable58 implements Nameable, Removable 59 59 { 60 60 /** … … 376 376 } 377 377 /** 378 The name cannot be changed. 379 @throws PermissionDeniedException Always 380 */ 381 public void setName(String name) 382 throws PermissionDeniedException 383 { 384 throw new PermissionDeniedException("Not allowed to set the name of a plugin"); 385 } 386 387 /** 378 388 The name cannot be changed. Used internally only. 379 389 … … 383 393 @throws InvalidDataException If the name is null or too long 384 394 */ 385 private void setName (String name)395 private void setNameInternal(String name) 386 396 throws InvalidDataException 387 397 { … … 397 407 return getData().getDescription(); 398 408 } 409 /** 410 The description cannot be changed. 411 @throws PermissionDeniedException Always 412 */ 413 public void setDescription(String description) 414 throws PermissionDeniedException 415 { 416 throw new PermissionDeniedException("Not allowed to set the description of a plugin"); 417 } 418 399 419 /** 400 420 The description cannot be changed. Used internally only. … … 405 425 @throws InvalidDataException If the description is too long 406 426 */ 407 protected void setDescription (String description)427 protected void setDescriptionInternal(String description) 408 428 throws InvalidDataException 409 429 { … … 801 821 } 802 822 803 public <P extends Plugin> P newInstance(Class<P> clazz, SessionControl sc, PluginConfiguration configuration, Job job)823 Plugin newInstance(String jarPath) 804 824 throws PermissionDeniedException, BaseException 805 825 { 806 Plugin p = newInstance(); 826 checkPermission(Permission.USE); 827 return newInstance(jarPath == null ? getData().getJarPath() : jarPath, getData().getClassName(), false); 828 } 829 830 /** 831 Get an instance of the plugin implementation. 832 @param clazz The class of the plugin which must be a subclass of <code>Plugin</code> 833 @param jarPath Overrides the default JAR path for a plugin, null to use the default 834 JAR path 835 @param sc The session control to initialise the plugin with 836 @param configuration The configuration parameters to initialise the plugin with, 837 or null if no configuration exists 838 @param job The job parameters to intialise the plugin with, or null if no 839 job exists 840 @return An initialised plugin instance 841 @throws PermissionDeniedException 842 @throws BaseException 843 */ 844 public <P extends Plugin> P newInstance(Class<P> clazz, String jarPath, SessionControl sc, PluginConfiguration configuration, Job job) 845 throws PermissionDeniedException, BaseException 846 { 847 Plugin p = newInstance(jarPath); 807 848 if (!clazz.isInstance(p)) 808 849 { … … 921 962 // Everything returned by the getAbout() method... 922 963 About about = plugin.getAbout(); 923 setName (about.getName());924 setDescription (about.getDescription());964 setNameInternal(about.getName()); 965 setDescriptionInternal(about.getDescription()); 925 966 setVersionString(about.getVersion()); 926 967 setCopyright(about.getCopyright()); -
trunk/src/core/net/sf/basedb/core/User.java
r2382 r2648 34 34 35 35 import java.util.Date; 36 import java.util.HashSet; 36 37 import java.util.Set; 37 38 import java.util.Collections; … … 110 111 } 111 112 113 /** 114 Load the ID:s of all users that are direct members of 115 the specified groups. 116 @param groupIds The ID:s of the groups 117 @return The ID:s of all members 118 @see Group#getGroupsRecursive(DbControl, Set) 119 */ 120 public static Set<Integer> getAllMembers(DbControl dc, Set<Integer> groupIds) 121 { 122 Set<Integer> userIds = new HashSet<Integer>(); 123 if (groupIds != null && groupIds.size() > 0) 124 { 125 org.hibernate.Session session = dc.getHibernateSession(); 126 // Get the users which are members of the same groups 127 org.hibernate.Query query = HibernateUtil.getPredefinedQuery(session, "GET_USER_IDS_FOR_GROUPS"); 128 /* 129 SELECT ug.userId 130 FROM UserGroups ug 131 WHERE ug.groupId IN (:groups) 132 */ 133 query.setParameterList("groups", groupIds, org.hibernate.Hibernate.INTEGER); 134 userIds.addAll(HibernateUtil.loadList(Integer.class, query)); 135 136 // Get the users that have a quota group among the same groups 137 query = HibernateUtil.getPredefinedQuery(session, "GET_USER_IDS_FOR_QUOTAGROUPS"); 138 /* 139 SELECT usr.id 140 FROM UserData usr 141 WHERE usr.quotaGroup.id IN (:groups) 142 */ 143 query.setParameterList("groups", groupIds, org.hibernate.Hibernate.INTEGER); 144 userIds.addAll(HibernateUtil.loadList(Integer.class, query)); 145 } 146 return userIds; 147 148 } 149 112 150 /** 113 151 Get a query configured to retrieve users. If the logged in user -
trunk/src/core/net/sf/basedb/util/AutoDetectFileFormat.java
r2304 r2648 116 116 { 117 117 AutoDetectingImporter importer = plugin.newInstance(AutoDetectingImporter.class, 118 sc, config, null);118 null, sc, config, null); 119 119 if (currentItem == null || ((InteractivePlugin)importer).isInContext(context, currentItem) == null) 120 120 { … … 139 139 { 140 140 AutoDetectingImporter importer = plugin.newInstance(AutoDetectingImporter.class, 141 sc, null, null);141 null, sc, null, null); 142 142 if (currentItem == null || ((InteractivePlugin)importer).isInContext(context, currentItem) == null) 143 143 { -
trunk/src/core/net/sf/basedb/util/SocketUtil.java
r2641 r2648 37 37 import java.nio.channels.ServerSocketChannel; 38 38 39 39 40 /** 40 41 This class contains some useful methods when working with sockets. Mainly … … 58 59 catch (Throwable t) 59 60 { 60 // TODO - log maybe?61 61 t.printStackTrace(); 62 62 } … … 231 231 catch (UnknownHostException ex) 232 232 { 233 // TODO - how to handle?234 233 ex.printStackTrace(); 235 234 } -
trunk/src/log4j.properties.in
r2634 r2648 50 50 # Job agent loggers 51 51 # ----------------- 52 log4j.logger.net.sf.basedb.clients.jobagent= debug52 log4j.logger.net.sf.basedb.clients.jobagent=warn 53 53 54 54 # ----------------- -
trunk/src/test/TestAll.java
r2576 r2648 127 127 results.put("TestPluginConfiguration", TestPluginConfiguration.test_all()); 128 128 results.put("TestJob", TestJob.test_all()); 129 results.put("TestJobAgent", TestJobAgent.test_all()); 129 130 results.put("TestReporterFlatFileImporter", TestReporterFlatFileImporter.test_all()); 130 131 results.put("TestReporterMapFlatFileImporter", TestReporterMapFlatFileImporter.test_all()); -
trunk/www/admin/jobagents/edit_agent.jsp
r2631 r2648 72 72 title = "Create job agent"; 73 73 cc.removeObject("item"); 74 port = Values.getInteger(cc.getPropertyValue("port"), null);74 port = Values.getInteger(cc.getPropertyValue("port"), JobAgent.DEFAULT_PORT); 75 75 } 76 76 else … … 434 434 <td class="prompt">Port</td> 435 435 <td><input <%=clazz%> type="text" name="port" 436 value="<%=port == null ? JobAgent.DEFAULT_PORT : port%>"436 value="<%=port == null ? "" : port.toString() %>" 437 437 size="12" maxlength="10" 438 onkeypress="return Numbers.integerOnly(event)"></td> 438 onkeypress="return Numbers.integerOnly(event)"> 439 <span class="link" onclick="document.forms['agent'].port.value = '<%=JobAgent.DEFAULT_PORT%>'" 440 >Use default (<%=JobAgent.DEFAULT_PORT%>)</span> 441 </td> 439 442 </tr> 440 443 <tr valign=top> -
trunk/www/admin/jobagents/index.jsp
r2643 r2648 41 41 import="net.sf.basedb.util.RemovableUtil" 42 42 import="net.sf.basedb.util.ShareableUtil" 43 import="net.sf.basedb.util.jobagent.JobAgentConnection" 43 44 import="net.sf.basedb.clients.web.Base" 44 45 import="net.sf.basedb.clients.web.WebException" … … 293 294 redirect = "../../common/plugin/index.jsp?ID="+ID+"&cmd=SelectPlugin&item_type="+itemType.name()+"&context_type=ITEM&main_type=OTHER&title=Run+plugin"; 294 295 } 296 else if ("Pause".equals(cmd) || "Start".equals(cmd)) 297 { 298 ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext); 299 dc = sc.newDbControl(); 300 JobAgent agent = JobAgent.getById(dc, cc.getId()); 301 dc.close(); 302 JobAgentConnection conn = agent.getConnection(null); 303 String answer = null; 304 if (conn != null) 305 { 306 try 307 { 308 if ("Start".equals(cmd)) 309 { 310 answer = conn.sendStart(); 311 } 312 else if ("Pause".equals(cmd)) 313 { 314 answer = conn.sendPause(); 315 } 316 } 317 catch (Throwable t) 318 { 319 answer = t.getMessage(); 320 } 321 if (!"OK".equals(answer)) 322 { 323 cc.setMessage("Could not " + cmd.toLowerCase() + " the job agent. The answer is: " + answer); 324 } 325 } 326 else 327 { 328 cc.setMessage("Could not create connection to job agent, probably because no " + 329 "server and/or port has been specified."); 330 } 331 redirect = viewPage; 332 } 333 else if ("PauseSelected".equals(cmd) || "StartSelected".equals(cmd)) 334 { 335 ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext); 336 dc = sc.newDbControl(); 337 boolean start = "StartSelected".equals(cmd); 338 int total = cc.getSelected().size(); 339 int started = 0; 340 int paused = 0; 341 342 for (int agentId : cc.getSelected()) 343 { 344 JobAgent agent = JobAgent.getById(dc, agentId); 345 if (agent.hasPermission(Permission.WRITE)) 346 { 347 try 348 { 349 JobAgentConnection conn = agent.getConnection(null); 350 if (conn != null) 351 { 352 if (start) 353 { 354 String answer = conn.sendStart(); 355 started += "OK".equals(answer) ? 1 : 0; 356 } 357 else 358 { 359 String answer = conn.sendPause(); 360 paused += "OK".equals(answer) ? 1 : 0; 361 } 362 } 363 } 364 catch (Throwable t) 365 {} 366 } 367 } 368 if (total != started + paused) 369 { 370 message = "Only " + (start ? started : paused) + " job agents of " + total + 371 " could be " + (start ? "started" : "paused"); 372 } 373 redirect = listPage+(message != null ? "&popmessage="+HTML.urlEncode(message) : ""); 374 } 295 375 else 296 376 { -
trunk/www/admin/jobagents/list_agents.jsp
r2643 r2648 37 37 import="net.sf.basedb.core.Permission" 38 38 import="net.sf.basedb.core.PluginDefinition" 39 import="net.sf.basedb.core.Job" 40 import="net.sf.basedb.core.Type" 41 import="net.sf.basedb.core.query.Expressions" 42 import="net.sf.basedb.core.query.Restrictions" 39 43 import="net.sf.basedb.core.query.Orders" 40 44 import="net.sf.basedb.core.query.Hql" … … 49 53 import="java.util.List" 50 54 import="java.util.Map" 55 import="java.util.Set" 51 56 %> 52 57 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %> … … 69 74 try 70 75 { 76 final ItemQuery<PluginDefinition> pluginQuery = PluginDefinition.getQuery(); 77 pluginQuery.include(cc.getInclude()); 78 pluginQuery.join(Hql.innerJoin("jobAgentSettings", Item.JOBAGENTSETTINGS.getAlias())); 79 pluginQuery.restrict(Restrictions.eq(Hql.property(Item.JOBAGENTSETTINGS.getAlias(), "jobAgent"), Expressions.parameter("agent"))); 80 pluginQuery.order(Orders.asc(Hql.property("name"))); 81 71 82 Map<Plugin.MainType, Integer> pluginCount = PluginDefinition.countPlugins(dc, guiContext); 72 83 try … … 151 162 Table.presetOnChange('<%=ID%>', formId, '<%=itemType.name()%>', '<%=(String)cc.getObject("defaultColumns")%>'); 152 163 } 164 function controlJobAgents(cmd) 165 { 166 var frm = document.forms[formId]; 167 if (Forms.numChecked(frm) == 0) 168 { 169 alert('Please select at least one item in the list'); 170 return; 171 } 172 frm.action = submitPage; 173 frm.cmd.value = cmd; 174 frm.submit(); 175 } 153 176 </script> 154 177 </base:head> … … 313 336 tooltip="Run a plugin" 314 337 visible="<%=pluginCount.containsKey(Plugin.MainType.OTHER)%>" 338 /> 339 <tbl:button 340 image="pause.png" 341 onclick="controlJobAgents('PauseSelected')" 342 title="Pause" 343 tooltip="Pause the selected job agents" 344 /> 345 <tbl:button 346 image="start.png" 347 onclick="controlJobAgents('StartSelected')" 348 title="Start" 349 tooltip="Start the selected job agents" 315 350 /> 316 351 </tbl:toolbar> … … 426 461 Used memory: <%=item.getUsedMemory() == null ? "<i>- unknown -</i>" : Values.formatBytes(item.getUsedMemory()) %> 427 462 </tbl:cell> 428 <tbl:cell column="jobs">TODO</tbl:cell> 429 <tbl:cell column="plugins">TODO</tbl:cell> 463 <tbl:cell column="jobs"> 464 <% 465 Set<Integer> jobs = item.getInfo().getJobs(); 466 if (jobs == null || jobs.size() == 0) 467 { 468 %> 469 <i>- none -</i> 470 <% 471 } 472 else 473 { 474 String separator = ""; 475 for (int jobId : jobs) 476 { 477 try 478 { 479 Job job = Job.getById(dc, jobId); 480 out.write(separator); 481 if (mode.hasPropertyLink()) 482 { 483 out.write(Base.getLinkedName(ID, job, false, mode.hasEditLink()) + 484 " (" + job.getPercentComplete() + "%)"); 485 } 486 else 487 { 488 out.write(HTML.encodeTags(job.getName()) + 489 " (" + job.getPercentComplete() + "%)"); 490 } 491 separator = ", "; 492 } 493 catch (Throwable t) 494 { 495 %> 496 <div class="error"><%=t.getMessage()%></div> 497 <% 498 } 499 } 500 } 501 %> 502 </tbl:cell> 503 <tbl:cell column="plugins"> 504 <% 505 pluginQuery.setParameter("agent", itemId, Type.INT); 506 try 507 { 508 String separator = ""; 509 for (PluginDefinition p : pluginQuery.list(dc)) 510 { 511 out.write(separator); 512 if (mode.hasPropertyLink()) 513 { 514 out.write(Base.getLink(ID, p.getName(), Item.PLUGINDEFINITION, p.getId(), mode.hasEditLink())); 515 } 516 else 517 { 518 out.write(HTML.encodeTags(p.getName())); 519 } 520 separator = ", "; 521 } 522 } 523 catch (Throwable t) 524 { 525 %> 526 <div class="error"><%=t.getMessage()%></div> 527 <% 528 } 529 %> 530 </tbl:cell> 430 531 <tbl:cell column="owner" 431 532 ><base:propertyvalue -
trunk/www/admin/jobagents/view_agent.jsp
r2631 r2648 32 32 import="net.sf.basedb.core.ItemContext" 33 33 import="net.sf.basedb.core.Permission" 34 import="net.sf.basedb.core.Job" 34 35 import="net.sf.basedb.core.JobAgent" 35 36 import="net.sf.basedb.core.JobAgentSettings" 37 import="net.sf.basedb.util.jobagent.JobAgentInfo" 36 38 import="net.sf.basedb.core.User" 37 39 import="net.sf.basedb.core.PermissionDeniedException" … … 49 51 import="net.sf.basedb.clients.web.util.NameablePluginAdaptor" 50 52 import="java.util.Map" 53 import="java.util.Set" 51 54 %> 52 55 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %> … … 72 75 JobAgent agent = JobAgent.getById(dc, itemId); 73 76 77 JobAgentInfo info = agent.getInfo(); 78 Boolean paused = info.isPaused(); 79 74 80 final boolean writePermission = agent.hasPermission(Permission.WRITE); 75 81 final boolean deletePermission = agent.hasPermission(Permission.DELETE); … … 78 84 79 85 <base:page title="<%=title%>"> 80 <base:head scripts="tabcontrol.js,table.js" styles="toolbar.css,headertabcontrol.css,path.css,table.css ">86 <base:head scripts="tabcontrol.js,table.js" styles="toolbar.css,headertabcontrol.css,path.css,table.css,progressbar.css"> 81 87 <script language="JavaScript"> 82 88 function editItem() … … 99 105 { 100 106 Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, true, '&plugin_id='+pluginId); 107 } 108 function controlJobAgent(cmd) 109 { 110 location.href = 'index.jsp?ID=<%=ID%>&cmd='+cmd+'&item_id=<%=itemId%>'; 101 111 } 102 112 </script> … … 166 176 /> 167 177 <tbl:button 178 image="start.png" 179 onclick="controlJobAgent('Start')" 180 title="Start" 181 tooltip="Start the job agent" 182 visible="<%=writePermission && paused != null && paused == true%>" 183 /> 184 <tbl:button 185 image="pause.png" 186 onclick="controlJobAgent('Pause')" 187 title="Pause" 188 tooltip="Pause the job agent" 189 visible="<%=writePermission && paused != null && paused == false%>" 190 /> 191 <tbl:button 168 192 image="help.gif" 169 193 onclick="<%="Main.openHelp('" + ID +"', 'jobagent.view.properties')"%>" … … 173 197 </tbl:toolbar> 174 198 <div class="boxedbottom"> 199 <% 200 if (cc.getMessage() != null) 201 { 202 %> 203 <div class="error"><%=cc.getMessage()%></div> 204 <% 205 cc.setMessage(null); 206 } 207 %> 208 175 209 <div class="itemstatus">Permissions on this item: <i><%=PermissionUtil.getFullPermissionNames(agent)%></i></div> 176 210 <div class="itemstatus"> … … 201 235 </tr> 202 236 <tr> 237 <td class="prompt">Status</td> 238 <td> 239 <%=paused == null ? "<i>- unknown -</i>" : paused == true ? "Paused" : "Running"%> 240 </td> 241 </tr> 242 <tr> 203 243 <td class="prompt">CPU usage</td> 204 <td><%= agent.getCpuUsage() == null ? "<i>- unknown -</i>" : agent.getCpuUsage() + "%"%></td>244 <td><%=info.getCpuUsage() == null ? "<i>- unknown -</i>" : info.getCpuUsage() + "%"%></td> 205 245 </tr> 206 246 <tr> 207 247 <td class="prompt">Memory</td> 208 248 <td> 209 Total: <%= agent.getTotalMemory() == null ? "<i>- unknown -</i>" : Values.formatBytes(agent.getTotalMemory())%>,210 Used: <%= agent.getUsedMemory() == null ? "<i>- unknown -</i>" : Values.formatBytes(agent.getUsedMemory())%>249 Total: <%=info.getTotalMemory() == null ? "<i>- unknown -</i>" : Values.formatBytes(info.getTotalMemory())%>, 250 Used: <%=info.getUsedMemory() == null ? "<i>- unknown -</i>" : Values.formatBytes(info.getUsedMemory())%> 211 251 </td> 212 252 </tr> … … 315 355 } 316 356 %> 357 358 <% 359 Set<Integer> jobs = agent.getInfo().getJobs(); 360 if (jobs == null || jobs.size() == 0) 361 { 362 %> 363 <h4>Executing jobs</h4> 364 <% 365 if (jobs == null) 366 { 367 %> 368 Unknown 369 <% 370 } 371 else 372 { 373 %> 374 No jobs are currently executing on this job agent 375 <% 376 } 377 } 378 else 379 { 380 %> 381 <h4 class="docked">Executing jobs</h4> 382 <tbl:table 383 id="jobs" 384 clazz="itemlist" 385 columns="all" 386 > 387 <tbl:columndef 388 id="job" 389 title="Job" 390 /> 391 <tbl:columndef 392 id="plugin" 393 title="Plugin" 394 /> 395 <tbl:columndef 396 id="started" 397 title="Started" 398 /> 399 <tbl:columndef 400 id="percentComplete" 401 title="Percent complete" 402 /> 403 <tbl:columndef 404 id="owner" 405 title="Owner" 406 /> 407 <tbl:data> 408 <tbl:columns> 409 </tbl:columns> 410 <tbl:rows> 411 <% 412 for (int jobId : jobs) 413 { 414 Job job = null; 415 boolean readJob = true; 416 try 417 { 418 job = Job.getById(dc, jobId); 419 } 420 catch (Throwable t) 421 { 422 readJob = false; 423 } 424 %> 425 <tbl:row> 426 <tbl:cell column="job"><%=Base.getLinkedName(ID, job, !readJob, true) %></tbl:cell> 427 <tbl:cell column="plugin"><base:propertyvalue item="<%=job%>" property="pluginDefinition"/></tbl:cell> 428 <tbl:cell column="started"><%=job == null ? "" : Values.formatDateTime(job.getStarted())%></tbl:cell> 429 <tbl:cell column="percentComplete"> 430 <% 431 if (job != null) 432 { 433 %> 434 <table border=0 cellspacing=0 cellpadding=0> 435 <tr> 436 <td width="100"> 437 <table width="100" class="progressbar" border=0 cellspacing=0 cellpadding=0> 438 <tr> 439 <% 440 int percent = job.getPercentComplete(); 441 if (percent > 0) 442 { 443 %> 444 <td width="<%=percent%>%" class="done"> </td> 445 <% 446 } 447 if (percent < 100) 448 { 449 %> 450 <td width="<%=100-percent%>%" class="remain"> </td> 451 <% 452 } 453 %> 454 </tr> 455 </table> 456 </td> 457 <td> <%=percent%>%</td> 458 </tr> 459 </table> 460 <% 461 } 462 %> 463 </tbl:cell> 464 <tbl:cell column="owner"><base:propertyvalue item="<%=job%>" property="owner" /></tbl:cell> 465 </tbl:row> 466 <% 467 } 468 %> 469 </tbl:rows> 470 </tbl:data> 471 </tbl:table> 472 <% 473 } 474 %> 475 317 476 </div> 318 477 </t:tab> -
trunk/www/common/import/index.jsp
r2512 r2648 107 107 for (PluginConfiguration pluginConfig : configQuery.list(dc)) 108 108 { 109 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, sc, pluginConfig, null);109 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, null, sc, pluginConfig, null); 110 110 String contextMessage = null; 111 111 try … … 134 134 else if (!plugin.requiresConfiguration()) 135 135 { 136 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, sc, null, null);136 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, null, sc, null, null); 137 137 String contextMessage = null; 138 138 try -
trunk/www/common/import/select_plugin.jsp
r2512 r2648 213 213 } 214 214 %> 215 <tr valign="top">216 <td class="prompt">Job name</td>217 <td><input type="text" class="text"218 name="job_name" value="<%=HTML.encodeTags(jobName)%>" size="40" maxlength="<%=Job.MAX_NAME_LENGTH%>">219 </td>220 </tr>221 <tr valign=top>222 <td class="prompt">Job description</td>223 <td nowrap>224 <textarea class="text" rows="4" cols="40" name="job_description" wrap="virtual"225 ></textarea>226 <a href="javascript:Main.zoom('Job description', 'plugin', 'job_description')"227 title="Edit in larger window"><base:icon image="zoom.gif" /></a>228 </td>229 </tr>230 215 </table> 231 216 <div align=right> <i><base:icon image="required.gif" /> = required information</i></div> -
trunk/www/common/plugin/finish_job.jsp
r2643 r2648 63 63 PluginDefinition plugin = (PluginDefinition)sc.getSessionSetting("plugin.configure.plugin"); 64 64 PluginConfiguration pluginConfig = (PluginConfiguration)sc.getSessionSetting("plugin.configure.config"); 65 boolean sendMessage = Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), true); 65 66 %> 66 67 <base:page type="popup" title="Set job name and options"> … … 118 119 <td class="prompt">Send message</td> 119 120 <td> 120 <input type="checkbox" name="send_message" value="1" checked>121 <input type="checkbox" name="send_message" value="1" <%=sendMessage ? "checked" : "" %>> 121 122 <a href="javascript:document.forms['plugin'].send_message.click();">Send a message when the job is completed</a> 122 123 </td> -
trunk/www/common/plugin/index.jsp
r2643 r2648 141 141 for (PluginConfiguration pluginConfig : configQuery.list(dc)) 142 142 { 143 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, sc, pluginConfig, null);143 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, null, sc, pluginConfig, null); 144 144 String contextMessage = null; 145 145 try … … 167 167 else if (!plugin.requiresConfiguration()) 168 168 { 169 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, sc, null, null);169 InteractivePlugin ip = plugin.newInstance(InteractivePlugin.class, null, sc, null, null); 170 170 String contextMessage = null; 171 171 try -
trunk/www/footnote.jsp
r2474 r2648 59 59 try 60 60 { 61 if (sc != null && sc.isLoggedIn()) numNewMessages = Message.countUnreadMessages(dc, null );61 if (sc != null && sc.isLoggedIn()) numNewMessages = Message.countUnreadMessages(dc, null, false); 62 62 %> 63 63 <base:page type="popup" title=""> -
trunk/www/my_base/user/preferences.jsp
r2596 r2648 84 84 return true; 85 85 } 86 function validatePlugins() 87 { 88 return true; 89 } 86 90 // Changes the scale value 87 91 function setScale(newScale) … … 110 114 <t:tabcontrol active="<%=activePage%>" id="settings" contentstyle="<%="height: "+(int)(scale*160)+"px;"%>" 111 115 position="bottom"> 112 <t:tab id="appearance" title="Appearance" validate="validateAppearance()" helpid="userpreferences.appearance"> 116 <t:tab 117 id="appearance" 118 title="Appearance" 119 validate="validateAppearance()" 120 helpid="userpreferences.appearance" 121 > 113 122 <table class="form" cellspacing=0> 114 123 <tr> … … 118 127 String fontsize = Values.getString(sc.getUserClientSetting("appearance.fontsize"), "size_m.css"); 119 128 %> 120 <input type="radio" name="fontsize" value="size_xs.css" <%="size_xs.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(80)">XS 121 <input type="radio" name="fontsize" value="size_s.css" <%="size_s.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(90)">S 122 <input type="radio" name="fontsize" value="size_m.css" <%="size_m.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(100)">M 123 <input type="radio" name="fontsize" value="size_l.css" <%="size_l.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(120)">L 124 <input type="radio" name="fontsize" value="size_xl.css" <%="size_xl.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(140)">XL 129 <input type="radio" name="fontsize" value="size_xs.css" 130 <%="size_xs.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(80)" 131 ><a href="javascript:document.forms['preferences'].fontsize[0].click()">XS</a> 132 <input type="radio" name="fontsize" value="size_s.css" 133 <%="size_s.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(90)" 134 ><a href="javascript:document.forms['preferences'].fontsize[1].click()">S</a> 135 <input type="radio" name="fontsize" value="size_m.css" 136 <%="size_m.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(100)" 137 ><a href="javascript:document.forms['preferences'].fontsize[2].click()">M</a> 138 <input type="radio" name="fontsize" value="size_l.css" 139 <%="size_l.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(120)" 140 ><a href="javascript:document.forms['preferences'].fontsize[3].click()">L</a> 141 <input type="radio" name="fontsize" value="size_xl.css" 142 <%="size_xl.css".equals(fontsize) ? "checked" : ""%> onclick="setScale(140)" 143 ><a href="javascript:document.forms['preferences'].fontsize[4].click()">XL</a> 125 144 </td> 126 145 </tr> … … 137 156 <td class="prompt">Toolbar</td> 138 157 <td> 139 <input type="radio" name="toolbar" value="both" <%=hasImages && hasText ? "checked" : "" %>>Images and text 140 <input type="radio" name="toolbar" value="images" <%=hasImages && !hasText ? "checked" : "" %>>Images only 141 <input type="radio" name="toolbar" value="text" <%=!hasImages && hasText ? "checked" : "" %>>Text only 158 <input type="radio" name="toolbar" value="both" 159 <%=hasImages && hasText ? "checked" : "" %> 160 ><a href="javascript:document.forms['preferences'].toolbar[0].click()">Images and text</a> 161 <input type="radio" name="toolbar" value="images" 162 <%=hasImages && !hasText ? "checked" : "" %> 163 ><a href="javascript:document.forms['preferences'].toolbar[1].click()">Images only</a> 164 <input type="radio" name="toolbar" value="text" 165 <%=!hasImages && hasText ? "checked" : "" %> 166 ><a href="javascript:document.forms['preferences'].toolbar[2].click()">Text only</a> 142 167 </td> 143 168 </tr> … … 154 179 <div align="right"> <i><base:icon image="required.gif" /> = required information</i></div> 155 180 </t:tab> 181 182 <t:tab 183 id="plugins" 184 title="Plugins" 185 validate="validatePlugins()" 186 helpid="userpreferences.plugins" 187 > 188 <table class="form" cellspacing=0> 189 <tr> 190 <td class="prompt">Messages</td> 191 <td> 192 <% 193 boolean sendMessage = Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), true); 194 %> 195 <input type=checkbox name="sendmessage" value="1" <%=sendMessage ? "checked" : ""%> 196 ><a href="javascript:document.forms['preferences'].sendmessage.click()">Send message when plugin completes</a> 197 </td> 198 </tr> 199 </table> 200 </t:tab> 201 156 202 </t:tabcontrol> 157 203 -
trunk/www/my_base/user/submit_user.jsp
r2304 r2648 104 104 sc.setUserClientSetting("toolbar.text", hasText ? "1" : "0"); 105 105 106 sc.setUserClientSetting("plugins.sendmessage", Values.getString(request.getParameter("sendmessage"), "0")); 107 106 108 message = "Preferences saved"; 107 109 } -
trunk/www/views/jobs/view_job.jsp
r2643 r2648 86 86 readCurrentOwner = false; 87 87 } 88 final boolean autoUpdate = job.getStatus() == Job.Status.WAITING || job.getStatus() == Job.Status.EXECUTING; 88 final Job.Status status = job.getStatus(); 89 final boolean autoUpdate = status == Job.Status.WAITING || 90 status == Job.Status.PREPARED || status == Job.Status.EXECUTING; 89 91 %> 90 92 … … 296 298 </table> 297 299 </t:tab> 298 299 300 </t:tabcontrol> 300 301 301 302 <base:buttongroup align="center"> 302 303 <% 303 if ( job.getStatus() == Job.Status.WAITING || job.getStatus() == Job.Status.EXECUTING)304 if (autoUpdate) 304 305 { 305 306 %> … … 309 310 %> 310 311 <% 311 if (job.getStatus() == Job.Status.ERROR && sc.hasPermission(Permission.CREATE, Item.PLUGINDEFINITION))312 if (job.getStatus() == Job.Status.ERROR) 312 313 { 313 314 %> … … 321 322 <center> 322 323 <% 323 if ( job.getStatus() == Job.Status.WAITING || job.getStatus() == Job.Status.EXECUTING)324 if (autoUpdate) 324 325 { 325 326 %>
Note: See TracChangeset
for help on using the changeset viewer.