简体   繁体   English

AEM 6.3:使用 OSGi R6 注释创建调度程序

[英]AEM 6.3 : Creating Scheduler using OSGi R6 annotations

I have written a scheduler using OSGi R6 annotations but it doesn't seem to run :我已经使用 OSGi R6 注释编写了一个调度程序,但它似乎没有运行:

package com.aem.sites.interfaces;

import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "Scheduler Configuration for Weather", description = "Configuration file for Scheduler")
public @interface SchedulerConfiguration {

    @AttributeDefinition(
            name = "sample parameter",
            description="Sample String parameter",
            type = AttributeType.STRING
            )
    public String parameter() default "scheduler";

    @AttributeDefinition(
            name = "Concurrent",
            description = "Schedule task concurrently",
            type = AttributeType.BOOLEAN
        )
        boolean scheduler_concurrent() default true;

        @AttributeDefinition(
            name = "Expression",
            description = "Cron-job expression. Default: run every minute.",
            type = AttributeType.STRING
        )
        String scheduler_expression() default "0 * * * * ?";

}

and

package com.aem.sites.schedulers;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.interfaces.SchedulerConfiguration;

@Component(immediate = true,
        configurationPid = "com.aem.sites.schedulers.WeatherServiceScheduler")
@Designate(ocd=SchedulerConfiguration.class)
public class WeatherServiceScheduler implements Runnable {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

     private String myParameter;

    @Override
    public void run() {
         logger.info("*******************************************Sample OSGi Scheduler is now running", myParameter);

    }
    @Activate
    public void activate(SchedulerConfiguration config) {
        logger.info("*******************************************weather service scheduler"+ myParameter);
        myParameter = config.parameter();
    }

}

I am following this https://github.com/nateyolles/aem-osgi-annotation-demo/blob/master/core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleOsgiScheduledTask.java but looks like I am doing something wrong here.我正在关注这个https://github.com/nateyolles/aem-osgi-annotation-demo/blob/master/core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleOsgiScheduledTask.java但是看起来我在这里做错了什么。 Not sure what though.虽然不确定是什么。

Thanks in advance提前致谢

In your WeatherSchedulerService class, you are not registering it as a service.在您的WeatherSchedulerService类中,您没有将其注册为服务。 Instead of configurationPid , you can do like this service = Runnable.class .您可以像这样service = Runnable.class ,而不是configurationPid

The correct way to create a SlingScheduler using OSGi R6 annotations is as follows -使用OSGi R6注释创建 SlingScheduler 的正确方法如下 -

  1. Create your OSGi configuration class创建您的 OSGi 配置类
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "Sling Scheduler Configuration", description = "This configuration is used to demonstrates a sling scheduler in action")
public @interface SchedulerConfiguration {

    @AttributeDefinition(
            name = "Scheduler name", 
            description = "Name of the scheduler", 
            type = AttributeType.STRING)
    public String name() default "Custom Sling Scheduler";

    @AttributeDefinition(
            name = "Enabled", 
            description = "Flag to enable/disable a scheduler", 
            type = AttributeType.STRING)
    public boolean enabled() default false;

    @AttributeDefinition(
            name = "Cron expression", 
            description = "Cron expression used by the scheduler", 
            type = AttributeType.STRING)
    public String cronExpression() default "0 * * * * ?";

    @AttributeDefinition(
            name = "Custom parameter", 
            description = "Custom parameter to showcase the usage of a sling scheduler", 
            type = AttributeType.STRING)
    public String customParameter();
}
  1. Create your Scheduler class as a service.将您的 Scheduler 类创建为服务。 For creating an OSGi service using R6 annotations we use @Component(service=<your-interface>.class,...) .为了使用 R6 注释创建 OSGi 服务,我们使用@Component(service=<your-interface>.class,...) Thus, create a service as follows因此,创建一个服务如下
import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.redquark.aem.learning.core.configurations.SchedulerConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Component(immediate = true, service = Runnable.class)
@Designate(ocd = SchedulerConfiguration.class)
public class CustomScheduler implements Runnable {

    // Logger
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    // Custom parameter that is to be read from the configuration
    private String customParameter;

    // Id of the scheduler based on its name
    private int schedulerId;

    // Scheduler instance injected
    @Reference
    private Scheduler scheduler;

    /**
     * Activate method to initialize stuff
     * 
     * @param schedulerConfiguration
     */
    @Activate
    protected void activate(SchedulerConfiguration schedulerConfiguration) {
        schedulerId = schedulerConfiguration.name().hashCode();
        customParameter = schedulerConfiguration.customParameter();
    }

    /**
     * Modifies the scheduler id on modification
     * 
     * @param schedulerConfiguration
     */
    @Modified
    protected void modified(SchedulerConfiguration schedulerConfiguration) {
        // Removing scheduler
        removeScheduler();
        // Updating the scheduler id
        schedulerId = schedulerConfiguration.name().hashCode();
        // Again adding the scheduler
        addScheduler(schedulerConfiguration);
    }

    /**
     * This method deactivates the scheduler and removes it
     * 
     * @param schedulerConfiguration
     */
    @Deactivate
    protected void deactivate(SchedulerConfiguration schedulerConfiguration) {
        // Removing the scheduler
        removeScheduler();
    }

    /**
     * This method removes the scheduler
     */
    private void removeScheduler() {
        log.info("Removing scheduler: {}", schedulerId);
        // Unscheduling/removing the scheduler
        scheduler.unschedule(String.valueOf(schedulerId));
    }

    /**
     * This method adds the scheduler
     * 
     * @param schedulerConfiguration
     */
    private void addScheduler(SchedulerConfiguration schedulerConfiguration) {
        // Check if the scheduler is enabled
        if (schedulerConfiguration.enabled()) {
            // Scheduler option takes the cron expression as a parameter and run accordingly
            ScheduleOptions scheduleOptions = scheduler.EXPR(schedulerConfiguration.cronExpression());

            // Adding some parameters
            scheduleOptions.name(schedulerConfiguration.name());
            scheduleOptions.canRunConcurrently(false);

            // Scheduling the job
            scheduler.schedule(this, scheduleOptions);
            log.info("Scheduler added");
        } else {
            log.info("Scheduler is disabled");
        }
    }

    /**
     * Overridden run method to execute Job
     */
    @Override
    public void run() {
        log.info("Custom Scheduler is now running using the passed custom paratmeter, customParameter {}",
                customParameter);

    }
  • In the activate() method, we are reading the required values.在 activate() 方法中,我们正在读取所需的值。 Then we are getting the schedulerId from the scheduler name.然后我们从调度程序名称中获取 schedulerId。
  • The modified() method recalculates the schedulerId in case the OSGi configuration is modified.在 OSGi 配置被修改的情况下, modified() 方法会重新计算 schedulerId。
  • In the addScheduler() method, we are registering the scheduler using the Scheduler API.在 addScheduler() 方法中,我们使用 Scheduler API 注册调度程序。

For more information and step by step execution, you can see my blog post as well - Day 13: Schedulers in AEM有关更多信息和分步执行,您也可以查看我的博客文章 - 第 13 天:AEM 中的调度程序

I hope this helps.我希望这有帮助。 Happy coding!快乐编码!

There is no need for configurationPid in the class annotation, and also you are missing service=Runnable.class which should follow immediate=true , ie the class declaration should look like:类注释中不需要configurationPid ,而且您也缺少service=Runnable.class ,它应该跟在immediate=true ,即类声明应该如下所示:

@Component(immediate = true, service=Runnable.class)
@Designate(ocd=SchedulerConfiguration.class)
public class WeatherServiceScheduler implements Runnable {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM