Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create post on how to create workflow step #31

Open
wildone opened this issue Nov 27, 2019 · 0 comments
Open

create post on how to create workflow step #31

wildone opened this issue Nov 27, 2019 · 0 comments

Comments

@wildone
Copy link
Member

wildone commented Nov 27, 2019

Talk about

  • why throttledTaskRunner
  • PROCESS="design.aem.workflow.process.ContentFragmentPageGenerator"
  • public @interface Config
  • OSGI annotations, mention @Designate(ocd = ContentFragmentPageGenerator.Config.class)

_cq_dialog/.content.xml
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured" jcr:title="Content Fragment Page Generation" sling:resourceType="cq/gui/components/authoring/dialog" extraClientlibs="[cq.workflow-util]"> <content granite:id="worfklow-processpayload" jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/tabs"> <items jcr:primaryType="nt:unstructured"> <common cq:hideOnEdit="true" jcr:primaryType="nt:unstructured" jcr:title="Common" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"/> <process cq:hideOnEdit="true" jcr:primaryType="nt:unstructured" jcr:title="Process" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"/> <processcommon jcr:primaryType="nt:unstructured" jcr:title="Common" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <basic jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"> <items jcr:primaryType="nt:unstructured"> <title jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" disabled="false" fieldLabel="Title" name="./jcr:title"/> <description jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textarea" disabled="false" fieldLabel="Description" name="./jcr:description"/> </items> </basic> <advanced jcr:primaryType="nt:unstructured" jcr:title="Advanced Settings" sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"> <items jcr:primaryType="nt:unstructured"> <advance jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/checkbox" fieldDescription="Check if your handler will advance to the next step." fieldLabel="Handler Advance" name="./metaData/PROCESS_AUTO_ADVANCE" text="Handler Advance" value="true"/> </items> </advanced> </items> </column> </items> </processcommon> <processargs jcr:primaryType="nt:unstructured" jcr:title="Config" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <advanced jcr:primaryType="nt:unstructured" jcr:title="Advanced" sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"> <items jcr:primaryType="nt:unstructured"> <throttle jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/select" fieldDescription="Process will throttle it self depending on system resources." fieldLabel="Throttle execution of page generation." name="./metaData/throttle" emptyOption="{Boolean}true" value=""> <items jcr:primaryType="nt:unstructured"> <true jcr:primaryType="nt:unstructured" text="Yes" value="true"/> <false jcr:primaryType="nt:unstructured" text="No" value="false"/> </items> </throttle> </items> </advanced> </items> </column> </items> </processargs> </items> </content> </jcr:root>

content.xml
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:description="Generate Pages for Content Fragments" jcr:primaryType="cq:Component" jcr:title="Content Fragment Page Generation" sling:resourceSuperType="cq/workflow/components/model/process" allowedParents="[*/parsys]" componentGroup="AEM.Design - Workflow"/>

_cq_editConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" cq:dialogMode="floating" cq:inherit="{Boolean}true" jcr:primaryType="cq:EditConfig"> <cq:formParameters jcr:description="Generate Pages for Content Fragments" jcr:primaryType="nt:unstructured" jcr:title="Content Fragment Page Generation" PROCESS="design.aem.workflow.process.ContentFragmentPageGenerator" PROCESS_AUTO_ADVANCE="true"/> </jcr:root>

TemplateProcess.java

`package design.aem.workflow.process;

import com.adobe.acs.commons.fam.ThrottledTaskRunner;
import com.adobe.acs.commons.util.WorkflowHelper;
import com.adobe.acs.commons.util.visitors.ContentVisitor;
import com.adobe.acs.commons.util.visitors.ResourceRunnable;
import com.adobe.acs.commons.workflow.WorkflowPackageManager;
import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.WorkflowProcess;
import com.adobe.granite.workflow.metadata.MetaDataMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.osgi.service.component.annotations.*;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.osgi.service.component.propertytypes.ServiceRanking;
import org.osgi.service.component.propertytypes.ServiceVendor;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Session;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@component(
immediate = true,
service = WorkflowProcess.class
)
@Designate(ocd = TemplateProcess.Config.class)
@ServiceDescription("Workflow step for generating pages for Content Fragments")
@ServiceRanking(1001)
@ServiceVendor("AEM.Design")
public class TemplateProcess implements WorkflowProcess {
@ObjectClassDefinition(
name = "AEM Design - Workflow - Content Fragment Page Generator",
description = "Workflow step for generating pages for Content Fragments"
)
public @interface Config {
@AttributeDefinition(
name = "Throttle",
description = "Throttle execution of workflow, default: true"
)
boolean throttle() default true;
}
private Config config;
private static final Logger LOGGER = LoggerFactory.getLogger(TemplateProcess.class);
protected static final String ARG_THROTTLE = "throttle";
@reference
private WorkflowHelper workflowHelper;
@reference
private WorkflowPackageManager workflowPackageManager;
@reference
private ResourceResolverFactory resourceResolverFactory;
@reference
private ThrottledTaskRunner throttledTaskRunner;
@activate
@Modified
protected void activate(Config config) {
LOGGER.info("activate: resourceResolverFactory={}", resourceResolverFactory);
this.config = config;
}
@deactivate
protected void deactivate(Config config) {
}
@OverRide
public final void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
ResourceResolver resourceResolver = null;
final long start = System.currentTimeMillis();
try {
resourceResolver = workflowHelper.getResourceResolver(workflowSession);
final String originalPayload = (String) workItem.getWorkflowData().getPayload();
final List payloads = workflowPackageManager.getPaths(resourceResolver, originalPayload);
final ProcessArgs processArgs = new ProcessArgs(metaDataMap, config);
final AtomicInteger count = new AtomicInteger(0);
final AtomicInteger failCount = new AtomicInteger(0);
final Session session = resourceResolver.adaptTo(Session.class);
// Anonymous inner class to facilitate counting of processed payloads
final ResourceRunnable generatorRunnable = new ResourceRunnable() {
@OverRide
public void run(final Resource resource) throws Exception {
if (processArgs.isThrottle()) {
throttledTaskRunner.waitForLowCpuAndLowMemory();
}
//TODO: Add logic here
count.incrementAndGet();
}
private void failed(String message, Object... error) {
failCount.incrementAndGet();
LOGGER.error(message, error);
}
};
final ContentVisitor visitor = new ContentVisitor(generatorRunnable);
for (final String payload : payloads) {
final Resource resource = resourceResolver.getResource(payload);
if (!ResourceUtil.isNonExistingResource(resource)) {
visitor.accept(resource);
} else {
LOGGER.info("Payload does not exist: {}", payload);
}
}
if (failCount.get() == 0) {
session.save();
} else {
LOGGER.info("There were failures total of {} not saving", failCount.get());
}
LOGGER.error("Workflow step was execute [{}] times in {} ms", count.get(), System.currentTimeMillis() - start);
} catch (Exception e) {
LOGGER.error("Error occurred executing workflow.");
throw new WorkflowException(e);
}
}
/**
* ProcessArgs parsed from the Workflow metadata map.
*/
protected static class ProcessArgs {
private boolean throttle;
ProcessArgs(MetaDataMap map, Config config) throws WorkflowException {
// advanced config
if (map.get(ARG_THROTTLE, Boolean.class) == null) {
LOGGER.warn("Throttle not specified defaulting to throttle enabled.");
}
throttle = map.get(ARG_THROTTLE, config.throttle());
}
public boolean isThrottle() {
return throttle;
}
}
}
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant