|
Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobPoller.java
URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobPoller.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobPoller.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/JobPoller.java Thu Oct 25 05:04:09 2012 @@ -19,204 +19,278 @@ package org.ofbiz.service.job; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import org.ofbiz.base.start.Start; +import org.ofbiz.base.util.Assert; import org.ofbiz.base.util.Debug; import org.ofbiz.service.config.ServiceConfigUtil; -import org.apache.commons.lang.math.NumberUtils; - /** - * JobPoller - Polls for persisted jobs to run. + * Job poller. Queues and runs jobs. */ -public final class JobPoller implements Runnable { +public final class JobPoller { public static final String module = JobPoller.class.getName(); - public static final int MIN_THREADS = 1; - public static final int MAX_THREADS = 15; - public static final int POLL_WAIT = 20000; - public static final long THREAD_TTL = 18000000; - - private final JobManager jm; - private final ThreadPoolExecutor executor; - private final String name; - private boolean enabled = false; + private static final AtomicInteger created = new AtomicInteger(); + private static final int MIN_THREADS = 1; // Must be no less than one or the executor will shut down. + private static final int MAX_THREADS = 5; // Values higher than 5 might slow things down. + private static final int POLL_WAIT = 30000; // Database polling interval - 30 seconds. + private static final int QUEUE_SIZE = 100; + private static final long THREAD_TTL = 120000; // Idle thread lifespan - 2 minutes. + private static final ConcurrentHashMap<String, JobManager> jobManagers = new ConcurrentHashMap<String, JobManager>(); + private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(minThreads(), maxThreads(), getTTL(), + TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(queueSize()), new JobInvokerThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); + private static final JobPoller instance = new JobPoller(); /** - * Creates a new JobScheduler - * - * @param jm - * JobManager associated with this scheduler + * Returns the <code>JobPoller</code> instance. */ - public JobPoller(JobManager jm) { - this.name = jm.getDelegator().getDelegatorName(); - this.jm = jm; - this.executor = new ThreadPoolExecutor(minThreads(), maxThreads(), getTTL(), TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), - new JobInvokerThreadFactory(this.name), new ThreadPoolExecutor.AbortPolicy()); - } - - public synchronized void enable() { - if (!enabled) { - enabled = true; - // start the thread only if polling is enabled - if (pollEnabled()) { - // create the poller thread - Thread thread = new Thread(this, "OFBiz-JobPoller-" + this.name); - thread.setDaemon(false); - // start the poller - thread.start(); + public static JobPoller getInstance() { + return instance; + } + + private static long getTTL() { + String threadTTLAttr = ServiceConfigUtil.getElementAttr("thread-pool", "ttl"); + if (!threadTTLAttr.isEmpty()) { + try { + int threadTTL = Integer.parseInt(threadTTLAttr); + if (threadTTL > 0) { + return threadTTL; + } + } catch (NumberFormatException e) { + Debug.logError("Exception thrown while parsing thread TTL from serviceengine.xml file [" + e + "]. Using default value.", module); } } + return THREAD_TTL; + } + + private static int maxThreads() { + String maxThreadsAttr = ServiceConfigUtil.getElementAttr("thread-pool", "max-threads"); + if (!maxThreadsAttr.isEmpty()) { + try { + int maxThreads = Integer.parseInt(maxThreadsAttr); + if (maxThreads > 0) { + return maxThreads; + } + } catch (NumberFormatException e) { + Debug.logError("Exception thrown while parsing maximum threads from serviceengine.xml file [" + e + "]. Using default value.", module); + } + } + return MAX_THREADS; + } + + private static int minThreads() { + String minThreadsAttr = ServiceConfigUtil.getElementAttr("thread-pool", "min-threads"); + if (!minThreadsAttr.isEmpty()) { + try { + int minThreads = Integer.parseInt(minThreadsAttr); + if (minThreads > 0) { + return minThreads; + } + } catch (NumberFormatException e) { + Debug.logError("Exception thrown while parsing minimum threads from serviceengine.xml file [" + e + "]. Using default value.", module); + } + } + return MIN_THREADS; + } + + private static int pollWaitTime() { + String pollIntervalAttr = ServiceConfigUtil.getElementAttr("thread-pool", "poll-db-millis"); + if (!pollIntervalAttr.isEmpty()) { + try { + int pollInterval = Integer.parseInt(pollIntervalAttr); + if (pollInterval > 0) { + return pollInterval; + } + } catch (NumberFormatException e) { + Debug.logError("Exception thrown while parsing database polling interval from serviceengine.xml file [" + e + "]. Using default value.", module); + } + } + return POLL_WAIT; + } + + private static int queueSize() { + String queueSizeAttr = ServiceConfigUtil.getElementAttr("thread-pool", "jobs"); + if (!queueSizeAttr.isEmpty()) { + try { + int queueSize = Integer.parseInt(queueSizeAttr); + if (queueSize > 0) { + return queueSize; + } + } catch (NumberFormatException e) { + Debug.logError("Exception thrown while parsing queue size from serviceengine.xml file [" + e + "]. Using default value.", module); + } + } + return QUEUE_SIZE; } /** - * Returns the JobManager + * Register a {@link JobManager} with the job poller. + * + * @param jm The <code>JobManager</code> to register. + * @throws IllegalArgumentException if <code>jm</code> is null */ - public JobManager getManager() { - return jm; + public static void registerJobManager(JobManager jm) { + Assert.notNull("jm", jm); + jobManagers.putIfAbsent(jm.getDelegator().getDelegatorName(), jm); + } + + // -------------------------------------- // + + private final Thread jobManagerPollerThread; + + private JobPoller() { + if (pollEnabled()) { + jobManagerPollerThread = new Thread(new JobManagerPoller(), "OFBiz-JobPoller"); + jobManagerPollerThread.setDaemon(false); + jobManagerPollerThread.start(); + } else { + jobManagerPollerThread = null; + } } + /** + * Returns a <code>Map</code> containing <code>JobPoller</code> statistics. + */ public Map<String, Object> getPoolState() { Map<String, Object> poolState = new HashMap<String, Object>(); - poolState.put("pollerName", this.name); - poolState.put("pollerThreadName", "OFBiz-JobPoller-" + this.name); - poolState.put("invokerThreadNameFormat", "OFBiz-JobInvoker-" + this.name + "-<SEQ>"); - poolState.put("keepAliveTimeInSeconds", this.executor.getKeepAliveTime(TimeUnit.SECONDS)); - poolState.put("numberOfCoreInvokerThreads", this.executor.getCorePoolSize()); - poolState.put("currentNumberOfInvokerThreads", this.executor.getPoolSize()); - poolState.put("numberOfActiveInvokerThreads", this.executor.getActiveCount()); - poolState.put("maxNumberOfInvokerThreads", this.executor.getMaximumPoolSize()); - poolState.put("greatestNumberOfInvokerThreads", this.executor.getLargestPoolSize()); - poolState.put("numberOfCompletedTasks", this.executor.getCompletedTaskCount()); - BlockingQueue<Runnable> queue = this.executor.getQueue(); + poolState.put("keepAliveTimeInSeconds", executor.getKeepAliveTime(TimeUnit.SECONDS)); + poolState.put("numberOfCoreInvokerThreads", executor.getCorePoolSize()); + poolState.put("currentNumberOfInvokerThreads", executor.getPoolSize()); + poolState.put("numberOfActiveInvokerThreads", executor.getActiveCount()); + poolState.put("maxNumberOfInvokerThreads", executor.getMaximumPoolSize()); + poolState.put("greatestNumberOfInvokerThreads", executor.getLargestPoolSize()); + poolState.put("numberOfCompletedTasks", executor.getCompletedTaskCount()); + BlockingQueue<Runnable> queue = executor.getQueue(); List<Map<String, Object>> taskList = new ArrayList<Map<String, Object>>(); Map<String, Object> taskInfo = null; for (Runnable task : queue) { - JobInvoker jobInvoker = (JobInvoker) task; + Job job = (Job) task; taskInfo = new HashMap<String, Object>(); - taskInfo.put("id", jobInvoker.getJobId()); - taskInfo.put("name", jobInvoker.getJobName()); - taskInfo.put("serviceName", jobInvoker.getServiceName()); - taskInfo.put("time", jobInvoker.getTime()); - taskInfo.put("runtime", jobInvoker.getCurrentRuntime()); + taskInfo.put("id", job.getJobId()); + taskInfo.put("name", job.getJobName()); + String serviceName = ""; + if (job instanceof GenericServiceJob) { + serviceName = ((GenericServiceJob) job).getServiceName(); + } + taskInfo.put("serviceName", serviceName); + taskInfo.put("time", job.getStartTime()); + taskInfo.put("runtime", job.getRuntime()); taskList.add(taskInfo); } poolState.put("taskList", taskList); return poolState; } - private long getTTL() { - long ttl = THREAD_TTL; - try { - ttl = NumberUtils.toLong(ServiceConfigUtil.getElementAttr("thread-pool", "ttl")); - } catch (NumberFormatException nfe) { - Debug.logError("Problems reading value from attribute [ttl] of element [thread-pool] in serviceengine.xml file [" + nfe.toString() + "]. Using default (" + THREAD_TTL + ").", module); - } - return ttl; + private boolean pollEnabled() { + String enabled = ServiceConfigUtil.getElementAttr("thread-pool", "poll-enabled"); + return !"false".equalsIgnoreCase(enabled); } - private int maxThreads() { - int max = MAX_THREADS; + /** + * Adds a job to the job queue. + * @throws InvalidJobException if the job is in an invalid state. + * @throws RejectedExecutionException if the poller is stopped. + */ + public void queueNow(Job job) throws InvalidJobException { + job.queue(); try { - max = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "max-threads")); - } catch (NumberFormatException nfe) { - Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.", module); + executor.execute(job); + } catch (Exception e) { + job.deQueue(); } - return max; } - private int minThreads() { - int min = MIN_THREADS; - try { - min = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "min-threads")); - } catch (NumberFormatException nfe) { - Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.", module); + /** + * Stops the <code>JobPoller</code>. This method is called when OFBiz shuts down. + * The <code>JobPoller</code> cannot be restarted. + */ + public void stop() { + Debug.logInfo("Shutting down JobPoller.", module); + if (jobManagerPollerThread != null) { + jobManagerPollerThread.interrupt(); } - return min; + List<Runnable> queuedJobs = executor.shutdownNow(); + for (Runnable task : queuedJobs) { + try { + Job queuedJob = (Job) task; + queuedJob.deQueue(); + } catch (Exception e) { + Debug.logWarning(e, module); + } + } + Debug.logInfo("JobPoller shutdown completed.", module); } - private boolean pollEnabled() { - String enabled = ServiceConfigUtil.getElementAttr("thread-pool", "poll-enabled"); - if (enabled.equalsIgnoreCase("false")) - return false; - return true; - } + private static class JobInvokerThreadFactory implements ThreadFactory { - private int pollWaitTime() { - int poll = POLL_WAIT; - try { - poll = Integer.parseInt(ServiceConfigUtil.getElementAttr("thread-pool", "poll-db-millis")); - } catch (NumberFormatException nfe) { - Debug.logError("Problems reading values from serviceengine.xml file [" + nfe.toString() + "]. Using defaults.", module); + public Thread newThread(Runnable runnable) { + return new Thread(runnable, "OFBiz-JobQueue-" + created.getAndIncrement()); } - return poll; } - /** - * Adds a job to the RUN queue. - * @throws RejectedExecutionException if the poller is stopped. - */ - public void queueNow(Job job) { - this.executor.execute(new JobInvoker(job)); - } + // Polls all registered JobManagers for jobs to queue. + private class JobManagerPoller implements Runnable { - public synchronized void run() { - try { - // wait 30 seconds before the first poll - java.lang.Thread.sleep(30000); - } catch (InterruptedException e) { - } - while (!executor.isShutdown()) { - try { - // grab a list of jobs to run. - List<Job> pollList = jm.poll(); - // Debug.logInfo("Received poll list from JobManager [" + pollList.size() + "]", module); - for (Job job : pollList) { - if (job.isValid()) { - queueNow(job); - // Debug.logInfo("Job [" + job.getJobId() + "] is queued", module); + // Do not check for interrupts in this method. The design requires the + // thread to complete the job manager poll uninterrupted. + public void run() { + Debug.logInfo("JobPoller thread started.", module); + try { + while (Start.getInstance().getCurrentState() != Start.ServerState.RUNNING) { + Thread.sleep(1000); + } + while (!executor.isShutdown()) { + int remainingCapacity = executor.getQueue().remainingCapacity(); + if (remainingCapacity > 0) { + // Build "list of lists" + Collection<JobManager> jmCollection = jobManagers.values(); + List<Iterator<Job>> pollResults = new ArrayList<Iterator<Job>>(); + for (JobManager jm : jmCollection) { + pollResults.add(jm.poll(remainingCapacity).iterator()); + } + // Create queue candidate list from "list of lists" + List<Job> queueCandidates = new ArrayList<Job>(); + boolean addingJobs = true; + while (addingJobs) { + addingJobs = false; + for (Iterator<Job> jobIterator : pollResults) { + if (jobIterator.hasNext()) { + queueCandidates.add(jobIterator.next()); + addingJobs = true; + } + } + } + // The candidate list might be larger than the queue remaining capacity, + // but that is okay - the excess jobs will be dequeued and rescheduled. + for (Job job : queueCandidates) { + try { + queueNow(job); + } catch (InvalidJobException e) { + Debug.logError(e, module); + } + } } + Thread.sleep(pollWaitTime()); } - // NOTE: using sleep instead of wait for stricter locking - java.lang.Thread.sleep(pollWaitTime()); } catch (InterruptedException e) { - Debug.logError(e, module); - stop(); + // Happens when JobPoller shuts down - nothing to do. + Thread.currentThread().interrupt(); } + Debug.logInfo("JobPoller thread stopped.", module); } - Debug.logInfo("JobPoller " + this.name + " thread terminated.", module); - } - - /** - * Stops the JobPoller - */ - void stop() { - Debug.logInfo("Shutting down thread pool for JobPoller " + this.name, module); - this.executor.shutdown(); - try { - // Wait 60 seconds for existing tasks to terminate - if (!this.executor.awaitTermination(60, TimeUnit.SECONDS)) { - // abrupt shutdown (cancel currently executing tasks) - Debug.logInfo("Attempting abrupt shut down of thread pool for JobPoller " + this.name, module); - this.executor.shutdownNow(); - // Wait 60 seconds for tasks to respond to being cancelled - if (!this.executor.awaitTermination(60, TimeUnit.SECONDS)) { - Debug.logWarning("Unable to shutdown the thread pool for JobPoller " + this.name, module); - } - } - } catch (InterruptedException ie) { - // re cancel if current thread was also interrupted - this.executor.shutdownNow(); - // preserve interrupt status - Thread.currentThread().interrupt(); - } - Debug.logInfo("Shutdown completed of thread pool for JobPoller " + this.name, module); } } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java Thu Oct 25 05:04:09 2012 @@ -20,7 +20,6 @@ package org.ofbiz.service.job; import java.io.IOException; import java.sql.Timestamp; -import com.ibm.icu.util.Calendar; import java.util.Date; import java.util.Map; @@ -28,13 +27,11 @@ import javax.xml.parsers.ParserConfigura import javolution.util.FastMap; +import org.apache.commons.lang.StringUtils; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilDateTime; import org.ofbiz.base.util.UtilGenerics; -import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilValidate; -import org.ofbiz.service.calendar.TemporalExpression; -import org.ofbiz.service.calendar.TemporalExpressionWorker; import org.ofbiz.entity.Delegator; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.GenericValue; @@ -46,25 +43,31 @@ import org.ofbiz.service.DispatchContext import org.ofbiz.service.GenericRequester; import org.ofbiz.service.ServiceUtil; import org.ofbiz.service.calendar.RecurrenceInfo; +import org.ofbiz.service.calendar.RecurrenceInfoException; +import org.ofbiz.service.calendar.TemporalExpression; +import org.ofbiz.service.calendar.TemporalExpressionWorker; import org.ofbiz.service.config.ServiceConfigUtil; import org.xml.sax.SAXException; -import org.apache.commons.lang.StringUtils; +import com.ibm.icu.util.Calendar; /** - * Entity Service Job - Store => Schedule => Run + * A {@link Job} that is backed by the entity engine. Job data is stored + * in the JobSandbox entity. + * <p>When the job is queued, this object "owns" the entity value. Any external changes + * are ignored except the cancelDateTime field - jobs can be canceled after they are queued.</p> */ @SuppressWarnings("serial") public class PersistedServiceJob extends GenericServiceJob { public static final String module = PersistedServiceJob.class.getName(); - private transient Delegator delegator = null; - private Timestamp storedDate = null; + private final transient Delegator delegator; private long nextRecurrence = -1; - private long maxRetry = -1; - private long currentRetryCount = 0; - private boolean warningLogged = false; + private final long maxRetry; + private final long currentRetryCount; + private final GenericValue jobValue; + private final long startTime; /** * Creates a new PersistedServiceJob @@ -73,107 +76,102 @@ public class PersistedServiceJob extends * @param req */ public PersistedServiceJob(DispatchContext dctx, GenericValue jobValue, GenericRequester req) { - super(jobValue.getString("jobId"), jobValue.getString("jobName")); + super(dctx, jobValue.getString("jobId"), jobValue.getString("jobName"), null, null, req); this.delegator = dctx.getDelegator(); - this.requester = req; - this.dctx = dctx; - this.storedDate = jobValue.getTimestamp("runTime"); - this.runtime = storedDate.getTime(); + this.jobValue = jobValue; + Timestamp storedDate = jobValue.getTimestamp("runTime"); + this.startTime = storedDate.getTime(); this.maxRetry = jobValue.get("maxRetry") != null ? jobValue.getLong("maxRetry").longValue() : -1; Long retryCount = jobValue.getLong("currentRetryCount"); if (retryCount != null) { this.currentRetryCount = retryCount.longValue(); } else { // backward compatibility - this.currentRetryCount = PersistedServiceJob.getRetries(jobValue, this.delegator); + this.currentRetryCount = getRetries(this.delegator); } - - // Debug.logInfo("=============== New PersistedServiceJob, delegator from dctx is [" + dctx.getDelegator().getDelegatorName() + "] and delegator from jobValue is [" + jobValue.getDelegator().getDelegatorName() + "]", module); } @Override public void queue() throws InvalidJobException { super.queue(); - - // refresh the job object - GenericValue jobValue = null; try { - jobValue = this.getJob(); jobValue.refresh(); } catch (GenericEntityException e) { - runtime = -1; - throw new InvalidJobException("Unable to refresh Job object", e); + throw new InvalidJobException("Unable to refresh JobSandbox value", e); } - - // make sure it isn't already set/cancelled - if (runtime != -1) { - Timestamp cancelTime = jobValue.getTimestamp("cancelDateTime"); - Timestamp startTime = jobValue.getTimestamp("startDateTime"); - if (cancelTime != null || startTime != null) { - // job not available - runtime = -1; - throw new InvalidJobException("Job [" + getJobId() + "] is not available"); - - } else { - // set the start time to now - jobValue.set("startDateTime", UtilDateTime.nowTimestamp()); - jobValue.set("statusId", "SERVICE_RUNNING"); - try { - jobValue.store(); - } catch (GenericEntityException e) { - runtime = -1; - throw new InvalidJobException("Unable to set the startDateTime on the current job [" + getJobId() + "]; not running!", e); - - } + if (!JobManager.instanceId.equals(jobValue.getString("runByInstanceId"))) { + throw new InvalidJobException("Job has been accepted by a different instance"); + } + Timestamp cancelTime = jobValue.getTimestamp("cancelDateTime"); + Timestamp startTime = jobValue.getTimestamp("startDateTime"); + if (cancelTime != null || startTime != null) { + // job not available + throw new InvalidJobException("Job [" + getJobId() + "] is not available"); + } else { + jobValue.set("statusId", "SERVICE_QUEUED"); + try { + jobValue.store(); + } catch (GenericEntityException e) { + throw new InvalidJobException("Unable to set the startDateTime and statusId on the current job [" + getJobId() + "]; not running!", e); + } + if (Debug.verboseOn()) { + Debug.logVerbose("Placing job [" + getJobId() + "] in queue", module); } } } - /** - * @see org.ofbiz.service.job.GenericServiceJob#init() - */ @Override protected void init() throws InvalidJobException { super.init(); - - // configure any addition recurrences - GenericValue job = this.getJob(); + try { + jobValue.refresh(); + } catch (GenericEntityException e) { + throw new InvalidJobException("Unable to refresh JobSandbox value", e); + } + if (!JobManager.instanceId.equals(jobValue.getString("runByInstanceId"))) { + throw new InvalidJobException("Job has been accepted by a different instance"); + } + if (jobValue.getTimestamp("cancelDateTime") != null) { + // Job cancelled + throw new InvalidJobException("Job [" + getJobId() + "] was cancelled"); + } + jobValue.set("startDateTime", UtilDateTime.nowTimestamp()); + jobValue.set("statusId", "SERVICE_RUNNING"); + try { + jobValue.store(); + } catch (GenericEntityException e) { + throw new InvalidJobException("Unable to set the startDateTime and statusId on the current job [" + getJobId() + "]; not running!", e); + } + if (Debug.verboseOn()) { + Debug.logVerbose("Job [" + getJobId() + "] running", module); + } + // configure any additional recurrences long maxRecurrenceCount = -1; long currentRecurrenceCount = 0; TemporalExpression expr = null; - RecurrenceInfo recurrence = JobManager.getRecurrenceInfo(job); + RecurrenceInfo recurrence = getRecurrenceInfo(); if (recurrence != null) { - if (!this.warningLogged) { - Debug.logWarning("Persisted Job [" + getJobId() + "] references a RecurrenceInfo, recommend using TemporalExpression instead", module); - this.warningLogged = true; - } + Debug.logWarning("Persisted Job [" + getJobId() + "] references a RecurrenceInfo, recommend using TemporalExpression instead", module); currentRecurrenceCount = recurrence.getCurrentCount(); expr = RecurrenceInfo.toTemporalExpression(recurrence); } - if (expr == null && UtilValidate.isNotEmpty(job.getString("tempExprId"))) { + if (expr == null && UtilValidate.isNotEmpty(jobValue.getString("tempExprId"))) { try { - expr = TemporalExpressionWorker.getTemporalExpression(this.delegator, job.getString("tempExprId")); + expr = TemporalExpressionWorker.getTemporalExpression(this.delegator, jobValue.getString("tempExprId")); } catch (GenericEntityException e) { throw new RuntimeException(e.getMessage()); } } - - String instanceId = UtilProperties.getPropertyValue("general.properties", "unique.instanceId", "ofbiz0"); - if (!instanceId.equals(job.getString("runByInstanceId"))) { - throw new InvalidJobException("Job has been accepted by a different instance!"); - } - - if (job.get("maxRecurrenceCount") != null) { - maxRecurrenceCount = job.getLong("maxRecurrenceCount").longValue(); + if (jobValue.get("maxRecurrenceCount") != null) { + maxRecurrenceCount = jobValue.getLong("maxRecurrenceCount").longValue(); } - if (job.get("currentRecurrenceCount") != null) { - currentRecurrenceCount = job.getLong("currentRecurrenceCount").longValue(); + if (jobValue.get("currentRecurrenceCount") != null) { + currentRecurrenceCount = jobValue.getLong("currentRecurrenceCount").longValue(); } if (maxRecurrenceCount != -1) { currentRecurrenceCount++; - job.set("currentRecurrenceCount", currentRecurrenceCount); + jobValue.set("currentRecurrenceCount", currentRecurrenceCount); } - try { if (expr != null && (maxRecurrenceCount == -1 || currentRecurrenceCount <= maxRecurrenceCount)) { if (recurrence != null) { @@ -181,26 +179,25 @@ public class PersistedServiceJob extends } Calendar next = expr.next(Calendar.getInstance()); if (next != null) { - createRecurrence(job, next.getTimeInMillis(), false); + createRecurrence(next.getTimeInMillis(), false); } } } catch (GenericEntityException e) { - throw new RuntimeException(e.getMessage()); + throw new InvalidJobException(e); } if (Debug.infoOn()) Debug.logInfo("Job [" + getJobName() + "] Id [" + getJobId() + "] -- Next runtime: " + new Date(nextRecurrence), module); } - private void createRecurrence(GenericValue job, long next, boolean isRetryOnFailure) throws GenericEntityException { + private void createRecurrence(long next, boolean isRetryOnFailure) throws GenericEntityException { if (Debug.verboseOn()) Debug.logVerbose("Next runtime returned: " + next, module); - - if (next > runtime) { - String pJobId = job.getString("parentJobId"); + if (next > startTime) { + String pJobId = jobValue.getString("parentJobId"); if (pJobId == null) { - pJobId = job.getString("jobId"); + pJobId = jobValue.getString("jobId"); } - GenericValue newJob = GenericValue.create(job); + GenericValue newJob = GenericValue.create(jobValue); newJob.remove("jobId"); - newJob.set("previousJobId", job.getString("jobId")); + newJob.set("previousJobId", jobValue.getString("jobId")); newJob.set("parentJobId", pJobId); newJob.set("statusId", "SERVICE_PENDING"); newJob.set("startDateTime", null); @@ -217,20 +214,12 @@ public class PersistedServiceJob extends } } - /** - * @see org.ofbiz.service.job.GenericServiceJob#finish() - */ @Override protected void finish(Map<String, Object> result) throws InvalidJobException { super.finish(result); - // set the finish date - GenericValue job = getJob(); - String status = job.getString("statusId"); - if (status == null || "SERVICE_RUNNING".equals(status)) { - job.set("statusId", "SERVICE_FINISHED"); - } - job.set("finishDateTime", UtilDateTime.nowTimestamp()); + jobValue.set("statusId", "SERVICE_FINISHED"); + jobValue.set("finishDateTime", UtilDateTime.nowTimestamp()); String jobResult = null; if (ServiceUtil.isError(result)) { jobResult = StringUtils.substring(ServiceUtil.getErrorMessage(result), 0, 255); @@ -238,35 +227,29 @@ public class PersistedServiceJob extends jobResult = StringUtils.substring(ServiceUtil.makeSuccessMessage(result, "", "", "", ""), 0, 255); } if (UtilValidate.isNotEmpty(jobResult)) { - job.set("jobResult", jobResult); + jobValue.set("jobResult", jobResult); } try { - job.store(); + jobValue.store(); } catch (GenericEntityException e) { Debug.logError(e, "Cannot update the job [" + getJobId() + "] sandbox", module); } } - /** - * @see org.ofbiz.service.job.GenericServiceJob#failed(Throwable) - */ @Override protected void failed(Throwable t) throws InvalidJobException { super.failed(t); - - GenericValue job = getJob(); // if the job has not been re-scheduled; we need to re-schedule and run again if (nextRecurrence == -1) { if (this.canRetry()) { // create a recurrence Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); cal.add(Calendar.MINUTE, ServiceConfigUtil.getFailedRetryMin()); long next = cal.getTimeInMillis(); try { - createRecurrence(job, next, true); - } catch (GenericEntityException gee) { - Debug.logError(gee, "ERROR: Unable to re-schedule job [" + getJobId() + "] to re-run : " + job, module); + createRecurrence(next, true); + } catch (GenericEntityException e) { + Debug.logError(e, "Unable to re-schedule job [" + getJobId() + "]: ", module); } Debug.logInfo("Persisted Job [" + getJobId() + "] Failed Re-Scheduling : " + next, module); } else { @@ -274,50 +257,40 @@ public class PersistedServiceJob extends } } // set the failed status - job.set("statusId", "SERVICE_FAILED"); - job.set("finishDateTime", UtilDateTime.nowTimestamp()); - job.set("jobResult", StringUtils.substring(t.getMessage(), 0, 255)); + jobValue.set("statusId", "SERVICE_FAILED"); + jobValue.set("finishDateTime", UtilDateTime.nowTimestamp()); + jobValue.set("jobResult", StringUtils.substring(t.getMessage(), 0, 255)); try { - job.store(); + jobValue.store(); } catch (GenericEntityException e) { - Debug.logError(e, "Cannot update the job sandbox", module); + Debug.logError(e, "Cannot update the JobSandbox entity", module); } } - /** - * @see org.ofbiz.service.job.GenericServiceJob#getServiceName() - */ @Override - protected String getServiceName() throws InvalidJobException { - GenericValue jobObj = getJob(); - if (jobObj == null || jobObj.get("serviceName") == null) { + protected String getServiceName() { + if (jobValue == null || jobValue.get("serviceName") == null) { return null; } - return jobObj.getString("serviceName"); + return jobValue.getString("serviceName"); } - /** - * @see org.ofbiz.service.job.GenericServiceJob#getContext() - */ @Override protected Map<String, Object> getContext() throws InvalidJobException { Map<String, Object> context = null; try { - GenericValue jobObj = getJob(); - if (!UtilValidate.isEmpty(jobObj.getString("runtimeDataId"))) { - GenericValue contextObj = jobObj.getRelatedOne("RuntimeData", false); + if (!UtilValidate.isEmpty(jobValue.getString("runtimeDataId"))) { + GenericValue contextObj = jobValue.getRelatedOne("RuntimeData", false); if (contextObj != null) { context = UtilGenerics.checkMap(XmlSerializer.deserialize(contextObj.getString("runtimeInfo"), delegator), String.class, Object.class); } } - if (context == null) { context = FastMap.newInstance(); } - // check the runAsUser - if (!UtilValidate.isEmpty(jobObj.get("runAsUser"))) { - context.put("userLogin", ServiceUtil.getUserLogin(dctx, context, jobObj.getString("runAsUser"))); + if (!UtilValidate.isEmpty(jobValue.getString("runAsUser"))) { + context.put("userLogin", ServiceUtil.getUserLogin(dctx, context, jobValue.getString("runAsUser"))); } } catch (GenericEntityException e) { Debug.logError(e, "PersistedServiceJob.getContext(): Entity Exception", module); @@ -333,46 +306,70 @@ public class PersistedServiceJob extends if (context == null) { Debug.logError("Job context is null", module); } - return context; } - // gets the job value object - private GenericValue getJob() throws InvalidJobException { - try { - GenericValue jobObj = delegator.findOne("JobSandbox", false, "jobId", getJobId()); - - if (jobObj == null) { - throw new InvalidJobException("Job [" + getJobId() + "] came back null from datasource from delegator " + delegator.getDelegatorName()); - } - return jobObj; - } catch (GenericEntityException e) { - throw new InvalidJobException("Cannot get job definition [" + getJobId() + "] from entity", e); - } - } - // returns the number of current retries - private static long getRetries(GenericValue job, Delegator delegator) { - String pJobId = job.getString("parentJobId"); + private long getRetries(Delegator delegator) { + String pJobId = jobValue.getString("parentJobId"); if (pJobId == null) { return 0; } - long count = 0; try { EntityFieldMap ecl = EntityCondition.makeConditionMap("parentJobId", pJobId, "statusId", "SERVICE_FAILED"); count = delegator.findCountByCondition("JobSandbox", ecl, null, null); } catch (GenericEntityException e) { - Debug.logError(e, module); + Debug.logError(e, "Exception thrown while counting retries: ", module); } - return count + 1; // add one for the parent } - private boolean canRetry() throws InvalidJobException { + private boolean canRetry() { if (maxRetry == -1) { return true; } return currentRetryCount < maxRetry; } + + private RecurrenceInfo getRecurrenceInfo() { + try { + if (UtilValidate.isNotEmpty(jobValue.getString("recurrenceInfoId"))) { + GenericValue ri = jobValue.getRelatedOne("RecurrenceInfo", false); + if (ri != null) { + return new RecurrenceInfo(ri); + } + } + } catch (GenericEntityException e) { + Debug.logError(e, "Problem getting RecurrenceInfo entity from JobSandbox", module); + } catch (RecurrenceInfoException re) { + Debug.logError(re, "Problem creating RecurrenceInfo instance: " + re.getMessage(), module); + } + return null; + } + + @Override + public void deQueue() throws InvalidJobException { + if (currentState != State.QUEUED) { + throw new InvalidJobException("Illegal state change"); + } + currentState = State.CREATED; + try { + jobValue.refresh(); + jobValue.set("startDateTime", null); + jobValue.set("runByInstanceId", null); + jobValue.set("statusId", "SERVICE_PENDING"); + jobValue.store(); + } catch (GenericEntityException e) { + throw new InvalidJobException("Unable to dequeue job [" + getJobId() + "]", e); + } + if (Debug.verboseOn()) { + Debug.logVerbose("Job [" + getJobId() + "] not queued, rescheduling", module); + } + } + + @Override + public Date getStartTime() { + return new Date(startTime); + } } Modified: ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/rmi/RmiServiceContainer.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/rmi/RmiServiceContainer.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/rmi/RmiServiceContainer.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/service/src/org/ofbiz/service/rmi/RmiServiceContainer.java Thu Oct 25 05:04:09 2012 @@ -48,9 +48,7 @@ public class RmiServiceContainer impleme private String containerName; // Container methods - /** - * @see org.ofbiz.base.container.Container#init(String[] args, String name, String configFile) - */ + @Override public void init(String[] args, String name, String configFile) { this.containerName = name; this.configFile = configFile; Modified: ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Config.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Config.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Config.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Config.java Thu Oct 25 05:04:09 2012 @@ -73,7 +73,7 @@ public class Config { public String containerConfig; public String instrumenterClassName; public String instrumenterFile; - public List<Map> loaders; + public List<Map<String, String>> loaders; public String logDir; public String ofbizHome; public boolean requireCommJar = false; @@ -420,7 +420,7 @@ public class Config { instrumenterFile = getProp(props, "ofbiz.instrumenterFile", null); // loader classes - loaders = new ArrayList<Map>(); + loaders = new ArrayList<Map<String, String>>(); int currentPosition = 1; Map<String, String> loader = null; while (true) { Modified: ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Start.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Start.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Start.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/start/src/org/ofbiz/base/start/Start.java Thu Oct 25 05:04:09 2012 @@ -35,33 +35,29 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicReference; /** - * Start - OFBiz Container(s) Startup Class - * + * OFBiz startup class. + * */ -public class Start { +public final class Start { - private enum Control { - SHUTDOWN { - void processRequest(Start start, PrintWriter writer) { - if (start.serverState.get() == ServerState.STOPPING) { - writer.println("IN-PROGRESS"); - } else { - writer.println("OK"); - writer.flush(); - start.stopServer(); - } - } - }, STATUS { - void processRequest(Start start, PrintWriter writer) { - writer.println(start.serverState.get()); - } - }, FAIL { - void processRequest(Start start, PrintWriter writer) { - writer.println("FAIL"); - } - }; + private static final Start instance = new Start(); - abstract void processRequest(Start start, PrintWriter writer); + private static Command checkCommand(Command command, Command wanted) { + if (wanted == Command.HELP || wanted.equals(command)) { + return wanted; + } else if (command == null) { + return wanted; + } else { + System.err.println("Duplicate command detected(was " + command + ", wanted " + wanted); + return Command.HELP_ERROR; + } + } + + /** + * Returns the <code>Start</code> instance. + */ + public static Start getInstance() { + return instance; } private static void help(PrintStream out) { @@ -80,25 +76,10 @@ public class Start { out.println("[no command] -> Start the server w/ default config"); } - private enum Command { - HELP, HELP_ERROR, STATUS, SHUTDOWN, COMMAND - } - - private static Command checkCommand(Command command, Command wanted) { - if (wanted == Command.HELP || wanted.equals(command)) { - return wanted; - } else if (command == null) { - return wanted; - } else { - System.err.println("Duplicate command detected(was " + command + ", wanted " + wanted); - return Command.HELP_ERROR; - } - } - public static void main(String[] args) throws StartupException { Command command = null; List<String> loaderArgs = new ArrayList<String>(args.length); - for (String arg: args) { + for (String arg : args) { if (arg.equals("-help") || arg.equals("-?")) { command = checkCommand(command, Command.HELP); } else if (arg.equals("-status")) { @@ -128,16 +109,15 @@ public class Start { help(System.err); System.exit(1); } - Start start = new Start(); - start.init(args, command == Command.COMMAND); + instance.init(args, command == Command.COMMAND); try { if (command == Command.STATUS) { - System.out.println("Current Status : " + start.status()); + System.out.println("Current Status : " + instance.status()); } else if (command == Command.SHUTDOWN) { - System.out.println("Shutting down server : " + start.shutdown()); + System.out.println("Shutting down server : " + instance.shutdown()); } else { // general start - start.start(); + instance.start(); } } catch (Exception e) { e.printStackTrace(); @@ -145,20 +125,16 @@ public class Start { } } - private enum ServerState { - STARTING, RUNNING, STOPPING; - - public String toString() { - return name().charAt(0) + name().substring(1).toLowerCase(); - } - } + // ---------------------------------------------- // private Config config = null; - private List<String> loaderArgs = new ArrayList<String>(); + private final List<String> loaderArgs = new ArrayList<String>(); private final ArrayList<StartupLoader> loaders = new ArrayList<StartupLoader>(); - private AtomicReference<ServerState> serverState = new AtomicReference<ServerState>(ServerState.STARTING); + private final AtomicReference<ServerState> serverState = new AtomicReference<ServerState>(ServerState.STARTING); private Thread adminPortThread = null; + private Start() {} + private void createListenerThread() throws StartupException { if (config.adminPort > 0) { this.adminPortThread = new AdminPortThread(); @@ -177,11 +153,14 @@ public class Start { } } - public void init(String[] args) throws StartupException { - init(args, true); + /** + * Returns the server's current state. + */ + public ServerState getCurrentState() { + return serverState.get(); } - public void init(String[] args, boolean fullInit) throws StartupException { + private void init(String[] args, boolean fullInit) throws StartupException { String globalSystemPropsFileName = System.getProperty("ofbiz.system.props"); if (globalSystemPropsFileName != null) { FileInputStream stream = null; @@ -191,7 +170,7 @@ public class Start { } catch (IOException e) { throw (StartupException) new StartupException("Couldn't load global system props").initCause(e); } finally { - if (stream != null){ + if (stream != null) { try { stream.close(); } catch (IOException e) { @@ -209,22 +188,22 @@ public class Start { if (args.length > 1) { this.loaderArgs.addAll(Arrays.asList(args).subList(1, args.length)); } - if (!fullInit) { return; } // initialize the classpath initClasspath(); - // create the log directory createLogDirectory(); - // create the listener thread createListenerThread(); - // set the shutdown hook if (config.useShutdownHook) { - Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { shutdownServer(); } }); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + shutdownServer(); + } + }); } else { System.out.println("Shutdown hook disabled"); } @@ -254,12 +233,12 @@ public class Start { ClassLoader classloader = Thread.currentThread().getContextClassLoader(); synchronized (this.loaders) { // initialize the loaders - for (Map loaderMap: config.loaders) { + for (Map<String, String> loaderMap : config.loaders) { if (this.serverState.get() == ServerState.STOPPING) { return; } try { - String loaderClassName = (String)loaderMap.get("class"); + String loaderClassName = (String) loaderMap.get("class"); Class<?> loaderClass = classloader.loadClass(loaderClassName); StartupLoader loader = (StartupLoader) loaderClass.newInstance(); loader.load(config, loaderArgs.toArray(new String[loaderArgs.size()])); @@ -279,24 +258,19 @@ public class Start { private String sendSocketCommand(Control control) throws IOException, ConnectException { String response = "OFBiz is Down"; - try { - Socket socket = new Socket(config.adminAddress, config.adminPort); - - // send the command - PrintWriter writer = new PrintWriter(socket.getOutputStream(), true); - writer.println(config.adminKey + ":" + control); - writer.flush(); - - // read the reply - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - response = reader.readLine(); - - reader.close(); - - // close the socket - writer.close(); - socket.close(); + Socket socket = new Socket(config.adminAddress, config.adminPort); + // send the command + PrintWriter writer = new PrintWriter(socket.getOutputStream(), true); + writer.println(config.adminKey + ":" + control); + writer.flush(); + // read the reply + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + response = reader.readLine(); + reader.close(); + // close the socket + writer.close(); + socket.close(); } catch (ConnectException e) { System.out.println("Could not connect to " + config.adminAddress + ":" + config.adminPort); @@ -304,7 +278,7 @@ public class Start { return response; } - public String shutdown() throws IOException { + private String shutdown() throws IOException { return sendSocketCommand(Control.SHUTDOWN); } @@ -334,20 +308,6 @@ public class Start { } } - // org.apache.commons.daemon.Daemon.start() - public void start() throws Exception { - if (!startStartLoaders()) { - if (this.serverState.get() == ServerState.STOPPING) { - return; - } else { - throw new Exception("Error during start."); - } - } - if (config.shutdownAfterLoad) { - stopServer(); - } - } - /** * Returns <code>true</code> if all loaders were started. * @@ -356,7 +316,7 @@ public class Start { private boolean startStartLoaders() { synchronized (this.loaders) { // start the loaders - for (StartupLoader loader: this.loaders) { + for (StartupLoader loader : this.loaders) { if (this.serverState.get() == ServerState.STOPPING) { return false; } @@ -371,7 +331,7 @@ public class Start { return this.serverState.compareAndSet(ServerState.STARTING, ServerState.RUNNING); } - public String status() throws IOException { + private String status() throws IOException { try { return sendSocketCommand(Control.STATUS); } catch (ConnectException e) { @@ -381,21 +341,41 @@ public class Start { } } - public void stopServer() { + private void stopServer() { shutdownServer(); System.exit(0); } + // ----------------------------------------------- // + // org.apache.commons.daemon.Daemon implementation // + // ----------------------------------------------- // + // org.apache.commons.daemon.Daemon.destroy() public void destroy() { // FIXME: undo init() calls. } + // org.apache.commons.daemon.Daemon.start() + public void start() throws Exception { + if (!startStartLoaders()) { + if (this.serverState.get() == ServerState.STOPPING) { + return; + } else { + throw new Exception("Error during start."); + } + } + if (config.shutdownAfterLoad) { + stopServer(); + } + } + // org.apache.commons.daemon.Daemon.stop() public void stop() { shutdownServer(); } + // ----------------------------------------------- // + private class AdminPortThread extends Thread { private ServerSocket serverSocket = null; @@ -457,4 +437,42 @@ public class Start { } } } + + private enum Command { + HELP, HELP_ERROR, STATUS, SHUTDOWN, COMMAND + } + + private enum Control { + SHUTDOWN { + void processRequest(Start start, PrintWriter writer) { + if (start.serverState.get() == ServerState.STOPPING) { + writer.println("IN-PROGRESS"); + } else { + writer.println("OK"); + writer.flush(); + start.stopServer(); + } + } + }, + STATUS { + void processRequest(Start start, PrintWriter writer) { + writer.println(start.serverState.get()); + } + }, + FAIL { + void processRequest(Start start, PrintWriter writer) { + writer.println("FAIL"); + } + }; + + abstract void processRequest(Start start, PrintWriter writer); + } + + public enum ServerState { + STARTING, RUNNING, STOPPING; + + public String toString() { + return name().charAt(0) + name().substring(1).toLowerCase(); + } + } } Modified: ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestListContainer.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestListContainer.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestListContainer.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestListContainer.java Thu Oct 25 05:04:09 2012 @@ -58,9 +58,7 @@ public class TestListContainer implement } } - /** - * @see org.ofbiz.base.container.Container#init(String[] args, String name, String configFile) - */ + @Override public void init(String[] args, String name, String configFile) { this.name = name; this.outputLocation = args[0]; @@ -105,8 +103,7 @@ public class TestListContainer implement pout.format("%s:%s", foundTest.componentName, foundTest.suiteName); } pout.println("\"/>\n"); - for (int i = 0; i < foundTests.size(); i++) { - FoundTest foundTest = foundTests.get(i); + for (FoundTest foundTest : foundTests) { pout.format(" <target name=\"%1$s:%2$s\">\n <ant antfile=\"build.xml\" target=\"run-single-test-suite\">\n <property name=\"test.component\" value=\"%1$s\"/>\n <property name=\"test.suiteName\" value=\"%2$s\"/>\n </ant>\n </target>\n", foundTest.componentName, foundTest.suiteName); } pout.println("</project>"); Modified: ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestRunContainer.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestRunContainer.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestRunContainer.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/testtools/src/org/ofbiz/testtools/TestRunContainer.java Thu Oct 25 05:04:09 2012 @@ -59,15 +59,12 @@ public class TestRunContainer implements private String name; - /** - * @see org.ofbiz.base.container.Container#init(String[] args, String name, String configFile) - */ + @Override public void init(String[] args, String name, String configFile) { this.name = name; this.configFile = configFile; if (args != null) { - for (int i = 0; i < args.length; i++) { - String argument = args[i]; + for (String argument : args) { // arguments can prefix w/ a '-'. Just strip them off if (argument.startsWith("-")) { int subIdx = 1; Modified: ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java Thu Oct 25 05:04:09 2012 @@ -60,6 +60,7 @@ import org.ofbiz.security.SecurityConfig import org.ofbiz.security.SecurityFactory; import org.ofbiz.service.LocalDispatcher; import org.ofbiz.service.ServiceContainer; +import org.ofbiz.webapp.website.WebSiteWorker; /** * ContextFilter - Restricts access to raw files and configures servlet objects. @@ -126,7 +127,7 @@ public class ContextFilter implements Fi // set the webSiteId in the session if (UtilValidate.isEmpty(httpRequest.getSession().getAttribute("webSiteId"))){ - httpRequest.getSession().setAttribute("webSiteId", config.getServletContext().getAttribute("webSiteId")); + httpRequest.getSession().setAttribute("webSiteId", WebSiteWorker.getWebSiteId(httpRequest)); } // set the filesystem path of context root. Modified: ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java Thu Oct 25 05:04:09 2012 @@ -225,6 +225,9 @@ public class ControlServlet extends Http request.setAttribute("_ERROR_MESSAGE_", encoder.encode(throwable.toString())); errorPage = requestHandler.getDefaultErrorPage(request); } + } catch (RequestHandlerExceptionAllowExternalRequests e) { + errorPage = requestHandler.getDefaultErrorPage(request); + Debug.logInfo("Going to external page: " + request.getPathInfo(), module); } catch (Exception e) { Debug.logError(e, "Error in request handler: ", module); StringUtil.HtmlEncoder encoder = new StringUtil.HtmlEncoder(); Modified: ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java Thu Oct 25 05:04:09 2012 @@ -981,7 +981,13 @@ public class LoginWorker { if (security != null) { ServletContext context = (ServletContext) request.getAttribute("servletContext"); String serverId = (String) context.getAttribute("_serverId"); + + // get a context path from the request, if it is empty then assume it is the root mount point String contextPath = request.getContextPath(); + if (UtilValidate.isEmpty(contextPath)) { + contextPath = "/"; + } + ComponentConfig.WebappInfo info = ComponentConfig.getWebAppInfo(serverId, contextPath); if (info != null) { for (String permission: info.getBasePermission()) { Modified: ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java Thu Oct 25 05:04:09 2012 @@ -58,6 +58,7 @@ import org.ofbiz.webapp.view.ViewFactory import org.ofbiz.webapp.view.ViewHandler; import org.ofbiz.webapp.view.ViewHandlerException; import org.ofbiz.webapp.website.WebSiteWorker; +import org.owasp.esapi.errors.EncodingException; /** * RequestHandler - Request Processor Object @@ -65,6 +66,8 @@ import org.ofbiz.webapp.website.WebSiteW public class RequestHandler { public static final String module = RequestHandler.class.getName(); + private static final Boolean THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST = + UtilProperties.propertyValueEqualsIgnoreCase("requestHandler.properties", "throwRequestHandlerExceptionOnMissingLocalRequest", "Y"); public static RequestHandler getRequestHandler(ServletContext servletContext) { RequestHandler rh = (RequestHandler) servletContext.getAttribute("_REQUEST_HANDLER_"); @@ -96,7 +99,7 @@ public class RequestHandler { return ConfigXMLReader.getControllerConfig(this.controllerConfigURL); } - public void doRequest(HttpServletRequest request, HttpServletResponse response, String requestUri) throws RequestHandlerException { + public void doRequest(HttpServletRequest request, HttpServletResponse response, String requestUri) throws RequestHandlerException, RequestHandlerExceptionAllowExternalRequests { HttpSession session = request.getSession(); Delegator delegator = (Delegator) request.getAttribute("delegator"); GenericValue userLogin = (GenericValue) session.getAttribute("userLogin"); @@ -104,7 +107,7 @@ public class RequestHandler { } public void doRequest(HttpServletRequest request, HttpServletResponse response, String chain, - GenericValue userLogin, Delegator delegator) throws RequestHandlerException { + GenericValue userLogin, Delegator delegator) throws RequestHandlerException, RequestHandlerExceptionAllowExternalRequests { long startTime = System.currentTimeMillis(); HttpSession session = request.getSession(); @@ -152,10 +155,13 @@ public class RequestHandler { } } - // still not found so stop + // if no matching request is found in the controller, depending on THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST + // we throw a RequestHandlerException or RequestHandlerExceptionAllowExternalRequests if (requestMap == null) { - throw new RequestHandlerException(requestMissingErrorMessage); - } + if (THROW_REQUEST_HANDLER_EXCEPTION_ON_MISSING_LOCAL_REQUEST) throw new RequestHandlerException(requestMissingErrorMessage); + else throw new RequestHandlerExceptionAllowExternalRequests(); + } + String eventReturn = null; if (requestMap.metrics != null && requestMap.metrics.getThreshold() != 0.0 && requestMap.metrics.getTotalEvents() > 3 && requestMap.metrics.getThreshold() < requestMap.metrics.getServiceRate()) { eventReturn = "threshold-exceeded"; @@ -962,32 +968,36 @@ public class RequestHandler { value = request.getParameter(from); } - if (UtilValidate.isNotEmpty(value)) { - if (queryString.length() > 1) { - queryString.append("&"); - } - queryString.append(name); - queryString.append("="); - queryString.append(value); - } + addNameValuePairToQueryString(queryString, name, (String) value); } + for (Map.Entry<String, String> entry: requestResponse.redirectParameterValueMap.entrySet()) { String name = entry.getKey(); String value = entry.getValue(); - if (UtilValidate.isNotEmpty(value)) { - if (queryString.length() > 1) { - queryString.append("&"); - } - queryString.append(name); - queryString.append("="); - queryString.append(value); - } + addNameValuePairToQueryString(queryString, name, value); } + return queryString.toString(); } } + private void addNameValuePairToQueryString(StringBuilder queryString, String name, String value) { + if (UtilValidate.isNotEmpty(value)) { + if (queryString.length() > 1) { + queryString.append("&"); + } + + try { + queryString.append(StringUtil.defaultWebEncoder.encodeForURL(name)); + queryString.append("="); + queryString.append(StringUtil.defaultWebEncoder.encodeForURL(value)); + } catch (EncodingException e) { + Debug.logError(e, module); + } + } + } + public String makeLinkWithQueryString(HttpServletRequest request, HttpServletResponse response, String url, ConfigXMLReader.RequestResponse requestResponse) { String initialLink = this.makeLink(request, response, url); String queryString = this.makeQueryString(request, requestResponse); @@ -1127,8 +1137,11 @@ public class RequestHandler { newURL.insert(questionIndex, sessionId); } } - - encodedUrl = newURL.toString(); + if (response != null) { + encodedUrl = response.encodeURL(newURL.toString()); + } else { + encodedUrl = newURL.toString(); + } } } else { encodedUrl = newURL.toString(); Modified: ofbiz/branches/20120329_portletWidget/framework/webtools/config/WebtoolsUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webtools/config/WebtoolsUiLabels.xml?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webtools/config/WebtoolsUiLabels.xml (original) +++ ofbiz/branches/20120329_portletWidget/framework/webtools/config/WebtoolsUiLabels.xml Thu Oct 25 05:04:09 2012 @@ -920,8 +920,8 @@ </property> <property key="WebtoolsCheckAll"> <value xml:lang="de">Alle auswählen</value> - <value xml:lang="en">Check All</value> - <value xml:lang="fr">Tout sélectionner</value> + <value xml:lang="en">Check All (not views)</value> + <value xml:lang="fr">Tout sélectionner (pas les views)</value> <value xml:lang="it">Seleziona tutto</value> <value xml:lang="pt">Selecionar todos</value> <value xml:lang="th">à¸à¸£à¸§à¸à¸ªà¸à¸à¸à¸±à¹à¸à¸«à¸¡à¸</value> @@ -4181,7 +4181,7 @@ </property> <property key="WebtoolsServiceEngineThreads"> <value xml:lang="de">Dienste-Engine Threads</value> - <value xml:lang="en">Service Engine Threads</value> + <value xml:lang="en">Job Queue Service Threads</value> <value xml:lang="fr">Threads du Service Engine</value> <value xml:lang="it">Threads dell' Engine Servizi</value> <value xml:lang="pt">Threads do Engine de serviços</value> Modified: ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/WEB-INF/actions/entity/FindGeneric.groovy URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/WEB-INF/actions/entity/FindGeneric.groovy?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/WEB-INF/actions/entity/FindGeneric.groovy (original) +++ ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/WEB-INF/actions/entity/FindGeneric.groovy Thu Oct 25 05:04:09 2012 @@ -174,8 +174,13 @@ if ("true".equals(find)) { fieldsToSelect.add(functionField) } } - - resultEli = delegator.find(entityName, condition, null, fieldsToSelect, null, efo); + Collection pkNames = FastList.newInstance(); + Iterator iter = modelEntity.getPksIterator(); + while (iter != null && iter.hasNext()) { + ModelField curField = (ModelField) iter.next(); + pkNames.add(curField.getName()); + } + resultEli = delegator.find(entityName, condition, null, fieldsToSelect, pkNames, efo); resultPartialList = resultEli.getPartialList(lowIndex, highIndex - lowIndex + 1); arraySize = resultEli.getResultsSizeAfterPartialList(); Modified: ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/entity/xmldsdump.ftl URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/entity/xmldsdump.ftl?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/entity/xmldsdump.ftl (original) +++ ofbiz/branches/20120329_portletWidget/framework/webtools/webapp/webtools/entity/xmldsdump.ftl Thu Oct 25 05:04:09 2012 @@ -41,10 +41,10 @@ under the License. <#if security.hasPermission("ENTITY_MAINT", session)> <h2>${uiLabelMap.WebtoolsResults}:</h2> - <#if Static["org.ofbiz.base.util.UtilValidate"].isNotEmpty(parameters.filename) && (numberOfEntities?number > 0)> + <#if parameters.filename?has_content && (numberOfEntities?number > 0)> <p>${uiLabelMap.WebtoolsWroteXMLForAllDataIn}</p> <p>${uiLabelMap.WebtoolsWroteNRecordsToXMLFile}</p> - <#elseif Static["org.ofbiz.base.util.UtilValidate"].isNotEmpty(parameters.outpath) && (numberOfEntities?number > 0)> + <#elseif parameters.outpath?has_content && (numberOfEntities?number > 0)> <#list results as result> <p>${result}</p> </#list> Modified: ofbiz/branches/20120329_portletWidget/framework/webtools/widget/ServiceForms.xml URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/webtools/widget/ServiceForms.xml?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/webtools/widget/ServiceForms.xml (original) +++ ofbiz/branches/20120329_portletWidget/framework/webtools/widget/ServiceForms.xml Thu Oct 25 05:04:09 2012 @@ -96,7 +96,7 @@ under the License. </hyperlink> </field> <field name="statusId" title="${uiLabelMap.CommonStatus}" sort-field="true"><display-entity entity-name="StatusItem" description="${description}"/></field> - <field name="cancelDateTime" title="${uiLabelMap.CommonEndDateTime}" sort-field="true"><display/></field> + <field name="finishDateTime" title="${uiLabelMap.CommonEndDateTime}" sort-field="true"><display/></field> <field name="cancelButton" title=" " use-when="startDateTime==null&&finishDateTime==null&&cancelDateTime==null" widget-style="buttontext"> <hyperlink also-hidden="false" description="${uiLabelMap.WebtoolsCancelJob}" target="cancelJob"> <parameter param-name="jobId"/> @@ -111,9 +111,6 @@ under the License. <field name="value"><display/></field> </form> <form name="PoolState" type="single" default-map-name="poolState"> - <field name="pollerName"><display/></field> - <field name="pollerThreadName"><display/></field> - <field name="invokerThreadNameFormat"><display/></field> <field name="keepAliveTimeInSeconds"><display/></field> <field name="numberOfCoreInvokerThreads"><display/></field> <field name="currentNumberOfInvokerThreads"><display/></field> @@ -127,7 +124,7 @@ under the License. <field name="id" title="${uiLabelMap.WebtoolsThread}"><display description="${threadId} ${threadName}"/></field> <field name="name" title="${uiLabelMap.WebtoolsJob}"><display default-value="${uiLabelMap.CommonNone}"/></field> <field name="serviceName" title="${uiLabelMap.WebtoolsService}"><display default-value="${uiLabelMap.CommonNone}"/></field> - <field name="time"><display/></field> + <field name="time" title="${uiLabelMap.CommonStartDateTime}"><display/></field> <field name="runTime" title="${uiLabelMap.CommonTime} (ms)"><display/></field> </form> <form name="ListServices" type="list" list-name="services" paginate-target="ServiceLog" separate-columns="true" Modified: ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/WidgetWorker.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/WidgetWorker.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/WidgetWorker.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/WidgetWorker.java Thu Oct 25 05:04:09 2012 @@ -292,10 +292,15 @@ public class WidgetWorker { for (Map.Entry<String, String> parameter: parameterMap.entrySet()) { if (parameter.getValue() != null) { + String key = parameter.getKey(); + writer.append("<input name=\""); - writer.append(parameter.getKey()); + writer.append(key); writer.append("\" value=\""); - writer.append(parameter.getValue()); + + String valueFromContext = context.containsKey(key) ? + context.get(key).toString() : parameter.getValue(); + writer.append(valueFromContext); writer.append("\" type=\"hidden\"/>"); } } Modified: ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java Thu Oct 25 05:04:09 2012 @@ -983,10 +983,15 @@ public class ModelFormField { } public String getTooltip(Map<String, Object> context) { - if (UtilValidate.isNotEmpty(tooltip)) return tooltip.expandString(context); - return ""; + String tooltipString = ""; + if (UtilValidate.isNotEmpty(tooltip)) tooltipString = tooltip.expandString(context); + if (this.getEncodeOutput()) { + StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); + if (simpleEncoder != null) tooltipString = simpleEncoder.encode(tooltipString); + } + return tooltipString; } - + public String getUseWhen(Map<String, Object> context) { if (UtilValidate.isNotEmpty(this.useWhen)) return this.useWhen.expandString(context); return ""; @@ -1996,7 +2001,6 @@ public class ModelFormField { public String getDescription(Map<String, Object> context) { String retVal = null; - // Don't replace by UtilValidate.isNotEmpty: this.description is a FlexibleStringExpander and issues occur if (UtilValidate.isNotEmpty(this.description)) retVal = this.description.expandString(context); else retVal = this.modelFormField.getEntry(context); @@ -2079,7 +2083,6 @@ public class ModelFormField { throw new IllegalArgumentException(errMsg); } } - // Don't replace by UtilValidate.isNotEmpty: this.description is a FlexibleStringExpander and issues occur if (UtilValidate.isNotEmpty(this.description) && retVal != null && this.getModelFormField().getEncodeOutput()) { StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder"); if (simpleEncoder != null) { @@ -2175,10 +2178,7 @@ public class ModelFormField { this.cache = !"false".equals(element.getAttribute("cache")); this.size = element.getAttribute("size"); - // Don't replace by UtilValidate.isNotEmpty: this.description is a FlexibleStringExpander and issues occur - if (this.description == null || this.description.isEmpty()) { - this.setDescription("${description}"); - } + if (UtilValidate.isEmpty(this.description)) this.setDescription("${description}"); Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink"); if (subHyperlinkElement != null) { @@ -4125,7 +4125,6 @@ public class ModelFormField { } public String getDescription(Map<String, Object> context) { - // Don't replace by UtilValidate.isNotEmpty: this.description is a FlexibleStringExpander and issues occur if (UtilValidate.isNotEmpty(this.description)) return this.description.expandString(context); return ""; } Modified: ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java Thu Oct 25 05:04:09 2012 @@ -53,6 +53,7 @@ import org.ofbiz.service.DispatchContext import org.ofbiz.service.GenericServiceException; import org.ofbiz.service.LocalDispatcher; import org.ofbiz.webapp.control.LoginWorker; +import org.ofbiz.webapp.website.WebSiteWorker; import org.ofbiz.widget.cache.GenericWidgetOutput; import org.ofbiz.widget.cache.ScreenCache; import org.ofbiz.widget.cache.WidgetContextCacheKey; @@ -225,7 +226,7 @@ public class ScreenRenderer { context.put("rootDir", rootDir); } if (UtilValidate.isEmpty(webSiteId)) { - webSiteId = (String) servletContext.getAttribute("webSiteId"); + webSiteId = WebSiteWorker.getWebSiteId(request); context.put("webSiteId", webSiteId); } if (UtilValidate.isEmpty(https)) { Modified: ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java URL: http://svn.apache.org/viewvc/ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java?rev=1401975&r1=1401974&r2=1401975&view=diff ============================================================================== --- ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java (original) +++ ofbiz/branches/20120329_portletWidget/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java Thu Oct 25 05:04:09 2012 @@ -664,7 +664,13 @@ public class ModelTree extends ModelWidg ModelField modelField = modelEntity.getOnlyPk(); this.pkName = modelField.getName(); } else { - // TODO: what to do here? + List<String> pkFieldsName = modelEntity.getPkFieldNames(); + StringBuilder sb = new StringBuilder(); + for (String pk: pkFieldsName) { + sb.append(pk); + sb.append("|"); + } + this.pkName = sb.toString(); } } } |
| Free forum by Nabble | Edit this page |
