Package org.apache.sling.event.jobs

Source Code of org.apache.sling.event.jobs.JobUtil

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.event.jobs;

import java.util.Calendar;

import org.apache.sling.commons.threads.ThreadPool;
import org.apache.sling.event.impl.jobs.deprecated.JobStatusNotifier;
import org.apache.sling.event.impl.support.Environment;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.event.Event;
import org.slf4j.LoggerFactory;

/**
* The <code>Job</code> class is an utility class for
* creating and processing jobs.
* @since 3.0
* @deprecated
*/
@Deprecated
public abstract class JobUtil {

    /**
     * The job topic property.
     * @deprecated - Jobs should be started via {@link JobManager#addJob(String, String, java.util.Map)}
     */
    @Deprecated
    public static final String PROPERTY_JOB_TOPIC = "event.job.topic";

    /**
     * The property for the unique event name. Value is of type String.
     * This property should only be used if it can happen that the exact same
     * job is started on different cluster nodes.
     * By specifying the same id for this job on all cluster nodes,
     * the job handling can detect the duplicates and process the job
     * only once.
     * This is optional - and should only be used for the case mentioned.
     * @deprecated - Jobs should be started via {@link JobManager#addJob(String, String, java.util.Map)}
     */
    @Deprecated
    public static final String PROPERTY_JOB_NAME = "event.job.id";

    /**
     * This property is not supported anymore
     * @deprecated
     */
    @Deprecated
    public static final String PROPERTY_JOB_PARALLEL = "event.job.parallel";

    /**
     * This property is not supported anymore
     * @deprecated
     */
    @Deprecated
    public static final String PROPERTY_JOB_RUN_LOCAL = "event.job.run.local";

    /**
     * The property to track the retry count for jobs. Value is of type Integer.
     * On first execution the value of this property is zero.
     * This property is managed by the job handling.
     * If this property is set by the client creating the job it's value is ignored
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_RETRY_COUNT = "event.job.retrycount";

    /**
     * The property to track the retry maximum retry count for jobs. Value is of type Integer.
     * This property is managed by the job handling.
     * If this property is set by the client creating the job it's value is ignored
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_RETRIES = "event.job.retries";

    /**
     * The property to set a retry delay. Value is of type Long and specifies milliseconds.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_RETRY_DELAY = "event.job.retrydelay";

    /**
     * The name of the job queue processing this job.
     * This property is set by the job handling when the job is processed.
     * If this property is set by the client creating the job it's value is ignored
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_QUEUE_NAME = "event.job.queuename";

    /**
     * This property is not supported anymore
     * @deprecated
     */
    @Deprecated
    public static final String PROPERTY_JOB_QUEUE_ORDERED = "event.job.queueordered";

    /**
     * This property is set by the job handling to define the priority of this job
     * execution.
     * The property is evaluated by the {@link #processJob(Event, JobProcessor)} method.
     * If another way of executing the job is used, it is up to the processor to ensure
     * the job priority is taken into account.
     * For possible values see {@link JobPriority}.
     * If this property is set by the client creating the job it's value is ignored
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_PRIORITY = "event.job.priority";

    /**
     * This property is set by the job handling and contains a calendar object
     * specifying the date and time when this job has been created.
     * If this property is set by the client creating the job it's value is ignored
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_CREATED = "slingevent:created";

    /**
     * This property is set by the job handling and contains the Sling instance ID
     * of the instance where this job has been created.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_CREATED_APPLICATION = "slingevent:application";

    /**
     * This property is set by the job handling and contains the Sling instance ID
     * of the instance where this job should be processed.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String PROPERTY_JOB_APPLICATION = "event.job.application";

    /**
     * The priority for jobs.
     * @deprecated
     */
    public enum JobPriority {
        NORM,
        MIN,
        MAX
    }

    /**
     * The topic for jobs.
     * @deprecated - Use the new {@link JobManager#addJob(String, String, java.util.Map)} method instead.
     */
    @Deprecated
    public static final String TOPIC_JOB = "org/apache/sling/event/job";

    /**
     * This is a unique identifier which can be used to cancel the job.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static final String JOB_ID = "slingevent:eventId";

    /**
     * Notification events for jobs.
     */

    /**
     * @see NotificationConstants#TOPIC_JOB_STARTED
     * @deprecated Use NotificationConstants#TOPIC_JOB_STARTED
     */
    @Deprecated
    public static final String TOPIC_JOB_STARTED = NotificationConstants.TOPIC_JOB_STARTED;

    /**
     * @see NotificationConstants#TOPIC_JOB_FINISHED
     * @deprecated Use NotificationConstants#TOPIC_JOB_FINISHED
     */
    @Deprecated
    public static final String TOPIC_JOB_FINISHED = NotificationConstants.TOPIC_JOB_FINISHED;

    /**
     * @see NotificationConstants#TOPIC_JOB_FAILED
     * @deprecated Use NotificationConstants#TOPIC_JOB_FAILED
     */
    @Deprecated
    public static final String TOPIC_JOB_FAILED = NotificationConstants.TOPIC_JOB_FAILED;

    /**
     * @see NotificationConstants#TOPIC_JOB_CANCELLED
     * @deprecated Use NotificationConstants#TOPIC_JOB_CANCELLED
     */
    @Deprecated
    public static final String TOPIC_JOB_CANCELLED = NotificationConstants.TOPIC_JOB_CANCELLED;

    /**
     * Property containing the job event. The value is of type org.osgi.service.event.Event.
     * Since 1.6 this property is not send anymore.
     * @deprecated
     */
    @Deprecated
    public static final String PROPERTY_NOTIFICATION_JOB = "event.notification.job";

    /**
     * @see NotificationConstants#NOTIFICATION_PROPERTY_JOB_TOPIC
     * @deprecated Use NotificationConstants#NOTIFICATION_PROPERTY_JOB_TOPIC
     */
    @Deprecated
    public static final String NOTIFICATION_PROPERTY_JOB_TOPIC = NotificationConstants.NOTIFICATION_PROPERTY_JOB_TOPIC;

    /**
     * Property containing the optional job name. Value is of type String.
     */
    @Deprecated
    public static final String NOTIFICATION_PROPERTY_JOB_NAME = "event.job.id";

    /**
     * @see NotificationConstants#NOTIFICATION_PROPERTY_JOB_ID
     * @deprecated Use NotificationConstants#NOTIFICATION_PROPERTY_JOB_ID
     */
    @Deprecated
    public static final String NOTIFICATION_PROPERTY_JOB_ID = NotificationConstants.NOTIFICATION_PROPERTY_JOB_ID;

    /**
     * Is this a job event?
     * This method checks if the event contains the {@link #PROPERTY_JOB_TOPIC}
     * property.
     * @param event The event to check.
     * @return <code>true></code> if this is a job event.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static boolean isJobEvent(final Event event) {
        return event.getProperty(PROPERTY_JOB_TOPIC) != null;
    }

    /**
     * Check if this a job event and return the notifier context.
     * @throws IllegalArgumentException If the event is a job event but does not have a notifier context.
     * @deprecated - Use the new {@link JobConsumer} interface instead.
     */
    @Deprecated
    private static JobStatusNotifier.NotifierContext getNotifierContext(final Event job) {
        // check if this is a job event
        if ( !isJobEvent(job) ) {
            return null;
        }
        final JobStatusNotifier.NotifierContext ctx = (JobStatusNotifier.NotifierContext) job.getProperty(JobStatusNotifier.CONTEXT_PROPERTY_NAME);
        if ( ctx == null ) {
            throw new IllegalArgumentException("JobStatusNotifier context is not available in event properties.");
        }
        return ctx;
    }

    /**
     * Send an acknowledge.
     * This signals the job handler that someone is starting to process the job. This method
     * should be invoked as a first command during job processing.
     * If this method returns <code>false</code> this means someone else is already
     * processing this job, and the caller should not process the event anymore.
     * @return Returns <code>true</code> if the acknowledge could be sent
     * @throws IllegalArgumentException If the event is a job event but does not have a notifier context.
     * @deprecated - Use the new {@link JobConsumer} interface instead.
     */
    @Deprecated
    public static boolean acknowledgeJob(final Event job) {
        final JobStatusNotifier.NotifierContext ctx = getNotifierContext(job);
        if ( ctx != null ) {
            if ( !ctx.getJobStatusNotifier().sendAcknowledge(job) ) {
                // if we don't get an ack, someone else is already processing this job.
                // we process but do not notify the job event handler.
                LoggerFactory.getLogger(JobUtil.class).info("Someone else is already processing job {}.", job);
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * Notify a finished job.
     * @throws IllegalArgumentException If the event is a job event but does not have a notifier context.
     * @deprecated - Use the new {@link JobConsumer} interface instead.
     */
    @Deprecated
    public static void finishedJob(final Event job) {
        final JobStatusNotifier.NotifierContext ctx = getNotifierContext(job);
        if ( ctx != null ) {
            ctx.getJobStatusNotifier().finishedJob(job, false);
        }
    }

    /**
     * Notify a failed job.
     * @return <code>true</code> if the job has been rescheduled, <code>false</code> otherwise.
     * @throws IllegalArgumentException If the event is a job event but does not have a notifier context.
     * @deprecated - Use the new {@link JobConsumer} interface instead.
     */
    @Deprecated
    public static boolean rescheduleJob(final Event job) {
        final JobStatusNotifier.NotifierContext ctx = getNotifierContext(job);
        if ( ctx != null ) {
            return ctx.getJobStatusNotifier().finishedJob(job, true);
        }
        return false;
    }

    /**
     * Process a job in the background and notify its success.
     * This method also sends an acknowledge message to the job event handler.
     * @throws IllegalArgumentException If the event is a job event but does not have a notifier context.
     * @deprecated - Use the new {@link JobConsumer} interface instead.
     */
    @Deprecated
    public static void processJob(final Event job, final JobProcessor processor) {
        // first check for a notifier context to send an acknowledge
        final JobStatusNotifier.NotifierContext ctx = getNotifierContext(job);
        boolean notify = ctx != null;
        if ( ctx != null && !ctx.getJobStatusNotifier().sendAcknowledge(job) ) {
            // if we don't get an ack, someone else is already processing this job.
            // we process but do not notify the job event handler.
            LoggerFactory.getLogger(JobUtil.class).info("Someone else is already processing job {}.", job);
            notify = false;
        }
        final JobPriority priority = (JobPriority) job.getProperty(PROPERTY_JOB_PRIORITY);
        final boolean notifyResult = notify;

        final Runnable task = new Runnable() {

            /**
             * @see java.lang.Runnable#run()
             */
            @Override
            public void run() {
                final Thread currentThread = Thread.currentThread();
                // update priority and name
                final String oldName = currentThread.getName();
                final int oldPriority = currentThread.getPriority();

                currentThread.setName(oldName + "-" + job.getProperty(PROPERTY_JOB_QUEUE_NAME) + "(" + job.getProperty(PROPERTY_JOB_TOPIC) + ")");
                if ( priority != null ) {
                    switch ( priority ) {
                        case NORM : currentThread.setPriority(Thread.NORM_PRIORITY);
                                    break;
                        case MIN  : currentThread.setPriority(Thread.MIN_PRIORITY);
                                    break;
                        case MAX  : currentThread.setPriority(Thread.MAX_PRIORITY);
                                    break;
                    }
                }
                boolean result = false;
                try {
                    result = processor.process(job);
                } catch (Throwable t) { //NOSONAR
                    LoggerFactory.getLogger(JobUtil.class).error("Unhandled error occured in job processor " + t.getMessage() + " while processing job " + job, t);
                    // we don't reschedule if an exception occurs
                    result = true;
                } finally {
                    currentThread.setPriority(oldPriority);
                    currentThread.setName(oldName);
                    if ( notifyResult ) {
                        if ( result ) {
                            JobUtil.finishedJob(job);
                        } else {
                            JobUtil.rescheduleJob(job);
                        }
                    }
                }
            }

        };
        // check if the thread pool is available
        final ThreadPool pool = Environment.THREAD_POOL;
        if ( pool != null ) {
            pool.execute(task);
        } else {
            // if we don't have a thread pool, we create the thread directly
            // (this should never happen for jobs, but is a safe fallback and
            // allows to call this method for other background processing.
            new Thread(task).start();
        }
    }

    /**
     * Get the created calendar object.
     * @param job The job event
     * @return The created info or <code>null</code> if this is not a job event.
     * @deprecated - Use the new {@link Job} interface instead.
     */
    @Deprecated
    public static Calendar getJobCreated(final Event job) {
        return (Calendar) job.getProperty(PROPERTY_JOB_CREATED);
    }

    private JobUtil() {
        // avoid instantiation
    }
}
TOP

Related Classes of org.apache.sling.event.jobs.JobUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.