Hi Community,
I have a simple service with an OSGi config. After deploying, the service always uses defaults what I have in code - not picking from the environment valiables.
Here is my code
package com.acme.core.schedulers;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.*;
import org.osgi.service.metatype.annotations.*;
@component(service = Runnable.class, immediate = true)
@Designate(ocd = ACLCleanpSchedulerConfig.class) // not a factory
public class ACLCleanpScheduler implements Runnable {
@ObjectClassDefinition(name = "Acme - ACL Cleanp Scheduler")
public @interface ACLCleanpSchedulerConfig {
@AttributeDefinition(name="Enabled")
boolean enabled() default false;
@AttributeDefinition(name="Cron")
String cron() default "0/10 * * * * ?";
@AttributeDefinition(name="Base Path")
String base_path() default "/content/dam";
}
@reference private Scheduler scheduler;
private volatile ACLCleanpSchedulerConfig cfg;
@activate @MODIFIED
protected void activate(ACLCleanpSchedulerConfig cfg) throws Exception {
this.cfg = cfg;
scheduler.unschedule("acme-aclcleanp");
if (cfg.enabled()) {
scheduler.schedule(this, scheduler.EXPR(cfg.cron()), true);
}
}
@deactivate
protected void deactivate() throws Exception {
scheduler.unschedule("acme-aclcleanp");
}
@Override public void run() {
// cleanup work using cfg.base_path()
}
}
/apps/acme/osgiconfig/config/com.acme.core.schedulers.ACLCleanpScheduler.cfg.json
{
"enabled":"$[env:ACL_ENABLED;default=false]",
"cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
"base_path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}
Note: I have set the environment variables on the configurations already.
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @rakesh_mallel,
It looks good to me except one thing where I suspect:
Can you try to set the configuration property from base_path to base.path (dot instead underscore)?
{
"enabled":"$[env:ACL_ENABLED;default=false]",
"cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
"base.path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}
Hi @rakesh_mallel ,
First of all, in the AEMaaCS you must not use Sling Commons Scheduler for scheduling as execution cannot be guaranteed. It is just more likely that it is scheduled. Official documentation: https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/dev...
In addition, I would recommend to have env variable as String.
Refactored code and best practice:
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.ScheduledJobInfo;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import java.util.Collection;
import java.util.Optional;
import static ACLCleanpScheduler.TOPIC;
@Component(
service = {JobConsumer.class},
immediate = true,
property = {JobConsumer.PROPERTY_TOPICS + "=" + TOPIC},
configurationPolicy = ConfigurationPolicy.REQUIRE
)
@Designate(ocd = ACLCleanpScheduler.ACLCleanpSchedulerConfig.class)
@Slf4j
public class ACLCleanpScheduler implements JobConsumer {
public static final String TOPIC = "acme-aclcleanp";
@ObjectClassDefinition(name = "Acme - ACL Cleanp Scheduler")
public @interface ACLCleanpSchedulerConfig {
@AttributeDefinition(name = "Enabled")
String enabled() default "false";
@AttributeDefinition(name = "Cron")
String cron() default "0/10 * * * * ?";
@AttributeDefinition(name = "Base Path")
String base_path() default "/content/dam";
}
private volatile ACLCleanpSchedulerConfig cfg;
@Reference
private transient JobManager jobManager;
@Activate
@Modified
protected void activate(ACLCleanpSchedulerConfig cfg) throws Exception {
this.cfg = cfg;
if (!Boolean.parseBoolean(cfg.enabled())) {
return;
}
startScheduledJob();
}
private void unScheduleExistingJobs() {
Optional.ofNullable(jobManager.getScheduledJobs(TOPIC, 0, null))
.orElse(CollectionUtils.emptyCollection())
.forEach(job -> {
log.info("Removing Scheduler Job '{}'", job.getJobTopic());
job.unschedule();
});
}
private void startScheduledJob() {
unScheduleExistingJobs();
Collection<ScheduledJobInfo> myJobs = jobManager.getScheduledJobs(TOPIC, 0, null);
log.info("Initiating scheduled job with CRON expression: {}", cfg.cron());
if (!myJobs.isEmpty()) {
log.error("Can't schedule any existing scheduled jobs, because there are already scheduled");
return;
}
JobBuilder.ScheduleBuilder scheduleBuilder = jobManager.createJob(TOPIC).schedule();
scheduleBuilder.cron(cfg.cron());
if (scheduleBuilder.add() == null) {
log.error("Job '{}' was not scheduled", TOPIC);
return;
}
log.info("Job has been scheduled successfully");
}
@Override
public JobResult process(Job job) {
return JobResult.OK;
}
}
Hi @konstantyn_diachenko Thank you for your response - I have no issues in running scheduler, everyhting works well as expected but only issue is it's not reading the value from environment variables.
Also, I tried the same code as you pasted above but still not working specially base path is setting from the code which I have set as default here: String base_path() default "/content/dam"; where I have set /content/dam/acme/ in environment variable. Any idea? appreciate your help.
Views
Replies
Total Likes
Views
Replies
Total Likes
Yes, I did removed from the code too, just to double check but no luck - either it's empty or default from the code.
Views
Replies
Total Likes
Hi @rakesh_mallel ,
@SantoshSai made a good catch. In the OSGi R7 there is a mapping for Java annotation method to OSGi property:
Left: annotation method symbols
Right: replacement in the property name
"__" to "_",
"_" to ".",
"\$_\$" to "-",
"\$\$" to "\$",
"\$" to ""
So, please define OSGi property in the .cfg.json file as "base.path".
In addition, I would recommend to get rid of scheduler and start using Sling Jobs. I referenced an official documentation.
Hi @rakesh_mallel,
It looks good to me except one thing where I suspect:
Can you try to set the configuration property from base_path to base.path (dot instead underscore)?
{
"enabled":"$[env:ACL_ENABLED;default=false]",
"cron": "$[env:ACL_CRON;default=0/50 * * * * ?]",
"base.path": "$[env:ACL_BASE_PATH;default=/content/dam/]"
}
@SantoshSai This worked, thank you!
Views
Replies
Total Likes
Views
Likes
Replies