Expand my Community achievements bar.

SOLVED

Call Servlet from Schedular

Avatar

Employee

Hi ,

 

I have a requirement to call the servlet from the schedular. How can I do that ?

This is my Servlet path /reports/generatereport.export.json

 

 

Thanks

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @SateeshRe 
I think, you need to redesign the solution in order to reuse same logic in servlet and scheduler.

1. JobConsumer

2. Servlet

3. Report Service

 

in this example you can use Report Service osgi service in Job and Servlet

 

 

Anyway, there is a way to do it using either MockServlet or calling a servlet's get method

MockSlingHttpServletRequest req = new MockSlingHttpServletRequest(resolver);
MockSlingHttpServletResponse resp = new MockSlingHttpServletResponse();

or

https://github.com/arunpatidar02/aemaacs-aemlab/blob/e31fc62bfd147e56ecaca740c6e2739c66c75f75/core/s... 



Arun Patidar

View solution in original post

8 Replies

Avatar

Community Advisor

It is not a best practice nor recommend way to call a servlet from scheduler. You can call a service from scheduler. Move the existing logic in Servlet to a OSGi service or write a new service and call that OSGi service in your scheduler.This promotes better separation of concerns, code reusability, and easier testing.

 

High Level Steps - Sequence:

  1. Create OSGi Service (This service should contain the logic that you currently have in your servlet.)
  2. Update your servlet to call the new service instead of containing the logic itself. (optional) - if you want to keep the servlet for any other purposes.
  3. Create a scheduler that also calls the new service.

 

 

 

Avatar

Employee

Hi Suresh,

 

Actually, I have to call this GenerateReportServlet which is OOTB that creates the dam reports.

Avatar

Level 10

@SateeshRe This is one only one way to call HTTP call to this servlet and fetch the same. 

There is a best way to resolve you issue, we already have an access to ReportCSVExportServlet.java as part of below link and you can also perform same operation after copying this code under service class.

 

https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/master/bundle/src/main/java/com/ad...

Avatar

Employee

Thanks for the reply @Imran__Khan ,

I am looking to call the  GenerateReportServlet which is OOTB that creates the dam reports but the one you have suggested is to export the report to csv.

Avatar

Level 10

@SateeshRe This is one only one way to call HTTP call to this servlet and fetch the same. 

There is a best way to resolve you issue, we already have an access to ReportCSVExportServlet.java as part of below link and you can also perform same operation after copying this code under service class. Hitting a servlet will impact AEM publish performance.

https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/master/bundle/src/main/java/com/ad...

Avatar

Community Advisor

Hi @SateeshRe 
Please try this way

1. Create a new job consumer: In your AEM project, create a new job consumer that will execute the servlet. You can create a new Java class that implements the `org.apache.sling.event.jobs.consumer.JobConsumer` interface. In the `process` method of this class, you can use the `SlingHttpServletResponse` object to call the servlet URL and generate the report.

2. Create a new job: In your scheduler, create a new job that will trigger the job consumer. You can use the `org.apache.sling.event.jobs.JobManager` API to create a new job. Set the job topic to a unique value and add any job properties that are required by your job consumer.

3. Schedule the job: Finally, schedule the job to run at the desired frequency. You can use the `org.apache.sling.event.jobs.JobManager` API to schedule the job. Set the scheduling expression to the desired frequency, such as `0 0 1 * * ?` to run the job every day at 1 AM.

 

 

@Component(service = JobConsumer.class, property = {
JobConsumer.PROPERTY_TOPICS + "=" + "myproject/generate-report"
})
public class GenerateReportJobConsumer implements JobConsumer {

@Reference
private SlingHttpServletResponse response;

@Override
public JobResult process(Job job) {
try {
// Call the servlet URL to generate the report
String servletUrl = "/reports/generatereport.export.json";
response.sendRedirect(servletUrl);
} catch (IOException e) {
// Handle any exceptions
return JobResult.FAILED;
}
return JobResult.OK;
}
}

 

 


In your scheduler, you can create a new job using the following code:

@Reference
private JobManager jobManager;

public void scheduleReportGeneration() {
    // Create a new job with the topic "myproject/generate-report"
    Job job = jobManager.createJob("myproject/generate-report")
            .setProperty("reportType", "monthly")
            .setProperty("startDate", "2022-01-01")
            .setProperty("endDate", "2022-01-31")
            .build();

    // Schedule the job to run every day at 1 AM
    String schedulingExpression = "0 0 1 * * ?";
    jobManager.addJob(job, schedulingExpression);
}


Avatar

Correct answer by
Community Advisor

Hi @SateeshRe 
I think, you need to redesign the solution in order to reuse same logic in servlet and scheduler.

1. JobConsumer

2. Servlet

3. Report Service

 

in this example you can use Report Service osgi service in Job and Servlet

 

 

Anyway, there is a way to do it using either MockServlet or calling a servlet's get method

MockSlingHttpServletRequest req = new MockSlingHttpServletRequest(resolver);
MockSlingHttpServletResponse resp = new MockSlingHttpServletResponse();

or

https://github.com/arunpatidar02/aemaacs-aemlab/blob/e31fc62bfd147e56ecaca740c6e2739c66c75f75/core/s... 



Arun Patidar

Avatar

Administrator

@SateeshRe Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni