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

Click on Create System User

Enter the User Id - "packageassembler and the path - "system/packageassembler"


Login to config manager - http://localhost:4502/system/console/configMgr
Search for "Apache Sling Service User Mapper Service" and add new service mapping

The bundle id can be copied from OSGI console

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

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

Provide create/modify/delete access to /etc/packages

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


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

Download the sample code - https://gitlab.com/albinsblog-data/PackageGenerator(Refer com.packagegenerator.core.schedulers in core module)
No comments:
Post a Comment
If you have any doubts or questions, please let us know.