Solr indexing of AEM Assets or Pages Data Automatically by Replication Event Listener

Contents

Objective

After reading this Article, You should have an Understanding of –

  • Replication Event Listener in AEM
  • Solr indexing of AEM asset or page data automatically

Introduction

In AEM, we mostly work with assets and pages. Sometimes the scenario comes to publish the content and it automatically indexes the data to Solr for better search implementation. We can achieve this with the help of the Replication Event Listener. When we press the publish button, the Event Listener will trigger and send the necessary data to the Solr Collection.

Hence, without any further delay, let’s get started:

Dependency required for Solr implementation in AEM

Dependency in core pom.xml

				
					<!-- https://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.solr-solrj -->
<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.solr-solrj</artifactId>
    <version>8.11.1_1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.zookeeper</artifactId>
    <version>3.7.0_1</version>
</dependency>
				
			

Dependency in all pom.xml

				
					<!-- Embed the solrj in all pom.xml-->
<embedded>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.solr-solrj</artifactId>
    <target>/apps/learning-packages/application/install</target>
</embedded>

<!-- Embed the zookeeper/zookeeper in all pom.xml-->
<embedded>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.zookeeper</artifactId>
    <target>/apps/learning-packages/application/install</target>
</embedded>
				
			

Replication Event Listener for indexing content and asset data to Solr

The Replication Event Listener is an event handler that triggers when you publish any content in AEM. The below event handler shows the solr implementation and indexing. Here we are sending some basic data (i.e. id, path, title, and description) to Solr. Further, we can use the same data for search functionality. So let’s see the implementation code.

SolrEventHandler.java

				
					package com.adobe.learning.core.listeners;

import com.day.cq.replication.ReplicationAction;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.*;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.common.SolrInputDocument;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Shiv
 */
@Component(service = EventHandler.class, immediate = true, property = {
        Constants.SERVICE_DESCRIPTION + "= DAM Asset Events for Solr Indexing",
        EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC,
        EventConstants.EVENT_FILTER + "=(paths=/content/dam/*)"})

public class SolrEventHandler implements EventHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(SolrEventHandler.class);
    private static final String SYSTEM_USER = "system_user";
    private static final String METADATA_CONSTANT = "/jcr:content/metadata";

    @Reference
    ResourceResolverFactory resourceResolverFactory;

    ResourceResolver resourceResolver;

    @Override
    public void handleEvent(Event event) {
        try {
            //Getting Replication Options from Event
            ReplicationAction replicationAction = ReplicationAction.fromEvent(event);
            String assetPath = StringUtils.EMPTY;

            //Getting Resource Resolver from system user for ValueMap
            Map<String, Object> param = new HashMap<>();
            param.put(ResourceResolverFactory.SUBSERVICE, SYSTEM_USER);
            resourceResolver = resourceResolverFactory.getServiceResourceResolver(param);

            if (replicationAction != null) {
                //Getting asset path which we are publishing
                assetPath = replicationAction.getPath();

                //Getting Resource and ValueMap for uuid
                Resource parentResource = resourceResolver.getResource(assetPath);
                assert parentResource != null;
                ValueMap parentValueMap = parentResource.getValueMap();

                //Getting Resource and ValueMap for asset Metadata
                Resource resource = resourceResolver.getResource(assetPath + METADATA_CONSTANT);
                assert resource != null;
                ValueMap valueMap = resource.getValueMap();

                //Connecting to Solr Collection using Solr Client
                SolrClient solrClient = new HttpSolrClient.Builder("http://localhost:8983/solr/learnsolraem").build();

                //Add all properties that we want to send to solr
                SolrInputDocument solrInputFields = new SolrInputDocument();
                solrInputFields.addField("id", parentValueMap.get("jcr:uuid", String.class));
                solrInputFields.addField("path", assetPath);
                solrInputFields.addField("title", valueMap.get("dc:title", String.class));
                solrInputFields.addField("description", valueMap.get("dc:description", String.class));
                solrClient.add(solrInputFields);

                //Commit the data to solr
                solrClient.commit(true, true);
                LOGGER.info("Document is updated to Solr Successfully");
            }

            LOGGER.info("Event Path : {}", assetPath);
        } catch (SolrServerException | IOException | LoginException e) {
            LOGGER.error("Error in Replication Event : {}", e.getMessage());
        }
    }
}

				
			
Replication Event Listener
Asset in Author
Solr Data
Asset Data in Solr
Asset In Publish
Asset in Publisher

Conclusion

  • So in this post, we tried to index asset data to Solr using event handler. Same we can use for pages and packages as well. I hope you enjoyed this post. If you find it useful, leave us a comment. I would love to hear your thoughts and suggestions to make it better. Also, you can connect with me on LinkedIn, Instagram or Facebook. All links are active now.

2 Comments

Leave a Reply

Your email address will not be published.