JMX: Read attribute from Server

2019-04-12 17:54发布

问题:

We're using Adobe CQ (5.5) as CMS. Now, our CQ environment consists of one author server, where users can create content, and 2 publish servers which serve the content to the internet.

Now there's a replication agent which pushs content from the author server to both publish server. Unfortunately some articles block the queue of the replication agents, so no more new content is beeing published. This is not much of a problem, as it is easy to fix. The real problem is that we don't notice this blockage until users start to complain that no more changes are beeing published.

I searched around and found out that CQ provides a JMX API where monitoring applications could attach itself to it. I then tried to find some open source software which would allow me to configure alerts, so we can react faster, but I couldn't find something.

This is when I decided that I could try to write my own Java Application which just reads the attribute and sends a mail if the attribute should be true. I guess that was more complicated than I tought.

First off, I'm not a Java Developer, but since CQ is based on Java I tought I'd give it a try. I read some documentation about JMX and Java and was able to get a working connection to the CQ server. But this is almost everything I could realize.

I was able to find out that the class com.adobe.granite.replication has a type agent which stores an id for every replication agent (the id would be the name of the replication agent, for example id=replication-publish-1). Every replication-agent has different attributes, but the attribute relevant for me would be "QueueBlocked".

This is the code I've got so far (it's based on this example):

public static void main(String[] args) {
    try {
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://servername:9010/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

        ClientListener listener = new ClientListener();

        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // This outputs the domains, one of them is com.adobee.granite.replication, the one which I need to use
        // This is why I'm sure that at least the connection works, I don't have any com.adobe.granite.replication class on my Eclipse installation, so the output has to come from the server
        String domains[] = mbsc.getDomains();
        for (int i = 0; i < domains.length; i++) {
            echo("\tDomain[" + i + "] = " + domains[i]);
        }

        ObjectName replication = new ObjectName("com.adobe.granite.replication:type=Agent,id=replication-publish-1");

        mbsc.getAttribute(replication, "QueueBlocked"); // This throws the error
} catch(Exception e) {

}

}

The error thrown is the following:

javax.management.InstanceNotFoundException: com.adobe.granite.replication:type=Agent,id=replication-publish-1

From what I understand I should be creating some kind of instance, but I don't really have an idea what instance and how to create it. I'd really appreciate any help I can get no matter if it's a documentation or code snippet :)

回答1:

Solved it :)

This is the code I'm using:

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class Client {

    public static void main(String[] args) {
        try {
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://servername:9010/jmxrmi");
            JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

            MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

            ObjectName replication1 = new ObjectName("com.adobe.granite.replication:type=agent,id=\"replication-publish-1\"");
            ObjectName replication2 = new ObjectName("com.adobe.granite.replication:type=agent,id=\"replication-publish-2\"");

            String replication1Status = mbsc.getAttribute(replication1, "QueuePaused").toString();
            String replication2Status = mbsc.getAttribute(replication2, "QueuePaused").toString();



        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


标签: java jmx cq5