Tag Archives: AEM Solutions, Cyber Security

AEM Solution: AEM Author activity reports

AEM CMS lacks so many fundamental features and one of the critical feature is author activity reporting. We can say AEM has reporting: Disk usage, user activity, page activity & workflow instances etc. But in reality none of them are useful when it comes to basic features of reporting.

In my opinion, Without ACS Commons tool, AEM as CMS hasn’t provided many capabilities except stupid touch UI. Every team has to develop so many custom solutions to support operation work. One of the example, Migrating content from one environment to another. Will talk many more issues in AEM. Let’s explore about reporting feature in AEM.

Scenarios/Need of reporting feature in CMS

Let’s say there are many websites & brands hosted in one AEM author environment and multiple content teams are putting content at the same time. Page deleting, modification etc would be normal activity for a large team. And, Team often struggles to find out who has modified their pages, deleted etc. The Biggest question is that how do we restore the content? but keeping track of normal activities is essential.

Page Activity Report Solution

AEM has reporting capabilities called page activity report. AEM Reporting lacks following basic features:

  • It is unresponsive & provides very basic information.
  • Filtering based on date, author etc isn’t provided.
  • Querying feature isn’t available.
  • No way you can check what section of the page was modified?

Solutions

AEM OOTB (Out of the box) Page activity report could be helpful if you know the page name or title and you want to track of that page. In above snapshot, Filter setting provides a way to find out about the page.

Custom Solution using PageEvent Handler

Here is the one custom solution to track all the events of the page in AEM. Keep one PageEvent handler and keep pushing activities into JCR node or other storages.

@Component
@Service
@Property(name="event.topics", value= {DamEvent.EVENT_TOPIC, PageEvent.EVENT_TOPIC})
public class PageActivityReport implements EventHandler {
    /**PageModification.ModificationType.CREATED
       PageModification.ModificationType.DELETED
       PageModification.ModificationType.MODIFIED
       PageModification.ModificationType.MOVED
       PageModification.ModificationType.VERSION_CREATED
       PageModification.ModificationType.RESTORED
    ***/    
   @Override
   public void handleEvent(Event event) {
     PageEvent pageEvent = PageEvent.fromEvent(event);
    if(pageEvent != null) {
       Iterator<PageModification> modifications = pageEvent.getModifications();
        while (modifications.hasNext()) {
            PageModification modification = modifications.next();
            if (PageModification.ModificationType.CREATED.equalsIgnoreCase(modification.getType().toString())) {
        //Log it or write code to save created pages.
        } else if (PageModification.ModificationType.DELETED.equalsIgnoreCase(modification.getType().toString())) {
        //Log it or write code to save deleted pages. Notification or alert can be triggered from here.
        }else if (PageModification.ModificationType.MODIFIED.equalsIgnoreCase(modification.getType().toString())) {
   //Log it or write code to save modified pages.
   }
   }
 }
}

In the above code, We have multiple events specific blocks to write custom reporting code. One of the way is to create records of these activities is to create simple JCR nodes for each activities. Data models for reporting could be as follows.

Path of the code could be: /page-report/<today’s data in yyyy/mm/dd>/<current time in hours>/<page-path-replace_slashwith_hyphen>/<author>

  • path: /content/abc/en/example.html
  • pageTitle: <title of the page>
  • event: delete/modify/moved
  • activityBy: who performed any activity
  • timestamps: <Format should be correct so that it can be queried>

Final Thoughts

The above solution can be implemented or scale for other types of reporting. For example, Keep tracking assets activity reporting. One Challenge in scaling this solution would be, Keeping activities records in JCR nodes and fetching them quickly. Also, Above data model needs more thoughts based on how query would look like when generating final reports.

AEM Solution: Creating AEM JCR valid & Unique name programmatically

The objective of this post is to elaborate how AEM Page Manager API is being used to create unique JCR Node or Page name. And if there is a requirement for you to create same page name programatically then what API you should be using?

Scenario

Let’s consider a scenario where article pages are being created automatically in AEM content hierarchy and some of the promotional content under those pages. And, There is a product detail page which renders promotional content based Product data.

The problem occurs when you to have determine promotional content programatically with some information at the product level. To match appropriate promotional content & render onto product detail pages isn’t straight forward.

Solution

In order to solve above problem, all you have to do is to resolve promotional content page as resource. And that is possible if Your code is able to find content page in JCR Contrent hierarchy.

Let’s consider this example. Title of promotional/Article content: “This is a dummy content article page”. The Same page created in AEM would have hierarchy like this.

/content/<your-website>/en/articles/this-is-a-dummy-content-article-page

Below example shows how you can create valid JCR Resource/Node/Page Name out of given Title of the article.

#Simple Example Class
Public class UninqueValidPageName{
 public static String getValidPageName(final String articleTitle){
     return JcrUtil.createValidName(StringUtils.trim(articleTitle), JcrUtil.HYPHEN_LABEL_CHAR_MAPPING);
}
}

Final Thoughts 

This solution seems very simple however it has significant important of solving problem.