Search in sources :

Example 1 with Job

use of org.apache.sling.event.jobs.Job in project sling by apache.

the class JobManagerImpl method findJobs.

/**
     * @see org.apache.sling.event.jobs.JobManager#findJobs(org.apache.sling.event.jobs.JobManager.QueryType, java.lang.String, long, java.util.Map[])
     */
@Override
public Collection<Job> findJobs(final QueryType type, final String topic, final long limit, final Map<String, Object>... templates) {
    final boolean isHistoryQuery = type == QueryType.HISTORY || type == QueryType.SUCCEEDED || type == QueryType.CANCELLED || type == QueryType.DROPPED || type == QueryType.ERROR || type == QueryType.GIVEN_UP || type == QueryType.STOPPED;
    final List<Job> result = new ArrayList<>();
    final ResourceResolver resolver = this.configuration.createResourceResolver();
    final StringBuilder buf = new StringBuilder(64);
    try {
        buf.append("/jcr:root");
        buf.append(this.configuration.getJobsBasePathWithSlash());
        buf.append("/element(*,");
        buf.append(ResourceHelper.RESOURCE_TYPE_JOB);
        buf.append(")[@");
        buf.append(ISO9075.encode(ResourceHelper.PROPERTY_JOB_TOPIC));
        if (topic != null) {
            buf.append(" = '");
            buf.append(topic);
            buf.append("'");
        }
        // restricting on the type - history or unfinished
        if (isHistoryQuery) {
            buf.append(" and @");
            buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
            if (type == QueryType.SUCCEEDED || type == QueryType.DROPPED || type == QueryType.ERROR || type == QueryType.GIVEN_UP || type == QueryType.STOPPED) {
                buf.append(" = '");
                buf.append(type.name());
                buf.append("'");
            } else if (type == QueryType.CANCELLED) {
                buf.append(" and (@");
                buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
                buf.append(" = '");
                buf.append(QueryType.DROPPED.name());
                buf.append("' or @");
                buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
                buf.append(" = '");
                buf.append(QueryType.ERROR.name());
                buf.append("' or @");
                buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
                buf.append(" = '");
                buf.append(QueryType.GIVEN_UP.name());
                buf.append("' or @");
                buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
                buf.append(" = '");
                buf.append(QueryType.STOPPED.name());
                buf.append("')");
            }
        } else {
            buf.append(" and not(@");
            buf.append(ISO9075.encode(JobImpl.PROPERTY_FINISHED_STATE));
            buf.append(")");
            if (type == QueryType.ACTIVE) {
                buf.append(" and @");
                buf.append(ISO9075.encode(Job.PROPERTY_JOB_STARTED_TIME));
            } else if (type == QueryType.QUEUED) {
                buf.append(" and not(@");
                buf.append(ISO9075.encode(Job.PROPERTY_JOB_STARTED_TIME));
                buf.append(")");
            }
        }
        if (templates != null && templates.length > 0) {
            int index = 0;
            for (final Map<String, Object> template : templates) {
                // skip empty templates
                if (template.size() == 0) {
                    continue;
                }
                if (index == 0) {
                    buf.append(" and (");
                } else {
                    buf.append(" or ");
                }
                buf.append('(');
                final Iterator<Map.Entry<String, Object>> i = template.entrySet().iterator();
                boolean first = true;
                while (i.hasNext()) {
                    final Map.Entry<String, Object> current = i.next();
                    final String key = ISO9075.encode(current.getKey());
                    final char firstChar = key.length() > 0 ? key.charAt(0) : 0;
                    final String propName;
                    final Operation op;
                    if (firstChar == '=') {
                        propName = key.substring(1);
                        op = Operation.EQUALS;
                    } else if (firstChar == '<') {
                        final char secondChar = key.length() > 1 ? key.charAt(1) : 0;
                        if (secondChar == '=') {
                            op = Operation.LESS_OR_EQUALS;
                            propName = key.substring(2);
                        } else {
                            op = Operation.LESS;
                            propName = key.substring(1);
                        }
                    } else if (firstChar == '>') {
                        final char secondChar = key.length() > 1 ? key.charAt(1) : 0;
                        if (secondChar == '=') {
                            op = Operation.GREATER_OR_EQUALS;
                            propName = key.substring(2);
                        } else {
                            op = Operation.GREATER;
                            propName = key.substring(1);
                        }
                    } else {
                        propName = key;
                        op = Operation.EQUALS;
                    }
                    if (first) {
                        first = false;
                        buf.append('@');
                    } else {
                        buf.append(" and @");
                    }
                    buf.append(propName);
                    buf.append(' ');
                    switch(op) {
                        case EQUALS:
                            buf.append('=');
                            break;
                        case LESS:
                            buf.append('<');
                            break;
                        case LESS_OR_EQUALS:
                            buf.append("<=");
                            break;
                        case GREATER:
                            buf.append('>');
                            break;
                        case GREATER_OR_EQUALS:
                            buf.append(">=");
                            break;
                    }
                    buf.append(" '");
                    buf.append(current.getValue());
                    buf.append("'");
                }
                buf.append(')');
                index++;
            }
            if (index > 0) {
                buf.append(')');
            }
        }
        buf.append("] order by @");
        if (isHistoryQuery) {
            buf.append(JobImpl.PROPERTY_FINISHED_DATE);
            buf.append(" descending");
        } else {
            buf.append(Job.PROPERTY_JOB_CREATED);
            buf.append(" ascending");
        }
        final Iterator<Resource> iter = resolver.findResources(buf.toString(), "xpath");
        long count = 0;
        while (iter.hasNext() && (limit < 1 || count < limit)) {
            final Resource jobResource = iter.next();
            // sanity check for the path
            if (this.configuration.isJob(jobResource.getPath())) {
                final JobImpl job = Utility.readJob(logger, jobResource);
                if (job != null) {
                    count++;
                    result.add(job);
                }
            }
        }
    } catch (final QuerySyntaxException qse) {
        logger.warn("Query syntax wrong " + buf.toString(), qse);
    } finally {
        resolver.close();
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) Resource(org.apache.sling.api.resource.Resource) QuerySyntaxException(org.apache.sling.api.resource.QuerySyntaxException) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) Job(org.apache.sling.event.jobs.Job) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with Job

use of org.apache.sling.event.jobs.Job in project sling by apache.

the class JobManagerImpl method addJob.

/**
     * Internal method to add a job
     */
public Job addJob(final String topic, final Map<String, Object> properties, final List<String> errors) {
    final String errorMessage = Utility.checkJob(topic, properties);
    if (errorMessage != null) {
        logger.warn("{}", errorMessage);
        if (errors != null) {
            errors.add(errorMessage);
        }
        this.configuration.getAuditLogger().debug("ADD FAILED topic={}, properties={} : {}", new Object[] { topic, properties, errorMessage });
        return null;
    }
    final List<String> errorList = new ArrayList<>();
    Job result = this.addJobInternal(topic, properties, errorList);
    if (errors != null) {
        errors.addAll(errorList);
    }
    if (result == null) {
        this.configuration.getAuditLogger().debug("ADD FAILED topic={}, properties={} : {}", new Object[] { topic, properties, errorList });
    } else {
        this.configuration.getAuditLogger().debug("ADD OK topic={}, properties={} : {}", new Object[] { topic, properties, result.getId() });
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) Job(org.apache.sling.event.jobs.Job)

Example 3 with Job

use of org.apache.sling.event.jobs.Job in project sling by apache.

the class TopicMatchingTest method testDeepMatching.

/**
     * Test deep pattern matching /**
     */
@Test(timeout = DEFAULT_TEST_TIMEOUT)
public void testDeepMatching() throws Exception {
    final Barrier barrier = new Barrier(2);
    this.registerJobExecutor("sling/**", new JobExecutor() {

        @Override
        public JobExecutionResult process(final Job job, final JobExecutionContext context) {
            return context.result().succeeded();
        }
    });
    this.registerEventHandler(NotificationConstants.TOPIC_JOB_FINISHED, new EventHandler() {

        @Override
        public void handleEvent(final Event event) {
            barrier.block();
        }
    });
    this.getJobManager().addJob(TOPIC, null);
    barrier.block();
}
Also used : JobExecutionResult(org.apache.sling.event.jobs.consumer.JobExecutionResult) JobExecutor(org.apache.sling.event.jobs.consumer.JobExecutor) JobExecutionContext(org.apache.sling.event.jobs.consumer.JobExecutionContext) EventHandler(org.osgi.service.event.EventHandler) Event(org.osgi.service.event.Event) Barrier(org.apache.sling.event.impl.Barrier) Job(org.apache.sling.event.jobs.Job) Test(org.junit.Test)

Example 4 with Job

use of org.apache.sling.event.jobs.Job in project sling by apache.

the class TopicMatchingTest method testSimpleMatching.

/**
     * Test simple pattern matching /*
     */
@Test(timeout = DEFAULT_TEST_TIMEOUT)
public void testSimpleMatching() throws Exception {
    final Barrier barrier = new Barrier(2);
    this.registerJobExecutor("sling/test/*", new JobExecutor() {

        @Override
        public JobExecutionResult process(final Job job, final JobExecutionContext context) {
            return context.result().succeeded();
        }
    });
    this.registerEventHandler(NotificationConstants.TOPIC_JOB_FINISHED, new EventHandler() {

        @Override
        public void handleEvent(final Event event) {
            barrier.block();
        }
    });
    this.getJobManager().addJob(TOPIC, null);
    barrier.block();
}
Also used : JobExecutionResult(org.apache.sling.event.jobs.consumer.JobExecutionResult) JobExecutor(org.apache.sling.event.jobs.consumer.JobExecutor) JobExecutionContext(org.apache.sling.event.jobs.consumer.JobExecutionContext) EventHandler(org.osgi.service.event.EventHandler) Event(org.osgi.service.event.Event) Barrier(org.apache.sling.event.impl.Barrier) Job(org.apache.sling.event.jobs.Job) Test(org.junit.Test)

Example 5 with Job

use of org.apache.sling.event.jobs.Job in project sling by apache.

the class UnorderedQueueTest method testUnorderedQueue.

@Test(timeout = DEFAULT_TEST_TIMEOUT)
public void testUnorderedQueue() throws Exception {
    final JobManager jobManager = this.getJobManager();
    final Barrier cb = new Barrier(2);
    this.registerJobConsumer(TOPIC + "/start", new JobConsumer() {

        @Override
        public JobResult process(final Job job) {
            cb.block();
            return JobResult.OK;
        }
    });
    // register new consumer and event handle
    final AtomicInteger count = new AtomicInteger(0);
    final AtomicInteger parallelCount = new AtomicInteger(0);
    final Set<Integer> maxParticipants = new HashSet<Integer>();
    this.registerJobConsumer(TOPIC + "/*", new JobConsumer() {

        @Override
        public JobResult process(final Job job) {
            final int max = parallelCount.incrementAndGet();
            if (max > MAX_PAR) {
                parallelCount.decrementAndGet();
                return JobResult.FAILED;
            }
            synchronized (maxParticipants) {
                maxParticipants.add(max);
            }
            sleep(job.getProperty("sleep", 30));
            parallelCount.decrementAndGet();
            return JobResult.OK;
        }
    });
    this.registerEventHandler(NotificationConstants.TOPIC_JOB_FINISHED, new EventHandler() {

        @Override
        public void handleEvent(final Event event) {
            count.incrementAndGet();
        }
    });
    // we first sent one event to get the queue started
    jobManager.addJob(TOPIC + "/start", null);
    assertTrue("No event received in the given time.", cb.block(5));
    cb.reset();
    // get the queue
    final Queue q = jobManager.getQueue(QUEUE_NAME);
    assertNotNull("Queue '" + QUEUE_NAME + "' should exist!", q);
    // suspend it
    q.suspend();
    // we start "some" jobs:
    for (int i = 0; i < NUM_JOBS; i++) {
        final String subTopic = TOPIC + "/sub" + (i % 10);
        final Map<String, Object> props = new HashMap<String, Object>();
        if (i < 10) {
            props.put("sleep", 300);
        } else {
            props.put("sleep", 30);
        }
        jobManager.addJob(subTopic, props);
    }
    // start the queue
    q.resume();
    while (count.get() < NUM_JOBS + 1) {
        assertEquals("Failed count", 0, q.getStatistics().getNumberOfFailedJobs());
        assertEquals("Cancelled count", 0, q.getStatistics().getNumberOfCancelledJobs());
        sleep(300);
    }
    // we started one event before the test, so add one
    assertEquals("Finished count", NUM_JOBS + 1, count.get());
    assertEquals("Finished count", NUM_JOBS + 1, jobManager.getStatistics().getNumberOfFinishedJobs());
    assertEquals("Finished count", NUM_JOBS + 1, q.getStatistics().getNumberOfFinishedJobs());
    assertEquals("Failed count", 0, q.getStatistics().getNumberOfFailedJobs());
    assertEquals("Cancelled count", 0, q.getStatistics().getNumberOfCancelledJobs());
    for (int i = 1; i <= MAX_PAR; i++) {
        assertTrue("# Participants " + String.valueOf(i) + " not in " + maxParticipants, maxParticipants.contains(i));
    }
}
Also used : HashMap(java.util.HashMap) EventHandler(org.osgi.service.event.EventHandler) Barrier(org.apache.sling.event.impl.Barrier) JobManager(org.apache.sling.event.jobs.JobManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Event(org.osgi.service.event.Event) JobConsumer(org.apache.sling.event.jobs.consumer.JobConsumer) Job(org.apache.sling.event.jobs.Job) Queue(org.apache.sling.event.jobs.Queue) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

Job (org.apache.sling.event.jobs.Job)36 Test (org.junit.Test)23 JobConsumer (org.apache.sling.event.jobs.consumer.JobConsumer)16 JobManager (org.apache.sling.event.jobs.JobManager)12 Barrier (org.apache.sling.event.impl.Barrier)11 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)10 Event (org.osgi.service.event.Event)9 EventHandler (org.osgi.service.event.EventHandler)9 HashMap (java.util.HashMap)8 ArrayList (java.util.ArrayList)7 Map (java.util.Map)7 JobExecutionContext (org.apache.sling.event.jobs.consumer.JobExecutionContext)5 JobExecutionResult (org.apache.sling.event.jobs.consumer.JobExecutionResult)5 JobExecutor (org.apache.sling.event.jobs.consumer.JobExecutor)5 DistributionQueueEntry (org.apache.sling.distribution.queue.DistributionQueueEntry)4 IOException (java.io.IOException)3 DistributionQueueItem (org.apache.sling.distribution.queue.DistributionQueueItem)3 Queue (org.apache.sling.event.jobs.Queue)3 HashSet (java.util.HashSet)2 Nonnull (javax.annotation.Nonnull)2