Thursday, 11 December 2014

Workflow Details using MBean in AEM

When I was working on my project, I got an interesting task in which - 

I have to retrieve workflow related information such as total number of model, total active model instances, total stale instances for a model, currently active model instances i.e. complete list as displayed in workflow launcher. 

In this post, I will explain how I complete this task. There are lot of different ways to achieve these information for ex. you can write your own custom logic in sling servlet or service & then you will got your result.

But I am not going to do that. In place of it, I will use "Workflow Maintenance Operation MBean". This JMX MBean provides a set of methods, using them, I am able to find required results.

Agenda
1). How to use "Workflow Maintenance Operation MBean" to get workflow related information?


For doing this I have created a project named as blog as shown in left figure - 

Here, I create a component named as -workflowDetailsUsingMbean that uses MBean.

Note : - all JMX MBeans are displayed at -
http://localhost:4502/system/console/jmx

Here just search for "workflow", you will find two MBean services -

First having type Maintenance
Second having type Statics

In this post I will use first MBean service and fetch results from this service.


One more thing I want to ask you -
Do you know, what is the difference between Sling Services and MBean Services?
Shortly, just open both kind of services you will see the difference in MBean services you have access to all the method provided in your service (if exposed) as well as you can directly execute these methods by providing there parameters which is not possible in case of sling services.

NOTE :- If you have no idea about MBeans in AEM then in my next post, I am going to explain everything related to MBean as well as how to register them in AEM.

Now go to http://localhost:4502/system/console/jmx link -> search for "workflow" -> click on workflow MBean having type Maintenance. you will get a screen as -























Here you can click on any of the provided method and provide its required parameters, you are able to get the result of these methods for ex. click on fetchModelList() method and click on invoke, you can see all model present at your instance.

Now go to workflowDetailsUsingMbean component jsp file and paste given code -

<%@include file="/libs/foundation/global.jsp"%>
<%@page session="false"
    contentType="text/html; charset=utf-8"
    import="javax.management.MBeanServerConnection, 
    javax.management.MBeanServer,
java.lang.management.ManagementFactory,
javax.management.ObjectName,
javax.management.openmbean.TabularData,
java.util.* " %>
<%
    try
{
        /* 
          Get MBeanServer Instance for further infor read given link - 
          https://docs.oracle.com/javase/7/docs/api/javax/management/MBeanServer.html
        */
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        /*
          QueryNames Method have two parameter one is ObjectName to identify 
            which MBean Service you are looking for & other is QueryExpr which add
            additional conditions to find this object it is similar as database 
            where clauses.For further reading of ObjectName class go through the link - 
            https://docs.oracle.com/javase/7/docs/api/javax/management/ObjectName.html
        */
        Set<ObjectName> names = server.queryNames(
                                                      new ObjectName("com.adobe.granite.workflow:type=Maintenance,*") , null);
        ObjectName workflowMBean = names.iterator().next();
        /*
            Server invoke method is used to invoke a particular operation on existing MBean instance.
            It's parameter details are as follows - 
            invoke(ObjectName name, String operationName, Object[] params, String[] signature)
          I am executing stale workflowitems method from AEM.
        */
        Object staleWorkflowCount = server.invoke(workflowMBean, "countStaleWorkflows", 
                                                                               new Object[]{null}, new String[] {String.class.getName()});
        int mystaleCount = (Integer)staleWorkflowCount; 
        out.println("<h3>Number of Stale workflow instances are - "+mystaleCount +"</h3>");
        /*
          Another method execution that returns list of all workflow model present at your instance.
        */
        TabularData modelList = (TabularData) server.invoke(workflowMBean, "fetchModelList", null,null);
        Iterator itr = modelList.keySet().iterator();
       out.println("<h3>List of Workflow Models</h3>");
        while(itr.hasNext()){
        out.println(itr.next().toString()+"<br>");
        }
    }catch(Exception e){
out.println(e.getMessage());
    }
%>

I provide the description for all method used in JSP with reference URL.  Everything is done just drop this component at your web page you will get number of stale workflow model instances as well as list of all available model at your AEM.

github repository link

Happy Coding
Namah Shivay