Saturday, April 1, 2017

Generating the missing renditions for the Asset - Adobe CQ5/AEM

Generating the missing renditions for the Asset - Adobe CQ5/AEM

This post will explain the approach to generate the missing renditions for the asset(images) under a specific folder location in  Adobe Experience Manager(AEM)

Create a custom workflow with "Create Thumpnail" step


Edit "Create Thumpnail" step and configure the required renditions.


Servlet to re-generate the missing renditions:

Modify the workflow model path in the servlet with the actual path, the servlet is configured to handle the renditions 370.208 and 470.264(the same renditions are configured in the workflow). The code change is required to handle new renditions by the servlet.

Parameters:
path= the parent path of the assets(images) folder
test=true/false(true - Dry run, false - generate the renditions)


import java.io.IOException;
import java.util.HashSet;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.servlet.Servlet;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowService;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.model.WorkflowModel;
@Service(value = Servlet.class)
@Component(immediate = true, metatype = true)
@Properties({
@Property(name = "sling.servlet.paths", value = "/services/updateRenditions"),
@Property(name = "service.description", value = "This is update renditions service."),
@Property(name = "label", value = "UpdateRenditionsServlet") })
public class UpdateRenditions extends SlingSafeMethodsServlet {
@Reference
    private WorkflowService workflowService;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        ResourceResolver resourceResolver = request.getResourceResolver();
        Session session = (Session)resourceResolver.adaptTo((Class)Session.class);
        String path = request.getParameter("path");
        String test = request.getParameter("test");
        String model = "/etc/workflow/models/custom/update_asset_generate_rendition/jcr:content/model";
           
        if (path == null && test == null) {
            response.getWriter().println("Image folder path missing in parameter e.g path=/content/dam/geometrixx/banners");
            return;
        }
        if (test == null) {
        test="true";
            response.getWriter().println("test option missing e.g test=true, running in debug mode");
         
        }
        try {
            response.getWriter().println("Root folder path:" + path);        
            if (test.equals("false")) {              
                this.processRenditions(session, path, model, response, false);
            } else {
            response.getWriter().println("Running in debug mode, change test=false to create renditions ");
                this.processRenditions(session, path, model, response, true);
            }
        }
        catch (RepositoryException e) {
            response.getWriter().println("Error occors while creating renditions" + e.getMessage());
        }
    }

    private void runWorkFlow(Session session, String path, String model, SlingHttpServletResponse response) throws IOException {
        WorkflowSession wfSession = this.workflowService.getWorkflowSession(session);
        try {
            WorkflowModel wfModel = wfSession.getModel(model);
            WorkflowData wfData = wfSession.newWorkflowData("JCR_PATH", (Object)path);
            wfSession.startWorkflow(wfModel, wfData);
            response.getWriter().println("successfully created renditions");
        }
        catch (WorkflowException ex) {
            response.getWriter().println("  failed" + ex.getMessage());
            ex.printStackTrace();
        }
    }

    private void processRenditions(Session session, String JcrPath, String model, SlingHttpServletResponse response, boolean isTest) throws RepositoryException, IOException {
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        String sqlStatement = "SELECT * FROM [dam:Asset] AS s WHERE ISDESCENDANTNODE([" + JcrPath + "])";
        Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
        QueryResult result = query.execute();
        NodeIterator nodeIter = result.getNodes();
        int i = 1;
        HashSet set = new HashSet();
        while (nodeIter.hasNext()) {
            Node node = nodeIter.nextNode();
            if (this.hasThumbnail(queryManager, node.getPath()))
            {   response.getWriter().println("[" + i + "] " + "Renditions are already available for image path =" + node.getPath());
            ++i;
            continue;
            }
            if (isTest) {
                response.getWriter().println("[" + i + "] " + "Missing rendition for image path =" + node.getPath());
            } else {
                response.getWriter().println("[" + i + "] " + "Running renditioin workflow for image path =" + node.getPath());
                this.runWorkFlow(session, node.getPath(), model, response);
            }
            ++i;
        }
    }

    private boolean hasThumbnail(QueryManager queryManager, String JcrPath) throws InvalidQueryException, RepositoryException, IOException {
    String sqlStatement = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([" + JcrPath + "])";
        Query query = queryManager.createQuery(sqlStatement, "JCR-SQL2");
        QueryResult result = query.execute();
        NodeIterator nodeIter = result.getNodes();
        boolean isRendition370208=false;
        boolean isRendition470264=false;
        while (nodeIter.hasNext()) {
            Node node = nodeIter.nextNode();        
            if (node.getName().contains("cq5dam.thumbnail.370.208.png") || node.getName().contains("cq5dam.thumbnail.370.208.jpg") )
            {
            isRendition370208=true;
            }
         
            if (node.getName().contains("cq5dam.thumbnail.470.264.png") || node.getName().contains("cq5dam.thumbnail.470.264.jpg") )
            {
            isRendition470264=true;
            }
         
            if(isRendition370208 && isRendition470264)
            {
             return true;
            }        
        }
        return false;
    }

}

Dry Run - http://localhost:4502/services/updateRenditions?path=/content/dam/geometrixx/banners&test=true


Generate missing renditions - http://localhost:4502/services/updateRenditions?path=/content/dam/geometrixx/banners&test=false





No comments:

Post a Comment