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

时间:2017-10-21 00:30:14

标签: osgi quartz-scheduler aem

我使用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 * * * * ?";

}

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();
    }

}

我正在关注https://github.com/nateyolles/aem-osgi-annotation-demo/blob/master/core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/schedulers/SampleOsgiScheduledTask.java,但看起来我在这里做错了。不知道是什么。

提前致谢

2 个答案:

答案 0 :(得分:1)

在您的 WeatherSchedulerService 类中,您没有将其注册为服务。您可以像这样service = Runnable.class来代替 configurationPid

使用OSGi R6批注创建SlingScheduler的正确方法如下-

  1. 创建您的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. 将Scheduler类创建为服务。为了使用R6注释创建OSGi服务,我们使用@Component(service=<your-interface>.class,...)。 因此,如下创建服务
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);

    }
  • 在activate()方法中,我们正在读取所需的值。然后我们从调度程序名称中获取schedulerId。
  • 如果修改了OSGi配置,则Modifyed()方法将重新计算schedulerId。
  • 在addScheduler()方法中,我们正在使用Scheduler API注册调度程序。

有关更多信息和分步执行的信息,您也可以查看我的博客文章-Day 13: Schedulers in AEM

我希望这会有所帮助。编码愉快!

答案 1 :(得分:0)

在类注释中不需要configurationPid,而且您也缺少service=Runnable.class之后的immediate=true,即类声明应类似于:

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