Sunday 28 February 2016

Sling Scheduler

What is a Scheduler?

Apache Sling Scheduler enables you to easily schedule jobs within your application. Jobs can be executed at a specific time, regularly at a given period or at the time given by a cron expression by leveraging the Sling scheduler service.

Scheduling in CQ uses the open source Quartz library, part Sling Commons:‘org.apache.sling.commons.scheduler.Scheduler’. It is used to execute jobs at predefined times either periodically or at a set time. It is based on the Quartz scheduling library and can therefore make use of its syntax for defining the execution times of jobs, making it possible to precisely indicate times .

Simple Scheduler which calls Rest API:

Below scheduler writes data into JSON file which is under var folder for every 5 minutes.

package com.geometrixx.sightly.Schedulers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;

import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.ValueFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Component( metatype=true, immediate = true, label = "Gaurdian API Scheduler" )
@Properties({
@Property(label = "Scheduler Label", name = "scheduler.label", value = "News Scheduler"),
@Property(label = "Scheduler Name", name = "scheduler.name", value = "News Scheduler"),
@Property(label = "Article/Event xml Scheduler Expression", name = "gaurdian.scheduler.expression", value = "0 0 * * * ?")
})
public class GuardianAPIScheduler {

Logger  log = LoggerFactory.getLogger(this.getClass());

@Reference
    private Scheduler scheduler;

@Reference
private ResourceResolverFactory resourceResolverFactory;

protected void activate( ComponentContext ctx ) throws Exception {
final Runnable newsJob = new Runnable() {
            public void run() {
            try{
               log.debug("Executing My API Scheduler");
               GuardianAPIScheduler guardianAPIScheduler = new GuardianAPIScheduler();
               guardianAPIScheduler.generateJsonFile();
            }catch(Exception e){
            log.error("Error while getting data from Api");
            }
            }
        };
        try {        
        final String eventSchedulerExp = PropertiesUtil.toString(ctx.getProperties().get("gaurdian.scheduler.expression"), "0 0 * * * ?");
            this.scheduler.addJob("news-job", newsJob, new HashMap<String, Serializable>(), eventSchedulerExp, false);
            
        } catch (Exception e) {
        newsJob.run();
        }
}

protected void generateJsonFile() throws Exception{
// TODO Auto-generated method stub
HttpClient httpClient = new HttpClient();
        GetMethod post = new GetMethod("http://content.guardianapis.com/search?q=debates&api-key=test");
        int statusCode = httpClient.executeMethod(post);
        log.debug("Status Code {}",statusCode);
        String responseBody = post.getResponseBodyAsString();
        InputStream inputStream = new ByteArrayInputStream( responseBody.getBytes() );
        ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
        Session session = resourceResolver.adaptTo(Session.class);
        ValueFactory valueFactory = session.getValueFactory();
Binary contentValue = valueFactory.createBinary( inputStream );
Node varNode = JcrUtils.getOrAddNode(session.getRootNode(), "var", "sling:Folder");
Node reportNode = JcrUtils.getOrAddNode( varNode, "newsapi", "sling:Folder" );
Node reportFile = JcrUtils.getOrAddNode( reportNode, "newsapi.json" , "nt:file" );
Node jcrContentNode = JcrUtils.getOrAddNode( reportFile, "jcr:content", "nt:resource" );
jcrContentNode.setProperty( "jcr:mimeType", "application/json" );
jcrContentNode.setProperty( "jcr:data", contentValue );
log.debug("Reponse from API writing done {}",responseBody);
session.save();
}

}
  
Checking the scheduler status and other info can done under this path

http://localhost:4502/system/console/status-slingscheduler

Reference for Cron Expression:
http://www.docjar.com/docs/api/org/quartz/CronTrigger.html

No comments:

Post a Comment