April 27, 2020
Estimated Post Reading Time ~ 2 mins

Sling scheduler to auto create the packages through JcrPackageManager API - AEM

This post will explains the approach to define Sling scheduler to auto create the packages through JcrPackageManager API in Adobe Experience Manager(AEM).

Define a Service user:
Define a Service User with required access to create a package.

Login to CRX explorer - http://localhost:4502/crx/explorer/index.jsp
Click on User Administration

AEM-service-user
Click on Create System User

AEM-service-user
Enter the User Id - "packageassembler and the path - "system/packageassembler"

AEM-service-user

AEM-service-user

Login to config manager - http://localhost:4502/system/console/configMgr

Search for "Apache Sling Service User Mapper Service" and add new service mapping

AEM-service-user
The bundle id can be copied from OSGI console

AEM-service-user

Search for "Apache Sling Service User Mapper Service Amendment" add service mapping

AEM-service-user
Login to - http://localhost:4502/useradmin
Search for the user "packageassembler"
Provide the read-only access to the repository

AEM-service-user
Provide create/modify/delete access to /etc/packages

AEM-service-user

GeneratePackageSchedulerRequest.java:
Factory class to define the Job configuration

@Component(configurationFactory = true, policy = ConfigurationPolicy.OPTIONAL, metatype = true, immediate = true, label = "Scheduled Package Generator")
@Service(value = GeneratePackageSchedulerRequest.class)
public class GeneratePackageSchedulerRequest {

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

@Property(unbounded=PropertyUnbounded.DEFAULT, label="Scheduler Expression", description="Scheduler Expression", value="")
private static final String SCHEDULER_EXPRESSION = "sheduleExpression";
private String sheduleExpression;

@Property(unbounded = PropertyUnbounded.ARRAY, label = "Packages Filter String", cardinality = 50, description = "Packages Filter String")
public static final String PACKAGE_FILTERS = "packageFilters";
private String[] packageFilters;

@Property(unbounded=PropertyUnbounded.DEFAULT, label="Package Name", description="Package Name")
private static final String PACKAGE_NAME = "packgeName";
private String packageName;

@Property(unbounded=PropertyUnbounded.DEFAULT, label="Root Path to store the package", description="Root Path")
private static final String ROOT_PATH = "rootpath";
private String rootPath;

@Activate
protected void activate(final ComponentContext ctx) {

Dictionary<?, ?> props = ctx.getProperties();
sheduleExpression = PropertiesUtil.toString(props.get(SCHEDULER_EXPRESSION), "");

packageFilters = PropertiesUtil.toStringArray(props.get(PACKAGE_FILTERS), null);
packageName = PropertiesUtil.toString(props.get(PACKAGE_NAME), null);
rootPath=PropertiesUtil.toString(props.get(ROOT_PATH), null);
}

public String[] getPackageFilters() {
return packageFilters;
}

public String getJobname() {
return packageName;
}

public String getSheduleExpression() {
return sheduleExpression;
}

public String getRootPath() {
return rootPath;
}

}

GeneratePackageScheduledTask.java
Job class to create the package based on the Job parameter.

@Component(immediate = true, metatype = true)
@Service(GeneratePackageScheduledTask.class)

public class GeneratePackageScheduledTask {

@Reference
private SlingRepository repository;

@Reference
private ResourceResolverFactory resolverFactory;

@Reference
private SlingSettingsService settingsService;

@Reference
private Scheduler scheduler;

@Reference
private Packaging packaging;

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

@Reference(cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = GeneratePackageSchedulerRequest.class, policy = ReferencePolicy.DYNAMIC)
private final List<GeneratePackageSchedulerRequest> providers = new LinkedList<GeneratePackageSchedulerRequest>();

protected void bindProviders(final GeneratePackageSchedulerRequest config) throws Exception {

providers.add(config);

final String schedulingExpression=config.getSheduleExpression();
final String jobname= config.getJobname();
final String[] packageFilters = config.getPackageFilters();

final Runnable job = new Runnable() {
public void run() {

Session session=null;
if (isRunMode("author")&& isMasterRepository()) {

try {

Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "packageService");

ResourceResolver resolver = resolverFactory.getServiceResourceResolver(param);

//ResourceResolver resolver = resolverFactory.getAdministrativeResourceResolver(null);
session= resolver.adaptTo(Session.class);

logger.debug("{} is now running, Parameter='{}'",jobname, packageFilters);

List<PathFilterSet> pathFilterSets = new ArrayList<PathFilterSet>();
for (String packageFilter : packageFilters) {
pathFilterSets.add(new PathFilterSet(packageFilter));
}

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");

JcrPackageManager jcrPackageManager = packaging.getPackageManager(session);

JcrPackage jcrPackage = jcrPackageManager.create("ScheduledPackages", jobname+sdf.format(new Date()).toString(), "1.0");
JcrPackageDefinition jcrPackageDefinition = jcrPackage.getDefinition();
DefaultWorkspaceFilter workspaceFilter = new DefaultWorkspaceFilter();

for (PathFilterSet pathFilterSet : pathFilterSets) {
workspaceFilter.add(pathFilterSet);
}

jcrPackageDefinition.setFilter(workspaceFilter, true);
jcrPackageDefinition.set(JcrPackageDefinition.PN_DESCRIPTION, "Scheduled Package"+jobname+sdf.format(new Date()).toString(), false);
String filePath=config.getRootPath()+File.separator+ config.getJobname()+sdf.format(new Date()).toString()+".zip";
logger.debug("Package Export File Path:"+filePath);

ProgressTrackerListener listener = new DefaultProgressListener();
jcrPackageManager.assemble(jcrPackageDefinition,listener, new FileOutputStream(filePath));

jcrPackageManager.remove(jcrPackage);

} catch (Exception rex) {
rex.printStackTrace();
logger.error("Error occurred in pckage creation..", rex.getMessage());
}finally {

if (session != null) {
session.logout();
}
}
}

logger.debug("run() END"+jobname);
}

};

ScheduleOptions so = scheduler.EXPR(schedulingExpression);
so.name(jobname);
this.scheduler.schedule(job, so);
logger.debug("Scheduled Job: " + config.getJobname()+" "+schedulingExpression);
}

protected void unbindProviders(final GeneratePackageSchedulerRequest config) {
logger.debug("Removed Job: " + config.getJobname());
this.scheduler.unschedule(config.getJobname());
providers.remove(config);
}

private Boolean isRunMode(String mode) {
Set<String> runModes = settingsService.getRunModes();
for (String runMode : runModes) {
if (runMode.equalsIgnoreCase(mode)) {
logger.debug("Current Runmode is : " + runMode);
return true;
}
}
return false;
}

public boolean isMasterRepository(){
final String isMaster = repository.getDescriptor("crx.cluster.master");
logger.debug("isMaster.."+isMaster);
return isMaster!=null && !isMaster.equals("") && Boolean.parseBoolean(isMaster);
}

}

After deployment, Login to config manager - http://localhost:4502/system/console/configMgr
Search for "Scheduled Package Generator" and configure the Jobs(multiple jobs can be configured)

Scheduler Expression - Specify the scheduler expression to run the Job(use Cron maker to generate the expression)
Package Filter - Specify the repository path to include in the package(multiple paths can be specified)
Package Name - Specify the package name
Root Path to store the package - Specify the parent path in the server to store the package

AEM-package-generator-scheduler

OSGI-scheduler-factory

After enabling the configurations the packages will be created in specified location based on the scheduled time.

AEM-package-generator-scheduler
Download the sample code - https://gitlab.com/albinsblog-data/PackageGenerator(Refer com.packagegenerator.core.schedulers in core module)
aem4beginner.blogspot


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.

Ad Blocker Detected :(

Please consider supporting us by disabling your ad blocker.

Please Disable your adblocker and Refresh the page to view the site content.