user1969909
user1969909

Reputation: 3

Run workflow process from other workflow process

guys. I am a newbie in AEM and have a problem. I need to execute com.day.cq.dam.core.process.UnarchiverProcess process(inherited from AbstractAssetWorkflowProcess) from my own. So I need something like this(code below is obviously not working):

import com.day.cq.dam.core.process.UnarchiverProcess;
public class FirstProcess extends AbstractAssetWorkflowProcess {
       public final void execute(final WorkItem item, final WorkflowSession wfSession, final MetaDataMap args)
                throws WorkflowException {
    UnarchiverProcess unarchiverProcess = new UnarchiverProcess();
    unarchiverProcess.execute(item,wfSession,args);
    return;
}

Is there any way to do it? Thank you!

Upvotes: 0

Views: 1999

Answers (1)

Ameesh Trikha
Ameesh Trikha

Reputation: 1712

UnarchiverProcess is a standalone process, is there a reason to create a custom step to just invoke UnarchiverProcess. You could simply add another process step in your workflow model and configure it for UnarchiverProcess.

In case you want to do it (I however do not recommend this unless you a have a strong reason for doing it), there are two possibilities -

First :

  1. Create another custom workflow model with just one process step for UnarchiverProcess
  2. In your process step, use WorkflowSession to get WorkflowModel (WorkflowSession.getModel(....) ) for the above workflow and call WorkflowSession.startWorkflow(....) to invoke the process step.

This is not an efficient approach as you are invoking another workflow from a workflow process. Workflows are resource consuming tasks so if this workflow is called on heavy load will cause your instance to slow down.

Second:

  1. Each workflow process is resitered as an OSGi Service thus can inject other OSGi service.
  2. You could inject UnarchiverProcess in your custom process. But the challenge is that all the workflow processes are registered via their interface so all the processes are registered as WorkflowProcess so you need a way to filter out the only implementation you need i.e. UnarchiverProcess

    @Reference(target="(component.name = com.day.cq.dam.core.process.UnarchiverProcess)") WorkflowProcess workflowProcess;

Refer to article here for more details.

In this approach you are not invoking another process but injecting a service reference and calling its method.

I would still recommend adding another step to your workflow for this process as its more cleaner approach and you don't need to maintain code just for the sake of it.

UPDATE :

if Service filtering doesn't work, you can go OSGI Bundle context route (add missing imports) -

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.ComponentFactory;
import org.osgi.service.component.ComponentInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by ameesh.trikha on 2/24/16.
 */

@Service
@Component
public class YourWorkflowClass implements WorkflowProcess {

    private BundleContext bundleContext;
    private Map<String, ServiceReference> serviceReferenceMap = new ConcurrentHashMap<>();
    private Map<String, ComponentInstance> componentInstanceMap = new ConcurrentHashMap();

    @Activate
    protected void activate(ComponentContext context) {
        this.bundleContext = context.getBundleContext();
    }

    @Deactivate
    protected void deactivate(ComponentContext context) {

        synchronized (this.serviceReferenceMap) {
            for(Map.Entry<String,ComponentInstance> componentInstance : this.componentInstanceMap.entrySet()) {
                componentInstance.getValue().dispose();
            }

            for(Map.Entry<String, ServiceReference> serviceReference : this.serviceReferenceMap.entrySet()) {
                this.bundleContext.ungetService(serviceReference.getValue());
            }
        }
        this.componentInstanceMap.clear();
        this.serviceReferenceMap.clear();
        this.bundleContext = null;
    }


    public UnarchiverProcess getUnarchiverProcess() {

        ServiceReference [] serviceReferences;

        String serviceIdentifier = "component.name="+UnarchiverProcess.class.getName();
        if (this.componentInstanceMap.containsKey(serviceIdentifier)) {
            final ComponentInstance componentInstance = this.componentInstanceMap.get(serviceIdentifier);
            return (UnarchiverProcess) componentInstance.getInstance();
        }

        try {
            serviceReferences = this.bundleContext.getServiceReferences(ComponentFactory.class.getName(), serviceIdentifier);
        } catch (InvalidSyntaxException ise) {

            LOGGER.error("Could'nt get Service reference for {}", serviceIdentifier, ise);
            return null;
        }

        if (null != serviceReferences && serviceReferences.length > 0) {
            final ServiceReference serviceReference = serviceReferences[0];
            final ComponentFactory componentFactory = (ComponentFactory) this.bundleContext.getService(serviceReference);
            final ComponentInstance componentInstance = componentFactory.newInstance(null);
            final UnarchiverProcess unarchiverProcess = (UnarchiverProcess) componentInstance.getInstance();
            if (unarchiverProcess == null) {
                LOGGER.error("Unable to get " + serviceIdentifier);
                componentInstance.dispose();
                this.bundleContext.ungetService(serviceReference);
            } else {
                synchronized (this.serviceReferenceMap) {
                    this.serviceReferenceMap.put(serviceIdentifier, serviceReference);
                    this.componentInstanceMap.put(serviceIdentifier, componentInstance);
                }
            }

            return unarchiverProcess;
        }

        return null;
    }

}

Upvotes: 1

Related Questions